GDB (API)
/home/stan/gdb/src/gdb/tui/tui-file.c
Go to the documentation of this file.
00001 /* UI_FILE - a generic STDIO like output stream.
00002    Copyright (C) 1999-2013 Free Software Foundation, Inc.
00003 
00004    This file is part of GDB.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 3 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00018 
00019 #include "defs.h"
00020 #include "ui-file.h"
00021 #include "tui/tui-file.h"
00022 #include "tui/tui-io.h"
00023 
00024 #include "tui.h"
00025 
00026 #include "gdb_string.h"
00027 
00028 /* A ``struct ui_file'' that is compatible with all the legacy
00029    code.  */
00030 
00031 /* new */
00032 enum streamtype
00033 {
00034   afile,
00035   astring
00036 };
00037 
00038 /* new */
00039 struct tui_stream
00040 {
00041   int *ts_magic;
00042   enum streamtype ts_streamtype;
00043   FILE *ts_filestream;
00044   char *ts_strbuf;
00045   int ts_buflen;
00046 };
00047 
00048 static ui_file_flush_ftype tui_file_flush;
00049 extern ui_file_fputs_ftype tui_file_fputs;
00050 static ui_file_isatty_ftype tui_file_isatty;
00051 static ui_file_rewind_ftype tui_file_rewind;
00052 static ui_file_put_ftype tui_file_put;
00053 static ui_file_delete_ftype tui_file_delete;
00054 static struct ui_file *tui_file_new (void);
00055 static int tui_file_magic;
00056 
00057 static struct ui_file *
00058 tui_file_new (void)
00059 {
00060   struct tui_stream *tui = XMALLOC (struct tui_stream);
00061   struct ui_file *file = ui_file_new ();
00062 
00063   set_ui_file_data (file, tui, tui_file_delete);
00064   set_ui_file_flush (file, tui_file_flush);
00065   set_ui_file_fputs (file, tui_file_fputs);
00066   set_ui_file_isatty (file, tui_file_isatty);
00067   set_ui_file_rewind (file, tui_file_rewind);
00068   set_ui_file_put (file, tui_file_put);
00069   tui->ts_magic = &tui_file_magic;
00070   return file;
00071 }
00072 
00073 static void
00074 tui_file_delete (struct ui_file *file)
00075 {
00076   struct tui_stream *tmpstream = ui_file_data (file);
00077 
00078   if (tmpstream->ts_magic != &tui_file_magic)
00079     internal_error (__FILE__, __LINE__,
00080                     _("tui_file_delete: bad magic number"));
00081   if ((tmpstream->ts_streamtype == astring) 
00082       && (tmpstream->ts_strbuf != NULL))
00083     {
00084       xfree (tmpstream->ts_strbuf);
00085     }
00086   xfree (tmpstream);
00087 }
00088 
00089 struct ui_file *
00090 tui_fileopen (FILE *stream)
00091 {
00092   struct ui_file *file = tui_file_new ();
00093   struct tui_stream *tmpstream = ui_file_data (file);
00094 
00095   tmpstream->ts_streamtype = afile;
00096   tmpstream->ts_filestream = stream;
00097   tmpstream->ts_strbuf = NULL;
00098   tmpstream->ts_buflen = 0;
00099   return file;
00100 }
00101 
00102 struct ui_file *
00103 tui_sfileopen (int n)
00104 {
00105   struct ui_file *file = tui_file_new ();
00106   struct tui_stream *tmpstream = ui_file_data (file);
00107 
00108   tmpstream->ts_streamtype = astring;
00109   tmpstream->ts_filestream = NULL;
00110   if (n > 0)
00111     {
00112       tmpstream->ts_strbuf = xmalloc ((n + 1) * sizeof (char));
00113       tmpstream->ts_strbuf[0] = '\0';
00114     }
00115   else
00116     /* Do not allocate the buffer now.  The first time something is
00117        printed one will be allocated by tui_file_adjust_strbuf().  */
00118     tmpstream->ts_strbuf = NULL;
00119   tmpstream->ts_buflen = n;
00120   return file;
00121 }
00122 
00123 static int
00124 tui_file_isatty (struct ui_file *file)
00125 {
00126   struct tui_stream *stream = ui_file_data (file);
00127 
00128   if (stream->ts_magic != &tui_file_magic)
00129     internal_error (__FILE__, __LINE__,
00130                     _("tui_file_isatty: bad magic number"));
00131   if (stream->ts_streamtype == afile)
00132     return (isatty (fileno (stream->ts_filestream)));
00133   else
00134     return 0;
00135 }
00136 
00137 static void
00138 tui_file_rewind (struct ui_file *file)
00139 {
00140   struct tui_stream *stream = ui_file_data (file);
00141 
00142   if (stream->ts_magic != &tui_file_magic)
00143     internal_error (__FILE__, __LINE__,
00144                     _("tui_file_rewind: bad magic number"));
00145   stream->ts_strbuf[0] = '\0';
00146 }
00147 
00148 static void
00149 tui_file_put (struct ui_file *file,
00150               ui_file_put_method_ftype *write,
00151               void *dest)
00152 {
00153   struct tui_stream *stream = ui_file_data (file);
00154 
00155   if (stream->ts_magic != &tui_file_magic)
00156     internal_error (__FILE__, __LINE__,
00157                     _("tui_file_put: bad magic number"));
00158   if (stream->ts_streamtype == astring)
00159     write (dest, stream->ts_strbuf, strlen (stream->ts_strbuf));
00160 }
00161 
00162 /* All TUI I/O sent to the *_filtered and *_unfiltered functions
00163    eventually ends up here.  The fputs_unfiltered_hook is primarily
00164    used by GUIs to collect all output and send it to the GUI, instead
00165    of the controlling terminal.  Only output to gdb_stdout and
00166    gdb_stderr are sent to the hook.  Everything else is sent on to
00167    fputs to allow file I/O to be handled appropriately.  */
00168 
00169 /* FIXME: Should be broken up and moved to a TUI specific file.  */
00170 
00171 void
00172 tui_file_fputs (const char *linebuffer, struct ui_file *file)
00173 {
00174   struct tui_stream *stream = ui_file_data (file);
00175 
00176   if (stream->ts_streamtype == astring)
00177     {
00178       tui_file_adjust_strbuf (strlen (linebuffer), file);
00179       strcat (stream->ts_strbuf, linebuffer);
00180     }
00181   else
00182     {
00183       tui_puts (linebuffer);
00184     }
00185 }
00186 
00187 char *
00188 tui_file_get_strbuf (struct ui_file *file)
00189 {
00190   struct tui_stream *stream = ui_file_data (file);
00191 
00192   if (stream->ts_magic != &tui_file_magic)
00193     internal_error (__FILE__, __LINE__,
00194                     _("tui_file_get_strbuf: bad magic number"));
00195   return (stream->ts_strbuf);
00196 }
00197 
00198 /* Adjust the length of the buffer by the amount necessary to
00199    accomodate appending a string of length N to the buffer
00200    contents.  */
00201 void
00202 tui_file_adjust_strbuf (int n, struct ui_file *file)
00203 {
00204   struct tui_stream *stream = ui_file_data (file);
00205   int non_null_chars;
00206 
00207   if (stream->ts_magic != &tui_file_magic)
00208     internal_error (__FILE__, __LINE__,
00209                     _("tui_file_adjust_strbuf: bad magic number"));
00210 
00211   if (stream->ts_streamtype != astring)
00212     return;
00213 
00214   if (stream->ts_strbuf)
00215     {
00216       /* There is already a buffer allocated.  */
00217       non_null_chars = strlen (stream->ts_strbuf);
00218 
00219       if (n > (stream->ts_buflen - non_null_chars - 1))
00220         {
00221           stream->ts_buflen = n + non_null_chars + 1;
00222           stream->ts_strbuf = xrealloc (stream->ts_strbuf, stream->ts_buflen);
00223         }
00224     }
00225   else
00226     /* No buffer yet, so allocate one of the desired size.  */
00227     stream->ts_strbuf = xmalloc ((n + 1) * sizeof (char));
00228 }
00229 
00230 static void
00231 tui_file_flush (struct ui_file *file)
00232 {
00233   struct tui_stream *stream = ui_file_data (file);
00234 
00235   if (stream->ts_magic != &tui_file_magic)
00236     internal_error (__FILE__, __LINE__,
00237                     _("tui_file_flush: bad magic number"));
00238 
00239   switch (stream->ts_streamtype)
00240     {
00241     case astring:
00242       break;
00243     case afile:
00244       fflush (stream->ts_filestream);
00245       break;
00246     }
00247 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines