]>
Commit | Line | Data |
---|---|---|
d9fcf2fb | 1 | /* UI_FILE - a generic STDIO like output stream. |
4a94e368 | 2 | Copyright (C) 1999-2022 Free Software Foundation, Inc. |
d9fcf2fb JM |
3 | |
4 | This file is part of GDB. | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
a9762ec7 | 8 | the Free Software Foundation; either version 3 of the License, or |
d9fcf2fb JM |
9 | (at your option) any later version. |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
a9762ec7 | 17 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
d9fcf2fb JM |
18 | |
19 | #ifndef UI_FILE_H | |
20 | #define UI_FILE_H | |
21 | ||
8de00631 | 22 | #include <string> |
eedeedd2 | 23 | #include "ui-style.h" |
8de00631 | 24 | |
d7e74731 PA |
25 | /* The abstract ui_file base class. */ |
26 | ||
27 | class ui_file | |
28 | { | |
29 | public: | |
30 | ui_file (); | |
31 | virtual ~ui_file () = 0; | |
d9fcf2fb | 32 | |
d7e74731 | 33 | /* Public non-virtual API. */ |
d9fcf2fb | 34 | |
d7e74731 | 35 | void printf (const char *, ...) ATTRIBUTE_PRINTF (2, 3); |
d9fcf2fb | 36 | |
d53fd721 TT |
37 | /* Print a NUL-terminated string whose delimiter is QUOTER. Note |
38 | that these routines should only be called for printing things | |
39 | which are independent of the language of the program being | |
40 | debugged. | |
41 | ||
42 | This will normally escape backslashes and instances of QUOTER. | |
43 | If QUOTER is 0, it won't escape backslashes or any quoting | |
44 | character. As a side effect, if you pass the backslash character | |
45 | as the QUOTER, this will escape backslashes as usual, but not any | |
46 | other quoting character. */ | |
d7e74731 | 47 | void putstr (const char *str, int quoter); |
d9fcf2fb | 48 | |
d53fd721 TT |
49 | /* Like putstr, but only print the first N characters of STR. If |
50 | ASYNC_SAFE is true, then the output is done via the | |
51 | write_async_safe method. */ | |
52 | void putstrn (const char *str, int n, int quoter, bool async_safe = false); | |
3e43a32a | 53 | |
d7e74731 | 54 | int putc (int c); |
3e43a32a | 55 | |
d7e74731 | 56 | void vprintf (const char *, va_list) ATTRIBUTE_PRINTF (2, 0); |
01124a23 | 57 | |
d7e74731 PA |
58 | /* Methods below are both public, and overridable by ui_file |
59 | subclasses. */ | |
3e43a32a | 60 | |
d7e74731 | 61 | virtual void write (const char *buf, long length_buf) = 0; |
3e43a32a | 62 | |
d7e74731 PA |
63 | /* This version of "write" is safe for use in signal handlers. It's |
64 | not guaranteed that all existing output will have been flushed | |
65 | first. Implementations are also free to ignore some or all of | |
66 | the request. puts_async is not provided as the async versions | |
67 | are rarely used, no point in having both for a rarely used | |
68 | interface. */ | |
69 | virtual void write_async_safe (const char *buf, long length_buf) | |
70 | { gdb_assert_not_reached ("write_async_safe"); } | |
3e43a32a | 71 | |
d7e74731 PA |
72 | /* Some ui_files override this to provide a efficient implementation |
73 | that avoids a strlen. */ | |
74 | virtual void puts (const char *str) | |
75 | { this->write (str, strlen (str)); } | |
d9fcf2fb | 76 | |
d7e74731 PA |
77 | virtual long read (char *buf, long length_buf) |
78 | { gdb_assert_not_reached ("can't read from this file type"); } | |
d9fcf2fb | 79 | |
d7e74731 PA |
80 | virtual bool isatty () |
81 | { return false; } | |
2a9d5ccf | 82 | |
8a522c6c PW |
83 | /* true indicates terminal output behaviour such as cli_styling. |
84 | This default implementation indicates to do terminal output | |
85 | behaviour if the UI_FILE is a tty. A derived class can override | |
86 | TERM_OUT to have cli_styling behaviour without being a tty. */ | |
87 | virtual bool term_out () | |
88 | { return isatty (); } | |
89 | ||
90 | /* true if ANSI escapes can be used on STREAM. */ | |
91 | virtual bool can_emit_style_escape () | |
92 | { return false; } | |
93 | ||
d7e74731 PA |
94 | virtual void flush () |
95 | {} | |
6aa4f97c AB |
96 | |
97 | /* If this object has an underlying file descriptor, then return it. | |
98 | Otherwise, return -1. */ | |
99 | virtual int fd () const | |
100 | { return -1; } | |
84b33497 | 101 | |
7016a382 TT |
102 | /* Indicate that if the next sequence of characters overflows the |
103 | line, a newline should be inserted here rather than when it hits | |
104 | the end. If INDENT is non-zero, it is a number of spaces to be | |
105 | printed to indent the wrapped part on the next line. | |
106 | ||
107 | If the line is already overfull, we immediately print a newline and | |
108 | the indentation, and disable further wrapping. | |
109 | ||
110 | If we don't know the width of lines, but we know the page height, | |
111 | we must not wrap words, but should still keep track of newlines | |
112 | that were explicitly printed. | |
113 | ||
114 | This routine is guaranteed to force out any output which has been | |
115 | squirreled away in the wrap_buffer, so wrap_here (0) can be | |
116 | used to force out output from the wrap_buffer. */ | |
3cd52293 TT |
117 | virtual void wrap_here (int indent) |
118 | { | |
119 | } | |
7016a382 | 120 | |
c8d74a7b TT |
121 | /* Emit an ANSI style escape for STYLE. */ |
122 | virtual void emit_style_escape (const ui_file_style &style); | |
123 | ||
124 | /* Rest the current output style to the empty style. */ | |
125 | virtual void reset_style (); | |
126 | ||
9b716718 TT |
127 | /* Print STR, bypassing any paging that might be done by this |
128 | ui_file. Note that nearly no code should call this -- it's | |
6cb06a8c | 129 | intended for use by gdb_printf, but nothing else. */ |
9b716718 TT |
130 | virtual void puts_unfiltered (const char *str) |
131 | { | |
132 | this->puts (str); | |
133 | } | |
134 | ||
c8d74a7b TT |
135 | protected: |
136 | ||
137 | /* The currently applied style. */ | |
138 | ui_file_style m_applied_style; | |
139 | ||
d53fd721 TT |
140 | private: |
141 | ||
142 | /* Helper function for putstr and putstrn. Print the character C on | |
143 | this stream as part of the contents of a literal string whose | |
144 | delimiter is QUOTER. */ | |
145 | void printchar (int c, int quoter, bool async_safe); | |
d7e74731 | 146 | }; |
d9fcf2fb | 147 | |
d7e74731 | 148 | typedef std::unique_ptr<ui_file> ui_file_up; |
d9fcf2fb | 149 | |
d7e74731 | 150 | /* A ui_file that writes to nowhere. */ |
d9fcf2fb | 151 | |
d7e74731 PA |
152 | class null_file : public ui_file |
153 | { | |
154 | public: | |
155 | void write (const char *buf, long length_buf) override; | |
156 | void write_async_safe (const char *buf, long sizeof_buf) override; | |
157 | void puts (const char *str) override; | |
158 | }; | |
d9fcf2fb | 159 | |
d7e74731 PA |
160 | /* A preallocated null_file stream. */ |
161 | extern null_file null_stream; | |
162 | ||
e4adb939 EZ |
163 | extern int gdb_console_fputs (const char *, FILE *); |
164 | ||
d7e74731 PA |
165 | /* A std::string-based ui_file. Can be used as a scratch buffer for |
166 | collecting output. */ | |
d9fcf2fb | 167 | |
d7e74731 PA |
168 | class string_file : public ui_file |
169 | { | |
170 | public: | |
8a522c6c PW |
171 | /* Construct a string_file to collect 'raw' output, i.e. without |
172 | 'terminal' behaviour such as cli_styling. */ | |
173 | string_file () : m_term_out (false) {}; | |
174 | /* If TERM_OUT, construct a string_file with terminal output behaviour | |
175 | such as cli_styling) | |
176 | else collect 'raw' output like the previous constructor. */ | |
177 | explicit string_file (bool term_out) : m_term_out (term_out) {}; | |
d7e74731 | 178 | ~string_file () override; |
d9fcf2fb | 179 | |
d7e74731 | 180 | /* Override ui_file methods. */ |
8de00631 | 181 | |
d7e74731 | 182 | void write (const char *buf, long length_buf) override; |
d9fcf2fb | 183 | |
d7e74731 PA |
184 | long read (char *buf, long length_buf) override |
185 | { gdb_assert_not_reached ("a string_file is not readable"); } | |
186 | ||
8a522c6c PW |
187 | bool term_out () override; |
188 | bool can_emit_style_escape () override; | |
189 | ||
d7e74731 PA |
190 | /* string_file-specific public API. */ |
191 | ||
192 | /* Accesses the std::string containing the entire output collected | |
5d10a204 SM |
193 | so far. */ |
194 | const std::string &string () { return m_string; } | |
d7e74731 | 195 | |
5d10a204 | 196 | /* Return an std::string containing the entire output collected so far. |
d7e74731 | 197 | |
5d10a204 SM |
198 | The internal buffer is cleared, such that it's ready to build a new |
199 | string. */ | |
200 | std::string release () | |
201 | { | |
202 | std::string ret = std::move (m_string); | |
203 | m_string.clear (); | |
204 | return ret; | |
205 | } | |
d7e74731 | 206 | |
e867795e AB |
207 | /* Set the internal buffer contents to STR. Any existing contents are |
208 | discarded. */ | |
209 | string_file &operator= (std::string &&str) | |
210 | { | |
211 | m_string = std::move (str); | |
212 | return *this; | |
213 | } | |
214 | ||
d7e74731 PA |
215 | /* Provide a few convenience methods with the same API as the |
216 | underlying std::string. */ | |
217 | const char *data () const { return m_string.data (); } | |
218 | const char *c_str () const { return m_string.c_str (); } | |
219 | size_t size () const { return m_string.size (); } | |
220 | bool empty () const { return m_string.empty (); } | |
221 | void clear () { return m_string.clear (); } | |
222 | ||
223 | private: | |
224 | /* The internal buffer. */ | |
225 | std::string m_string; | |
8a522c6c PW |
226 | |
227 | bool m_term_out; | |
d7e74731 PA |
228 | }; |
229 | ||
230 | /* A ui_file implementation that maps directly onto <stdio.h>'s FILE. | |
231 | A stdio_file can either own its underlying file, or not. If it | |
232 | owns the file, then destroying the stdio_file closes the underlying | |
233 | file, otherwise it is left open. */ | |
234 | ||
235 | class stdio_file : public ui_file | |
236 | { | |
237 | public: | |
238 | /* Create a ui_file from a previously opened FILE. CLOSE_P | |
239 | indicates whether the underlying file should be closed when the | |
240 | stdio_file is destroyed. */ | |
241 | explicit stdio_file (FILE *file, bool close_p = false); | |
242 | ||
243 | /* Create an stdio_file that is not managing any file yet. Call | |
244 | open to actually open something. */ | |
245 | stdio_file (); | |
246 | ||
247 | ~stdio_file () override; | |
248 | ||
249 | /* Open NAME in mode MODE, and own the resulting file. Returns true | |
250 | on success, false otherwise. If the stdio_file previously owned | |
251 | a file, it is closed. */ | |
252 | bool open (const char *name, const char *mode); | |
253 | ||
254 | void flush () override; | |
255 | ||
256 | void write (const char *buf, long length_buf) override; | |
257 | ||
258 | void write_async_safe (const char *buf, long length_buf) override; | |
259 | ||
260 | void puts (const char *) override; | |
261 | ||
262 | long read (char *buf, long length_buf) override; | |
263 | ||
264 | bool isatty () override; | |
265 | ||
8a522c6c PW |
266 | bool can_emit_style_escape () override; |
267 | ||
6aa4f97c AB |
268 | /* Return the underlying file descriptor. */ |
269 | int fd () const override | |
270 | { return m_fd; } | |
271 | ||
d7e74731 PA |
272 | private: |
273 | /* Sets the internal stream to FILE, and saves the FILE's file | |
274 | descriptor in M_FD. */ | |
275 | void set_stream (FILE *file); | |
276 | ||
277 | /* The file. */ | |
278 | FILE *m_file; | |
279 | ||
280 | /* The associated file descriptor is extracted ahead of time for | |
281 | stdio_file::write_async_safe's benefit, in case fileno isn't | |
282 | async-safe. */ | |
283 | int m_fd; | |
284 | ||
285 | /* If true, M_FILE is closed on destruction. */ | |
286 | bool m_close_p; | |
287 | }; | |
288 | ||
289 | typedef std::unique_ptr<stdio_file> stdio_file_up; | |
290 | ||
291 | /* Like stdio_file, but specifically for stderr. | |
292 | ||
293 | This exists because there is no real line-buffering on Windows, see | |
294 | <http://msdn.microsoft.com/en-us/library/86cebhfs%28v=vs.71%29.aspx> | |
295 | so the stdout is either fully-buffered or non-buffered. We can't | |
296 | make stdout non-buffered, because of two concerns: | |
449092f6 | 297 | |
d7e74731 PA |
298 | 1. Non-buffering hurts performance. |
299 | 2. Non-buffering may change GDB's behavior when it is interacting | |
300 | with a front-end, such as Emacs. | |
2a9d5ccf | 301 | |
d7e74731 PA |
302 | We leave stdout as fully buffered, but flush it first when |
303 | something is written to stderr. | |
d9fcf2fb | 304 | |
d7e74731 PA |
305 | Note that the 'write_async_safe' method is not overridden, because |
306 | there's no way to flush a stream in an async-safe manner. | |
307 | Fortunately, it doesn't really matter, because: | |
308 | ||
309 | 1. That method is only used for printing internal debug output | |
310 | from signal handlers. | |
311 | ||
312 | 2. Windows hosts don't have a concept of async-safeness. Signal | |
313 | handlers run in a separate thread, so they can call the regular | |
314 | non-async-safe output routines freely. | |
315 | */ | |
316 | class stderr_file : public stdio_file | |
317 | { | |
318 | public: | |
319 | explicit stderr_file (FILE *stream); | |
320 | ||
321 | /* Override the output routines to flush gdb_stdout before deferring | |
322 | to stdio_file for the actual outputting. */ | |
323 | void write (const char *buf, long length_buf) override; | |
324 | void puts (const char *linebuffer) override; | |
325 | }; | |
d9fcf2fb | 326 | |
d7e74731 | 327 | /* A ui_file implementation that maps onto two ui-file objects. */ |
d9fcf2fb | 328 | |
d7e74731 PA |
329 | class tee_file : public ui_file |
330 | { | |
331 | public: | |
f3a09c80 AH |
332 | /* Create a file which writes to both ONE and TWO. ONE will remain |
333 | open when this object is destroyed; but TWO will be closed. */ | |
334 | tee_file (ui_file *one, ui_file_up &&two); | |
d7e74731 | 335 | ~tee_file () override; |
d9fcf2fb | 336 | |
d7e74731 PA |
337 | void write (const char *buf, long length_buf) override; |
338 | void write_async_safe (const char *buf, long length_buf) override; | |
339 | void puts (const char *) override; | |
ffa4ac95 | 340 | |
d7e74731 | 341 | bool isatty () override; |
8a522c6c PW |
342 | bool term_out () override; |
343 | bool can_emit_style_escape () override; | |
d7e74731 | 344 | void flush () override; |
ffa4ac95 | 345 | |
3cd52293 TT |
346 | void emit_style_escape (const ui_file_style &style) override |
347 | { | |
348 | m_one->emit_style_escape (style); | |
349 | m_two->emit_style_escape (style); | |
350 | } | |
351 | ||
352 | void reset_style () override | |
84b33497 | 353 | { |
3cd52293 TT |
354 | m_one->reset_style (); |
355 | m_two->reset_style (); | |
84b33497 TT |
356 | } |
357 | ||
9b716718 TT |
358 | void puts_unfiltered (const char *str) override |
359 | { | |
360 | m_one->puts_unfiltered (str); | |
361 | m_two->puts_unfiltered (str); | |
362 | } | |
363 | ||
d7e74731 | 364 | private: |
f3a09c80 AH |
365 | /* The two underlying ui_files. */ |
366 | ui_file *m_one; | |
367 | ui_file_up m_two; | |
d7e74731 | 368 | }; |
d9fcf2fb | 369 | |
0735b091 TT |
370 | /* A ui_file implementation that filters out terminal escape |
371 | sequences. */ | |
372 | ||
373 | class no_terminal_escape_file : public stdio_file | |
374 | { | |
375 | public: | |
376 | no_terminal_escape_file () | |
377 | { | |
378 | } | |
379 | ||
380 | /* Like the stdio_file methods, but these filter out terminal escape | |
381 | sequences. */ | |
382 | void write (const char *buf, long length_buf) override; | |
383 | void puts (const char *linebuffer) override; | |
c8d74a7b TT |
384 | |
385 | void emit_style_escape (const ui_file_style &style) override | |
386 | { | |
387 | } | |
388 | ||
389 | void reset_style () override | |
390 | { | |
391 | } | |
0735b091 TT |
392 | }; |
393 | ||
3c6c449e TT |
394 | /* A ui_file that optionally puts a timestamp at the start of each |
395 | line of output. */ | |
396 | ||
397 | class timestamped_file : public ui_file | |
398 | { | |
399 | public: | |
400 | explicit timestamped_file (ui_file *stream) | |
401 | : m_stream (stream) | |
402 | { | |
403 | } | |
404 | ||
405 | DISABLE_COPY_AND_ASSIGN (timestamped_file); | |
406 | ||
407 | void write (const char *buf, long len) override; | |
408 | ||
409 | private: | |
410 | ||
411 | /* Output is sent here. */ | |
412 | ui_file *m_stream; | |
413 | ||
414 | /* True if the next output should be timestamped. */ | |
415 | bool m_needs_timestamp = true; | |
416 | }; | |
417 | ||
d9fcf2fb | 418 | #endif |