1 /* MI Console code. 2 3 Copyright (C) 2000-2023 Free Software Foundation, Inc. 4 5 Contributed by Cygnus Solutions (a Red Hat company). 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22 /* An MI console is a kind of ui_file stream that sends output to 23 stdout, but encapsulated and prefixed with a distinctive string; 24 for instance, error output is normally identified by a leading 25 "&". */ 26 27 #include "defs.h" 28 #include "mi-console.h" 29 30 /* Create a console that wraps the given output stream RAW with the 31 string PREFIX and quoting it with QUOTE. */ 32 33 mi_console_file::mi_console_file (ui_file *raw, const char *prefix, char quote) 34 : m_raw (raw), 35 m_prefix (prefix), 36 m_quote (quote) 37 {} 38 39 void 40 mi_console_file::write (const char *buf, long length_buf) 41 { 42 size_t prev_size = m_buffer.size (); 43 /* Append the text to our internal buffer. */ 44 m_buffer.write (buf, length_buf); 45 /* Flush when an embedded newline is present anywhere in the 46 buffer. */ 47 if (strchr (m_buffer.c_str () + prev_size, '\n') != NULL) 48 this->flush (); 49 } 50 51 void 52 mi_console_file::write_async_safe (const char *buf, long length_buf) 53 { 54 m_raw->write_async_safe (m_prefix, strlen (m_prefix)); 55 if (m_quote) 56 { 57 m_raw->write_async_safe (&m_quote, 1); 58 m_raw->putstrn (buf, length_buf, m_quote, true); 59 m_raw->write_async_safe (&m_quote, 1); 60 } 61 else 62 m_raw->putstrn (buf, length_buf, 0, true); 63 64 char nl = '\n'; 65 m_raw->write_async_safe (&nl, 1); 66 } 67 68 void 69 mi_console_file::flush () 70 { 71 const std::string &str = m_buffer.string (); 72 73 /* Transform a byte sequence into a console output packet. */ 74 if (!str.empty ()) 75 { 76 size_t length_buf = str.size (); 77 const char *buf = str.data (); 78 79 gdb_puts (m_prefix, m_raw); 80 if (m_quote) 81 { 82 gdb_putc (m_quote, m_raw); 83 m_raw->putstrn (buf, length_buf, m_quote); 84 gdb_putc (m_quote, m_raw); 85 gdb_putc ('\n', m_raw); 86 } 87 else 88 { 89 m_raw->putstrn (buf, length_buf, 0); 90 gdb_putc ('\n', m_raw); 91 } 92 gdb_flush (m_raw); 93 } 94 95 m_buffer.clear (); 96 } 97 98 /* Change the underlying stream of the console directly; this is 99 useful as a minimum-impact way to reflect external changes like 100 logging enable/disable. */ 101 102 void 103 mi_console_file::set_raw (ui_file *raw) 104 { 105 m_raw = raw; 106 } 107