xref: /dflybsd-src/contrib/gdb-7/gdb/tui/tui-file.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* UI_FILE - a generic STDIO like output stream.
2*ef5ccd6cSJohn Marino    Copyright (C) 1999-2013 Free Software Foundation, Inc.
35796c8dcSSimon Schubert 
45796c8dcSSimon Schubert    This file is part of GDB.
55796c8dcSSimon Schubert 
65796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
75796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
85796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
95796c8dcSSimon Schubert    (at your option) any later version.
105796c8dcSSimon Schubert 
115796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
125796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
135796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
145796c8dcSSimon Schubert    GNU General Public License for more details.
155796c8dcSSimon Schubert 
165796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
175796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
185796c8dcSSimon Schubert 
195796c8dcSSimon Schubert #include "defs.h"
205796c8dcSSimon Schubert #include "ui-file.h"
215796c8dcSSimon Schubert #include "tui/tui-file.h"
225796c8dcSSimon Schubert #include "tui/tui-io.h"
235796c8dcSSimon Schubert 
245796c8dcSSimon Schubert #include "tui.h"
255796c8dcSSimon Schubert 
265796c8dcSSimon Schubert #include "gdb_string.h"
275796c8dcSSimon Schubert 
285796c8dcSSimon Schubert /* A ``struct ui_file'' that is compatible with all the legacy
295796c8dcSSimon Schubert    code.  */
305796c8dcSSimon Schubert 
315796c8dcSSimon Schubert /* new */
325796c8dcSSimon Schubert enum streamtype
335796c8dcSSimon Schubert {
345796c8dcSSimon Schubert   afile,
355796c8dcSSimon Schubert   astring
365796c8dcSSimon Schubert };
375796c8dcSSimon Schubert 
385796c8dcSSimon Schubert /* new */
395796c8dcSSimon Schubert struct tui_stream
405796c8dcSSimon Schubert {
415796c8dcSSimon Schubert   int *ts_magic;
425796c8dcSSimon Schubert   enum streamtype ts_streamtype;
435796c8dcSSimon Schubert   FILE *ts_filestream;
445796c8dcSSimon Schubert   char *ts_strbuf;
455796c8dcSSimon Schubert   int ts_buflen;
465796c8dcSSimon Schubert };
475796c8dcSSimon Schubert 
485796c8dcSSimon Schubert static ui_file_flush_ftype tui_file_flush;
495796c8dcSSimon Schubert extern ui_file_fputs_ftype tui_file_fputs;
505796c8dcSSimon Schubert static ui_file_isatty_ftype tui_file_isatty;
515796c8dcSSimon Schubert static ui_file_rewind_ftype tui_file_rewind;
525796c8dcSSimon Schubert static ui_file_put_ftype tui_file_put;
535796c8dcSSimon Schubert static ui_file_delete_ftype tui_file_delete;
545796c8dcSSimon Schubert static struct ui_file *tui_file_new (void);
555796c8dcSSimon Schubert static int tui_file_magic;
565796c8dcSSimon Schubert 
575796c8dcSSimon Schubert static struct ui_file *
tui_file_new(void)585796c8dcSSimon Schubert tui_file_new (void)
595796c8dcSSimon Schubert {
605796c8dcSSimon Schubert   struct tui_stream *tui = XMALLOC (struct tui_stream);
615796c8dcSSimon Schubert   struct ui_file *file = ui_file_new ();
62cf7f2e2dSJohn Marino 
635796c8dcSSimon Schubert   set_ui_file_data (file, tui, tui_file_delete);
645796c8dcSSimon Schubert   set_ui_file_flush (file, tui_file_flush);
655796c8dcSSimon Schubert   set_ui_file_fputs (file, tui_file_fputs);
665796c8dcSSimon Schubert   set_ui_file_isatty (file, tui_file_isatty);
675796c8dcSSimon Schubert   set_ui_file_rewind (file, tui_file_rewind);
685796c8dcSSimon Schubert   set_ui_file_put (file, tui_file_put);
695796c8dcSSimon Schubert   tui->ts_magic = &tui_file_magic;
705796c8dcSSimon Schubert   return file;
715796c8dcSSimon Schubert }
725796c8dcSSimon Schubert 
735796c8dcSSimon Schubert static void
tui_file_delete(struct ui_file * file)745796c8dcSSimon Schubert tui_file_delete (struct ui_file *file)
755796c8dcSSimon Schubert {
765796c8dcSSimon Schubert   struct tui_stream *tmpstream = ui_file_data (file);
77cf7f2e2dSJohn Marino 
785796c8dcSSimon Schubert   if (tmpstream->ts_magic != &tui_file_magic)
795796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
805796c8dcSSimon Schubert 		    _("tui_file_delete: bad magic number"));
815796c8dcSSimon Schubert   if ((tmpstream->ts_streamtype == astring)
825796c8dcSSimon Schubert       && (tmpstream->ts_strbuf != NULL))
835796c8dcSSimon Schubert     {
845796c8dcSSimon Schubert       xfree (tmpstream->ts_strbuf);
855796c8dcSSimon Schubert     }
865796c8dcSSimon Schubert   xfree (tmpstream);
875796c8dcSSimon Schubert }
885796c8dcSSimon Schubert 
895796c8dcSSimon Schubert struct ui_file *
tui_fileopen(FILE * stream)905796c8dcSSimon Schubert tui_fileopen (FILE *stream)
915796c8dcSSimon Schubert {
925796c8dcSSimon Schubert   struct ui_file *file = tui_file_new ();
935796c8dcSSimon Schubert   struct tui_stream *tmpstream = ui_file_data (file);
94cf7f2e2dSJohn Marino 
955796c8dcSSimon Schubert   tmpstream->ts_streamtype = afile;
965796c8dcSSimon Schubert   tmpstream->ts_filestream = stream;
975796c8dcSSimon Schubert   tmpstream->ts_strbuf = NULL;
985796c8dcSSimon Schubert   tmpstream->ts_buflen = 0;
995796c8dcSSimon Schubert   return file;
1005796c8dcSSimon Schubert }
1015796c8dcSSimon Schubert 
1025796c8dcSSimon Schubert struct ui_file *
tui_sfileopen(int n)1035796c8dcSSimon Schubert tui_sfileopen (int n)
1045796c8dcSSimon Schubert {
1055796c8dcSSimon Schubert   struct ui_file *file = tui_file_new ();
1065796c8dcSSimon Schubert   struct tui_stream *tmpstream = ui_file_data (file);
107cf7f2e2dSJohn Marino 
1085796c8dcSSimon Schubert   tmpstream->ts_streamtype = astring;
1095796c8dcSSimon Schubert   tmpstream->ts_filestream = NULL;
1105796c8dcSSimon Schubert   if (n > 0)
1115796c8dcSSimon Schubert     {
1125796c8dcSSimon Schubert       tmpstream->ts_strbuf = xmalloc ((n + 1) * sizeof (char));
1135796c8dcSSimon Schubert       tmpstream->ts_strbuf[0] = '\0';
1145796c8dcSSimon Schubert     }
1155796c8dcSSimon Schubert   else
1165796c8dcSSimon Schubert     /* Do not allocate the buffer now.  The first time something is
1175796c8dcSSimon Schubert        printed one will be allocated by tui_file_adjust_strbuf().  */
1185796c8dcSSimon Schubert     tmpstream->ts_strbuf = NULL;
1195796c8dcSSimon Schubert   tmpstream->ts_buflen = n;
1205796c8dcSSimon Schubert   return file;
1215796c8dcSSimon Schubert }
1225796c8dcSSimon Schubert 
1235796c8dcSSimon Schubert static int
tui_file_isatty(struct ui_file * file)1245796c8dcSSimon Schubert tui_file_isatty (struct ui_file *file)
1255796c8dcSSimon Schubert {
1265796c8dcSSimon Schubert   struct tui_stream *stream = ui_file_data (file);
127cf7f2e2dSJohn Marino 
1285796c8dcSSimon Schubert   if (stream->ts_magic != &tui_file_magic)
1295796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
1305796c8dcSSimon Schubert 		    _("tui_file_isatty: bad magic number"));
1315796c8dcSSimon Schubert   if (stream->ts_streamtype == afile)
1325796c8dcSSimon Schubert     return (isatty (fileno (stream->ts_filestream)));
1335796c8dcSSimon Schubert   else
1345796c8dcSSimon Schubert     return 0;
1355796c8dcSSimon Schubert }
1365796c8dcSSimon Schubert 
1375796c8dcSSimon Schubert static void
tui_file_rewind(struct ui_file * file)1385796c8dcSSimon Schubert tui_file_rewind (struct ui_file *file)
1395796c8dcSSimon Schubert {
1405796c8dcSSimon Schubert   struct tui_stream *stream = ui_file_data (file);
141cf7f2e2dSJohn Marino 
1425796c8dcSSimon Schubert   if (stream->ts_magic != &tui_file_magic)
1435796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
1445796c8dcSSimon Schubert 		    _("tui_file_rewind: bad magic number"));
1455796c8dcSSimon Schubert   stream->ts_strbuf[0] = '\0';
1465796c8dcSSimon Schubert }
1475796c8dcSSimon Schubert 
1485796c8dcSSimon Schubert static void
tui_file_put(struct ui_file * file,ui_file_put_method_ftype * write,void * dest)1495796c8dcSSimon Schubert tui_file_put (struct ui_file *file,
1505796c8dcSSimon Schubert 	      ui_file_put_method_ftype *write,
1515796c8dcSSimon Schubert 	      void *dest)
1525796c8dcSSimon Schubert {
1535796c8dcSSimon Schubert   struct tui_stream *stream = ui_file_data (file);
154cf7f2e2dSJohn Marino 
1555796c8dcSSimon Schubert   if (stream->ts_magic != &tui_file_magic)
1565796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
1575796c8dcSSimon Schubert 		    _("tui_file_put: bad magic number"));
1585796c8dcSSimon Schubert   if (stream->ts_streamtype == astring)
1595796c8dcSSimon Schubert     write (dest, stream->ts_strbuf, strlen (stream->ts_strbuf));
1605796c8dcSSimon Schubert }
1615796c8dcSSimon Schubert 
1625796c8dcSSimon Schubert /* All TUI I/O sent to the *_filtered and *_unfiltered functions
1635796c8dcSSimon Schubert    eventually ends up here.  The fputs_unfiltered_hook is primarily
1645796c8dcSSimon Schubert    used by GUIs to collect all output and send it to the GUI, instead
1655796c8dcSSimon Schubert    of the controlling terminal.  Only output to gdb_stdout and
1665796c8dcSSimon Schubert    gdb_stderr are sent to the hook.  Everything else is sent on to
1675796c8dcSSimon Schubert    fputs to allow file I/O to be handled appropriately.  */
1685796c8dcSSimon Schubert 
1695796c8dcSSimon Schubert /* FIXME: Should be broken up and moved to a TUI specific file.  */
1705796c8dcSSimon Schubert 
1715796c8dcSSimon Schubert void
tui_file_fputs(const char * linebuffer,struct ui_file * file)1725796c8dcSSimon Schubert tui_file_fputs (const char *linebuffer, struct ui_file *file)
1735796c8dcSSimon Schubert {
1745796c8dcSSimon Schubert   struct tui_stream *stream = ui_file_data (file);
1755796c8dcSSimon Schubert 
1765796c8dcSSimon Schubert   if (stream->ts_streamtype == astring)
1775796c8dcSSimon Schubert     {
1785796c8dcSSimon Schubert       tui_file_adjust_strbuf (strlen (linebuffer), file);
1795796c8dcSSimon Schubert       strcat (stream->ts_strbuf, linebuffer);
1805796c8dcSSimon Schubert     }
1815796c8dcSSimon Schubert   else
1825796c8dcSSimon Schubert     {
1835796c8dcSSimon Schubert       tui_puts (linebuffer);
1845796c8dcSSimon Schubert     }
1855796c8dcSSimon Schubert }
1865796c8dcSSimon Schubert 
1875796c8dcSSimon Schubert char *
tui_file_get_strbuf(struct ui_file * file)1885796c8dcSSimon Schubert tui_file_get_strbuf (struct ui_file *file)
1895796c8dcSSimon Schubert {
1905796c8dcSSimon Schubert   struct tui_stream *stream = ui_file_data (file);
191cf7f2e2dSJohn Marino 
1925796c8dcSSimon Schubert   if (stream->ts_magic != &tui_file_magic)
1935796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
1945796c8dcSSimon Schubert 		    _("tui_file_get_strbuf: bad magic number"));
1955796c8dcSSimon Schubert   return (stream->ts_strbuf);
1965796c8dcSSimon Schubert }
1975796c8dcSSimon Schubert 
1985796c8dcSSimon Schubert /* Adjust the length of the buffer by the amount necessary to
1995796c8dcSSimon Schubert    accomodate appending a string of length N to the buffer
2005796c8dcSSimon Schubert    contents.  */
2015796c8dcSSimon Schubert void
tui_file_adjust_strbuf(int n,struct ui_file * file)2025796c8dcSSimon Schubert tui_file_adjust_strbuf (int n, struct ui_file *file)
2035796c8dcSSimon Schubert {
2045796c8dcSSimon Schubert   struct tui_stream *stream = ui_file_data (file);
2055796c8dcSSimon Schubert   int non_null_chars;
206cf7f2e2dSJohn Marino 
2075796c8dcSSimon Schubert   if (stream->ts_magic != &tui_file_magic)
2085796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
2095796c8dcSSimon Schubert 		    _("tui_file_adjust_strbuf: bad magic number"));
2105796c8dcSSimon Schubert 
2115796c8dcSSimon Schubert   if (stream->ts_streamtype != astring)
2125796c8dcSSimon Schubert     return;
2135796c8dcSSimon Schubert 
2145796c8dcSSimon Schubert   if (stream->ts_strbuf)
2155796c8dcSSimon Schubert     {
2165796c8dcSSimon Schubert       /* There is already a buffer allocated.  */
2175796c8dcSSimon Schubert       non_null_chars = strlen (stream->ts_strbuf);
2185796c8dcSSimon Schubert 
2195796c8dcSSimon Schubert       if (n > (stream->ts_buflen - non_null_chars - 1))
2205796c8dcSSimon Schubert 	{
2215796c8dcSSimon Schubert 	  stream->ts_buflen = n + non_null_chars + 1;
2225796c8dcSSimon Schubert 	  stream->ts_strbuf = xrealloc (stream->ts_strbuf, stream->ts_buflen);
2235796c8dcSSimon Schubert 	}
2245796c8dcSSimon Schubert     }
2255796c8dcSSimon Schubert   else
2265796c8dcSSimon Schubert     /* No buffer yet, so allocate one of the desired size.  */
2275796c8dcSSimon Schubert     stream->ts_strbuf = xmalloc ((n + 1) * sizeof (char));
2285796c8dcSSimon Schubert }
2295796c8dcSSimon Schubert 
2305796c8dcSSimon Schubert static void
tui_file_flush(struct ui_file * file)2315796c8dcSSimon Schubert tui_file_flush (struct ui_file *file)
2325796c8dcSSimon Schubert {
2335796c8dcSSimon Schubert   struct tui_stream *stream = ui_file_data (file);
234cf7f2e2dSJohn Marino 
2355796c8dcSSimon Schubert   if (stream->ts_magic != &tui_file_magic)
2365796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
2375796c8dcSSimon Schubert 		    _("tui_file_flush: bad magic number"));
2385796c8dcSSimon Schubert 
2395796c8dcSSimon Schubert   switch (stream->ts_streamtype)
2405796c8dcSSimon Schubert     {
2415796c8dcSSimon Schubert     case astring:
2425796c8dcSSimon Schubert       break;
2435796c8dcSSimon Schubert     case afile:
2445796c8dcSSimon Schubert       fflush (stream->ts_filestream);
2455796c8dcSSimon Schubert       break;
2465796c8dcSSimon Schubert     }
2475796c8dcSSimon Schubert }
248