X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fui-file.c;h=71b74bba19054d35555e25328a1d6fd84fdaddd5;hb=4bdb25fe6902963ca9cf91d6b2688cf888527bf8;hp=84ad6031a4841c8db2c0b5b2f88a317fd920a5bd;hpb=e2882c85786571175a0b0bfc3bcd2f14620b1ea3;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ui-file.c b/gdb/ui-file.c index 84ad6031a4..71b74bba19 100644 --- a/gdb/ui-file.c +++ b/gdb/ui-file.c @@ -1,6 +1,6 @@ /* UI_FILE - a generic STDIO like output stream. - Copyright (C) 1999-2018 Free Software Foundation, Inc. + Copyright (C) 1999-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -23,7 +23,8 @@ #include "ui-file.h" #include "gdb_obstack.h" #include "gdb_select.h" -#include "filestuff.h" +#include "gdbsupport/filestuff.h" +#include "cli/cli-style.h" null_file null_stream; @@ -52,7 +53,7 @@ ui_file::putstr (const char *str, int quoter) void ui_file::putstrn (const char *str, int n, int quoter) { - fputstrn_unfiltered (str, n, quoter, this); + fputstrn_unfiltered (str, n, quoter, fputc_unfiltered, this); } int @@ -101,6 +102,31 @@ ui_file_isatty (struct ui_file *file) return file->isatty (); } +/* true if the gdb terminal supports styling, and styling is enabled. */ + +static bool +term_cli_styling () +{ + if (!cli_styling) + return false; + + const char *term = getenv ("TERM"); + /* Windows doesn't by default define $TERM, but can support styles + regardless. */ +#ifndef _WIN32 + if (term == nullptr || !strcmp (term, "dumb")) + return false; +#else + /* But if they do define $TERM, let us behave the same as on Posix + platforms, for the benefit of programs which invoke GDB as their + back-end. */ + if (term && !strcmp (term, "dumb")) + return false; +#endif + return true; +} + + void ui_file_write (struct ui_file *file, const char *buf, @@ -140,6 +166,22 @@ string_file::write (const char *buf, long length_buf) m_string.append (buf, length_buf); } +/* See ui-file.h. */ + +bool +string_file::term_out () +{ + return m_term_out; +} + +/* See ui-file.h. */ + +bool +string_file::can_emit_style_escape () +{ + return m_term_out && term_cli_styling (); +} + stdio_file::stdio_file (FILE *file, bool close_p) @@ -236,6 +278,12 @@ stdio_file::write_async_safe (const char *buf, long length_buf) void stdio_file::puts (const char *linebuffer) { + /* This host-dependent function (with implementations in + posix-hdep.c and mingw-hdep.c) is given the opportunity to + process the output first in host-dependent way. If it does, it + should return non-zero, to avoid calling fputs below. */ + if (gdb_console_fputs (linebuffer, m_file)) + return; /* Calling error crashes when we are called from the exception framework. */ if (fputs (linebuffer, m_file)) { @@ -249,6 +297,16 @@ stdio_file::isatty () return ::isatty (m_fd); } +/* See ui-file.h. */ + +bool +stdio_file::can_emit_style_escape () +{ + return (this == gdb_stdout + && this->isatty () + && term_cli_styling ()); +} + /* This is the implementation of ui_file method 'write' for stderr. @@ -277,20 +335,13 @@ stderr_file::stderr_file (FILE *stream) -tee_file::tee_file (ui_file *one, bool close_one, - ui_file *two, bool close_two) +tee_file::tee_file (ui_file *one, ui_file_up &&two) : m_one (one), - m_two (two), - m_close_one (close_one), - m_close_two (close_two) + m_two (std::move (two)) {} tee_file::~tee_file () { - if (m_close_one) - delete m_one; - if (m_close_two) - delete m_two; } void @@ -326,3 +377,53 @@ tee_file::isatty () { return m_one->isatty (); } + +/* See ui-file.h. */ + +bool +tee_file::term_out () +{ + return m_one->term_out (); +} + +/* See ui-file.h. */ + +bool +tee_file::can_emit_style_escape () +{ + return (this == gdb_stdout + && m_one->term_out () + && term_cli_styling ()); +} + +/* See ui-file.h. */ + +void +no_terminal_escape_file::write (const char *buf, long length_buf) +{ + std::string copy (buf, length_buf); + this->puts (copy.c_str ()); +} + +/* See ui-file.h. */ + +void +no_terminal_escape_file::puts (const char *buf) +{ + while (*buf != '\0') + { + const char *esc = strchr (buf, '\033'); + if (esc == nullptr) + break; + + int n_read = 0; + if (!skip_ansi_escape (esc, &n_read)) + ++esc; + + this->stdio_file::write (buf, esc - buf); + buf = esc + n_read; + } + + if (*buf != '\0') + this->stdio_file::write (buf, strlen (buf)); +}