GDB (API)
/home/stan/gdb/src/gdb/mi/mi-console.c
Go to the documentation of this file.
00001 /* MI Console code.
00002 
00003    Copyright (C) 2000-2013 Free Software Foundation, Inc.
00004 
00005    Contributed by Cygnus Solutions (a Red Hat company).
00006 
00007    This file is part of GDB.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 3 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00021 
00022 /* An MI console is a kind of ui_file stream that sends output to
00023    stdout, but encapsulated and prefixed with a distinctive string;
00024    for instance, error output is normally identified by a leading
00025    "&".  */
00026 
00027 #include "defs.h"
00028 #include "mi-console.h"
00029 #include "gdb_string.h"
00030 
00031 static ui_file_fputs_ftype mi_console_file_fputs;
00032 static ui_file_flush_ftype mi_console_file_flush;
00033 static ui_file_delete_ftype mi_console_file_delete;
00034 
00035 struct mi_console_file
00036   {
00037     int *magic;
00038     struct ui_file *raw;
00039     struct ui_file *buffer;
00040     const char *prefix;
00041     char quote;
00042   };
00043 
00044 /* Use the address of this otherwise-unused global as a magic number
00045    identifying this class of ui_file objects.  */
00046 static int mi_console_file_magic;
00047 
00048 /* Create a console that wraps the given output stream RAW with the
00049    string PREFIX and quoting it with QUOTE.  */
00050 
00051 struct ui_file *
00052 mi_console_file_new (struct ui_file *raw, const char *prefix, char quote)
00053 {
00054   struct ui_file *ui_file = ui_file_new ();
00055   struct mi_console_file *mi_console = XMALLOC (struct mi_console_file);
00056 
00057   mi_console->magic = &mi_console_file_magic;
00058   mi_console->raw = raw;
00059   mi_console->buffer = mem_fileopen ();
00060   mi_console->prefix = prefix;
00061   mi_console->quote = quote;
00062   set_ui_file_fputs (ui_file, mi_console_file_fputs);
00063   set_ui_file_flush (ui_file, mi_console_file_flush);
00064   set_ui_file_data (ui_file, mi_console, mi_console_file_delete);
00065 
00066   return ui_file;
00067 }
00068 
00069 static void
00070 mi_console_file_delete (struct ui_file *file)
00071 {
00072   struct mi_console_file *mi_console = ui_file_data (file);
00073 
00074   if (mi_console->magic != &mi_console_file_magic)
00075     internal_error (__FILE__, __LINE__,
00076                     _("mi_console_file_delete: bad magic number"));
00077 
00078   xfree (mi_console);
00079 }
00080 
00081 static void
00082 mi_console_file_fputs (const char *buf, struct ui_file *file)
00083 {
00084   struct mi_console_file *mi_console = ui_file_data (file);
00085 
00086   if (mi_console->magic != &mi_console_file_magic)
00087     internal_error (__FILE__, __LINE__,
00088                     "mi_console_file_fputs: bad magic number");
00089 
00090   /* Append the text to our internal buffer.  */
00091   fputs_unfiltered (buf, mi_console->buffer);
00092   /* Flush when an embedded newline is present anywhere in the buffer.  */
00093   if (strchr (buf, '\n') != NULL)
00094     gdb_flush (file);
00095 }
00096 
00097 /* Transform a byte sequence into a console output packet.  */
00098 
00099 static void
00100 mi_console_raw_packet (void *data, const char *buf, long length_buf)
00101 {
00102   struct mi_console_file *mi_console = data;
00103 
00104   if (mi_console->magic != &mi_console_file_magic)
00105     internal_error (__FILE__, __LINE__,
00106                     _("mi_console_raw_packet: bad magic number"));
00107 
00108   if (length_buf > 0)
00109     {
00110       fputs_unfiltered (mi_console->prefix, mi_console->raw);
00111       if (mi_console->quote)
00112         {
00113           fputs_unfiltered ("\"", mi_console->raw);
00114           fputstrn_unfiltered (buf, length_buf,
00115                                mi_console->quote, mi_console->raw);
00116           fputs_unfiltered ("\"\n", mi_console->raw);
00117         }
00118       else
00119         {
00120           fputstrn_unfiltered (buf, length_buf, 0, mi_console->raw);
00121           fputs_unfiltered ("\n", mi_console->raw);
00122         }
00123       gdb_flush (mi_console->raw);
00124     }
00125 }
00126 
00127 static void
00128 mi_console_file_flush (struct ui_file *file)
00129 {
00130   struct mi_console_file *mi_console = ui_file_data (file);
00131 
00132   if (mi_console->magic != &mi_console_file_magic)
00133     internal_error (__FILE__, __LINE__,
00134                     _("mi_console_file_flush: bad magic number"));
00135 
00136   ui_file_put (mi_console->buffer, mi_console_raw_packet, mi_console);
00137   ui_file_rewind (mi_console->buffer);
00138 
00139 }
00140 
00141 /* Change the underlying stream of the console directly; this is
00142    useful as a minimum-impact way to reflect external changes like
00143    logging enable/disable.  */
00144 
00145 void
00146 mi_console_set_raw (struct ui_file *file, struct ui_file *raw)
00147 {
00148   struct mi_console_file *mi_console = ui_file_data (file);
00149 
00150   if (mi_console->magic != &mi_console_file_magic)
00151     internal_error (__FILE__, __LINE__,
00152                     _("mi_console_file_set_raw: bad magic number"));
00153 
00154   mi_console->raw = raw;
00155 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines