gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / ui-file.c
CommitLineData
d9fcf2fb 1/* UI_FILE - a generic STDIO like output stream.
349c5d5f 2
b811d2c2 3 Copyright (C) 1999-2020 Free Software Foundation, Inc.
d9fcf2fb
JM
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
d9fcf2fb
JM
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
d9fcf2fb 19
581e13c1 20/* Implement the ``struct ui_file'' object. */
d9fcf2fb
JM
21
22#include "defs.h"
23#include "ui-file.h"
94af9270 24#include "gdb_obstack.h"
06cc9596 25#include "gdbsupport/gdb_select.h"
268a13a5 26#include "gdbsupport/filestuff.h"
f64eea3a 27#include "cli/cli-style.h"
d9fcf2fb 28
d7e74731 29null_file null_stream;
d9fcf2fb 30
d7e74731
PA
31ui_file::ui_file ()
32{}
d9fcf2fb 33
d7e74731
PA
34ui_file::~ui_file ()
35{}
d9fcf2fb 36
d7e74731
PA
37void
38ui_file::printf (const char *format, ...)
d9fcf2fb 39{
d7e74731 40 va_list args;
d9fcf2fb 41
d7e74731
PA
42 va_start (args, format);
43 vfprintf_unfiltered (this, format, args);
44 va_end (args);
d9fcf2fb
JM
45}
46
d7e74731
PA
47void
48ui_file::putstr (const char *str, int quoter)
d9fcf2fb 49{
d7e74731 50 fputstr_unfiltered (str, quoter, this);
d9fcf2fb
JM
51}
52
d7e74731
PA
53void
54ui_file::putstrn (const char *str, int n, int quoter)
d9fcf2fb 55{
7c4e78cf 56 fputstrn_unfiltered (str, n, quoter, fputc_unfiltered, this);
d9fcf2fb
JM
57}
58
d7e74731
PA
59int
60ui_file::putc (int c)
449092f6 61{
d7e74731 62 return fputc_unfiltered (c, this);
449092f6
CV
63}
64
d7e74731
PA
65void
66ui_file::vprintf (const char *format, va_list args)
d9fcf2fb 67{
d7e74731 68 vfprintf_unfiltered (this, format, args);
d9fcf2fb
JM
69}
70
d7e74731 71\f
01124a23 72
d7e74731
PA
73void
74null_file::write (const char *buf, long sizeof_buf)
d9fcf2fb 75{
d7e74731 76 /* Discard the request. */
d9fcf2fb
JM
77}
78
d7e74731
PA
79void
80null_file::puts (const char *)
2a9d5ccf 81{
d7e74731 82 /* Discard the request. */
2a9d5ccf
HZ
83}
84
d7e74731
PA
85void
86null_file::write_async_safe (const char *buf, long sizeof_buf)
d9fcf2fb 87{
d7e74731 88 /* Discard the request. */
d9fcf2fb
JM
89}
90
d7e74731
PA
91\f
92
8a522c6c
PW
93/* true if the gdb terminal supports styling, and styling is enabled. */
94
95static bool
96term_cli_styling ()
97{
8a522c6c
PW
98 if (!cli_styling)
99 return false;
100
101 const char *term = getenv ("TERM");
102 /* Windows doesn't by default define $TERM, but can support styles
103 regardless. */
104#ifndef _WIN32
105 if (term == nullptr || !strcmp (term, "dumb"))
106 return false;
107#else
108 /* But if they do define $TERM, let us behave the same as on Posix
109 platforms, for the benefit of programs which invoke GDB as their
110 back-end. */
111 if (term && !strcmp (term, "dumb"))
112 return false;
113#endif
114 return true;
115}
116
d7e74731 117\f
d9fcf2fb 118
d7e74731
PA
119string_file::~string_file ()
120{}
d9fcf2fb
JM
121
122void
d7e74731 123string_file::write (const char *buf, long length_buf)
d9fcf2fb 124{
d7e74731 125 m_string.append (buf, length_buf);
d9fcf2fb
JM
126}
127
8a522c6c
PW
128/* See ui-file.h. */
129
130bool
131string_file::term_out ()
132{
133 return m_term_out;
134}
135
136/* See ui-file.h. */
137
138bool
139string_file::can_emit_style_escape ()
140{
141 return m_term_out && term_cli_styling ();
142}
143
d7e74731 144\f
01124a23 145
d7e74731 146stdio_file::stdio_file (FILE *file, bool close_p)
449092f6 147{
d7e74731
PA
148 set_stream (file);
149 m_close_p = close_p;
449092f6
CV
150}
151
d7e74731
PA
152stdio_file::stdio_file ()
153 : m_file (NULL),
154 m_fd (-1),
155 m_close_p (false)
156{}
d9fcf2fb 157
d7e74731 158stdio_file::~stdio_file ()
2a9d5ccf 159{
d7e74731
PA
160 if (m_close_p)
161 fclose (m_file);
2a9d5ccf
HZ
162}
163
d9fcf2fb 164void
d7e74731 165stdio_file::set_stream (FILE *file)
d9fcf2fb 166{
d7e74731
PA
167 m_file = file;
168 m_fd = fileno (file);
d9fcf2fb
JM
169}
170
d7e74731
PA
171bool
172stdio_file::open (const char *name, const char *mode)
d9fcf2fb 173{
d7e74731
PA
174 /* Close the previous stream, if we own it. */
175 if (m_close_p)
176 {
177 fclose (m_file);
178 m_close_p = false;
179 }
5d502164 180
d419f42d 181 gdb_file_up f = gdb_fopen_cloexec (name, mode);
d9fcf2fb 182
d7e74731
PA
183 if (f == NULL)
184 return false;
d9fcf2fb 185
d419f42d 186 set_stream (f.release ());
d7e74731 187 m_close_p = true;
5d502164 188
d7e74731 189 return true;
d9fcf2fb
JM
190}
191
192void
d7e74731 193stdio_file::flush ()
d9fcf2fb 194{
d7e74731 195 fflush (m_file);
d9fcf2fb
JM
196}
197
d7e74731
PA
198long
199stdio_file::read (char *buf, long length_buf)
449092f6 200{
f0881b37
PA
201 /* Wait until at least one byte of data is available, or we get
202 interrupted with Control-C. */
ad960ed2 203 {
ad960ed2 204 fd_set readfds;
f0881b37 205
ad960ed2 206 FD_ZERO (&readfds);
d7e74731
PA
207 FD_SET (m_fd, &readfds);
208 if (interruptible_select (m_fd + 1, &readfds, NULL, NULL, NULL) == -1)
ad960ed2
DJ
209 return -1;
210 }
211
d7e74731 212 return ::read (m_fd, buf, length_buf);
449092f6
CV
213}
214
d7e74731
PA
215void
216stdio_file::write (const char *buf, long length_buf)
d9fcf2fb 217{
bf1d7d9c 218 /* Calling error crashes when we are called from the exception framework. */
d7e74731 219 if (fwrite (buf, length_buf, 1, m_file))
d4fb63e1
TT
220 {
221 /* Nothing. */
222 }
d9fcf2fb
JM
223}
224
d7e74731
PA
225void
226stdio_file::write_async_safe (const char *buf, long length_buf)
01124a23 227{
9f7bc587
DE
228 /* This is written the way it is to avoid a warning from gcc about not using the
229 result of write (since it can be declared with attribute warn_unused_result).
230 Alas casting to void doesn't work for this. */
d7e74731 231 if (::write (m_fd, buf, length_buf))
d4fb63e1
TT
232 {
233 /* Nothing. */
234 }
01124a23
DE
235}
236
d7e74731
PA
237void
238stdio_file::puts (const char *linebuffer)
d9fcf2fb 239{
e4adb939
EZ
240 /* This host-dependent function (with implementations in
241 posix-hdep.c and mingw-hdep.c) is given the opportunity to
242 process the output first in host-dependent way. If it does, it
243 should return non-zero, to avoid calling fputs below. */
244 if (gdb_console_fputs (linebuffer, m_file))
245 return;
bf1d7d9c 246 /* Calling error crashes when we are called from the exception framework. */
d7e74731 247 if (fputs (linebuffer, m_file))
d4fb63e1
TT
248 {
249 /* Nothing. */
250 }
d9fcf2fb
JM
251}
252
d7e74731
PA
253bool
254stdio_file::isatty ()
d9fcf2fb 255{
d7e74731 256 return ::isatty (m_fd);
d9fcf2fb
JM
257}
258
8a522c6c
PW
259/* See ui-file.h. */
260
261bool
262stdio_file::can_emit_style_escape ()
263{
6ec1d75e 264 return ((this == gdb_stdout || this == gdb_stderr)
8a522c6c
PW
265 && this->isatty ()
266 && term_cli_styling ());
267}
268
d7e74731 269\f
2a9d5ccf 270
d7e74731 271/* This is the implementation of ui_file method 'write' for stderr.
ffa4ac95
YQ
272 gdb_stdout is flushed before writing to gdb_stderr. */
273
d7e74731
PA
274void
275stderr_file::write (const char *buf, long length_buf)
ffa4ac95 276{
da5bd37e 277 gdb_stdout->flush ();
d7e74731 278 stdio_file::write (buf, length_buf);
ffa4ac95
YQ
279}
280
d7e74731 281/* This is the implementation of ui_file method 'puts' for stderr.
ffa4ac95
YQ
282 gdb_stdout is flushed before writing to gdb_stderr. */
283
d7e74731
PA
284void
285stderr_file::puts (const char *linebuffer)
ffa4ac95 286{
da5bd37e 287 gdb_stdout->flush ();
d7e74731 288 stdio_file::puts (linebuffer);
ffa4ac95 289}
ffa4ac95 290
d7e74731
PA
291stderr_file::stderr_file (FILE *stream)
292 : stdio_file (stream)
293{}
d9fcf2fb 294
d7e74731 295\f
e4c242d9 296
f3a09c80 297tee_file::tee_file (ui_file *one, ui_file_up &&two)
d7e74731 298 : m_one (one),
f3a09c80 299 m_two (std::move (two))
d7e74731 300{}
e4c242d9 301
d7e74731 302tee_file::~tee_file ()
e4c242d9 303{
e4c242d9
DJ
304}
305
d7e74731
PA
306void
307tee_file::flush ()
e4c242d9 308{
d7e74731
PA
309 m_one->flush ();
310 m_two->flush ();
e4c242d9
DJ
311}
312
d7e74731
PA
313void
314tee_file::write (const char *buf, long length_buf)
e4c242d9 315{
d7e74731
PA
316 m_one->write (buf, length_buf);
317 m_two->write (buf, length_buf);
e4c242d9
DJ
318}
319
d7e74731
PA
320void
321tee_file::write_async_safe (const char *buf, long length_buf)
e4c242d9 322{
d7e74731
PA
323 m_one->write_async_safe (buf, length_buf);
324 m_two->write_async_safe (buf, length_buf);
e4c242d9
DJ
325}
326
d7e74731
PA
327void
328tee_file::puts (const char *linebuffer)
e4c242d9 329{
d7e74731
PA
330 m_one->puts (linebuffer);
331 m_two->puts (linebuffer);
e4c242d9
DJ
332}
333
d7e74731
PA
334bool
335tee_file::isatty ()
e4c242d9 336{
d7e74731 337 return m_one->isatty ();
e4c242d9 338}
8a522c6c
PW
339
340/* See ui-file.h. */
341
342bool
343tee_file::term_out ()
344{
345 return m_one->term_out ();
346}
347
348/* See ui-file.h. */
349
350bool
351tee_file::can_emit_style_escape ()
352{
6ec1d75e 353 return ((this == gdb_stdout || this == gdb_stderr)
8a522c6c
PW
354 && m_one->term_out ()
355 && term_cli_styling ());
356}
0735b091
TT
357
358/* See ui-file.h. */
359
360void
361no_terminal_escape_file::write (const char *buf, long length_buf)
362{
363 std::string copy (buf, length_buf);
364 this->puts (copy.c_str ());
365}
366
367/* See ui-file.h. */
368
369void
370no_terminal_escape_file::puts (const char *buf)
371{
372 while (*buf != '\0')
373 {
374 const char *esc = strchr (buf, '\033');
375 if (esc == nullptr)
376 break;
377
378 int n_read = 0;
379 if (!skip_ansi_escape (esc, &n_read))
380 ++esc;
381
382 this->stdio_file::write (buf, esc - buf);
383 buf = esc + n_read;
384 }
385
386 if (*buf != '\0')
387 this->stdio_file::write (buf, strlen (buf));
388}
This page took 2.204954 seconds and 4 git commands to generate.