xref: /dflybsd-src/contrib/gdb-7/gdb/ui-file.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* UI_FILE - a generic STDIO like output stream.
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright (C) 1999-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of GDB.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
195796c8dcSSimon Schubert 
205796c8dcSSimon Schubert /* Implement the ``struct ui_file'' object.  */
215796c8dcSSimon Schubert 
225796c8dcSSimon Schubert #include "defs.h"
235796c8dcSSimon Schubert #include "ui-file.h"
24cf7f2e2dSJohn Marino #include "gdb_obstack.h"
255796c8dcSSimon Schubert #include "gdb_string.h"
26cf7f2e2dSJohn Marino #include "gdb_select.h"
275796c8dcSSimon Schubert 
285796c8dcSSimon Schubert #include <errno.h>
295796c8dcSSimon Schubert 
305796c8dcSSimon Schubert static ui_file_isatty_ftype null_file_isatty;
315796c8dcSSimon Schubert static ui_file_write_ftype null_file_write;
32a45ae5f8SJohn Marino static ui_file_write_ftype null_file_write_async_safe;
335796c8dcSSimon Schubert static ui_file_fputs_ftype null_file_fputs;
345796c8dcSSimon Schubert static ui_file_read_ftype null_file_read;
355796c8dcSSimon Schubert static ui_file_flush_ftype null_file_flush;
365796c8dcSSimon Schubert static ui_file_delete_ftype null_file_delete;
375796c8dcSSimon Schubert static ui_file_rewind_ftype null_file_rewind;
385796c8dcSSimon Schubert static ui_file_put_ftype null_file_put;
39*ef5ccd6cSJohn Marino static ui_file_fseek_ftype null_file_fseek;
405796c8dcSSimon Schubert 
415796c8dcSSimon Schubert struct ui_file
425796c8dcSSimon Schubert   {
435796c8dcSSimon Schubert     int *magic;
445796c8dcSSimon Schubert     ui_file_flush_ftype *to_flush;
455796c8dcSSimon Schubert     ui_file_write_ftype *to_write;
46a45ae5f8SJohn Marino     ui_file_write_async_safe_ftype *to_write_async_safe;
475796c8dcSSimon Schubert     ui_file_fputs_ftype *to_fputs;
485796c8dcSSimon Schubert     ui_file_read_ftype *to_read;
495796c8dcSSimon Schubert     ui_file_delete_ftype *to_delete;
505796c8dcSSimon Schubert     ui_file_isatty_ftype *to_isatty;
515796c8dcSSimon Schubert     ui_file_rewind_ftype *to_rewind;
525796c8dcSSimon Schubert     ui_file_put_ftype *to_put;
53*ef5ccd6cSJohn Marino     ui_file_fseek_ftype *to_fseek;
545796c8dcSSimon Schubert     void *to_data;
555796c8dcSSimon Schubert   };
565796c8dcSSimon Schubert int ui_file_magic;
575796c8dcSSimon Schubert 
585796c8dcSSimon Schubert struct ui_file *
ui_file_new(void)595796c8dcSSimon Schubert ui_file_new (void)
605796c8dcSSimon Schubert {
615796c8dcSSimon Schubert   struct ui_file *file = xmalloc (sizeof (struct ui_file));
62cf7f2e2dSJohn Marino 
635796c8dcSSimon Schubert   file->magic = &ui_file_magic;
645796c8dcSSimon Schubert   set_ui_file_data (file, NULL, null_file_delete);
655796c8dcSSimon Schubert   set_ui_file_flush (file, null_file_flush);
665796c8dcSSimon Schubert   set_ui_file_write (file, null_file_write);
67a45ae5f8SJohn Marino   set_ui_file_write_async_safe (file, null_file_write_async_safe);
685796c8dcSSimon Schubert   set_ui_file_fputs (file, null_file_fputs);
695796c8dcSSimon Schubert   set_ui_file_read (file, null_file_read);
705796c8dcSSimon Schubert   set_ui_file_isatty (file, null_file_isatty);
715796c8dcSSimon Schubert   set_ui_file_rewind (file, null_file_rewind);
725796c8dcSSimon Schubert   set_ui_file_put (file, null_file_put);
73*ef5ccd6cSJohn Marino   set_ui_file_fseek (file, null_file_fseek);
745796c8dcSSimon Schubert   return file;
755796c8dcSSimon Schubert }
765796c8dcSSimon Schubert 
775796c8dcSSimon Schubert void
ui_file_delete(struct ui_file * file)785796c8dcSSimon Schubert ui_file_delete (struct ui_file *file)
795796c8dcSSimon Schubert {
805796c8dcSSimon Schubert   file->to_delete (file);
815796c8dcSSimon Schubert   xfree (file);
825796c8dcSSimon Schubert }
835796c8dcSSimon Schubert 
845796c8dcSSimon Schubert static int
null_file_isatty(struct ui_file * file)855796c8dcSSimon Schubert null_file_isatty (struct ui_file *file)
865796c8dcSSimon Schubert {
875796c8dcSSimon Schubert   return 0;
885796c8dcSSimon Schubert }
895796c8dcSSimon Schubert 
905796c8dcSSimon Schubert static void
null_file_rewind(struct ui_file * file)915796c8dcSSimon Schubert null_file_rewind (struct ui_file *file)
925796c8dcSSimon Schubert {
935796c8dcSSimon Schubert   return;
945796c8dcSSimon Schubert }
955796c8dcSSimon Schubert 
965796c8dcSSimon Schubert static void
null_file_put(struct ui_file * file,ui_file_put_method_ftype * write,void * dest)975796c8dcSSimon Schubert null_file_put (struct ui_file *file,
985796c8dcSSimon Schubert 	       ui_file_put_method_ftype *write,
995796c8dcSSimon Schubert 	       void *dest)
1005796c8dcSSimon Schubert {
1015796c8dcSSimon Schubert   return;
1025796c8dcSSimon Schubert }
1035796c8dcSSimon Schubert 
1045796c8dcSSimon Schubert static void
null_file_flush(struct ui_file * file)1055796c8dcSSimon Schubert null_file_flush (struct ui_file *file)
1065796c8dcSSimon Schubert {
1075796c8dcSSimon Schubert   return;
1085796c8dcSSimon Schubert }
1095796c8dcSSimon Schubert 
1105796c8dcSSimon Schubert static void
null_file_write(struct ui_file * file,const char * buf,long sizeof_buf)1115796c8dcSSimon Schubert null_file_write (struct ui_file *file,
1125796c8dcSSimon Schubert 		 const char *buf,
1135796c8dcSSimon Schubert 		 long sizeof_buf)
1145796c8dcSSimon Schubert {
1155796c8dcSSimon Schubert   if (file->to_fputs == null_file_fputs)
1165796c8dcSSimon Schubert     /* Both the write and fputs methods are null.  Discard the
1175796c8dcSSimon Schubert        request.  */
1185796c8dcSSimon Schubert     return;
1195796c8dcSSimon Schubert   else
1205796c8dcSSimon Schubert     {
1215796c8dcSSimon Schubert       /* The fputs method isn't null, slowly pass the write request
1225796c8dcSSimon Schubert          onto that.  FYI, this isn't as bad as it may look - the
1235796c8dcSSimon Schubert          current (as of 1999-11-07) printf_* function calls fputc and
1245796c8dcSSimon Schubert          fputc does exactly the below.  By having a write function it
1255796c8dcSSimon Schubert          is possible to clean up that code.  */
1265796c8dcSSimon Schubert       int i;
1275796c8dcSSimon Schubert       char b[2];
128cf7f2e2dSJohn Marino 
1295796c8dcSSimon Schubert       b[1] = '\0';
1305796c8dcSSimon Schubert       for (i = 0; i < sizeof_buf; i++)
1315796c8dcSSimon Schubert 	{
1325796c8dcSSimon Schubert 	  b[0] = buf[i];
1335796c8dcSSimon Schubert 	  file->to_fputs (b, file);
1345796c8dcSSimon Schubert 	}
1355796c8dcSSimon Schubert       return;
1365796c8dcSSimon Schubert     }
1375796c8dcSSimon Schubert }
1385796c8dcSSimon Schubert 
1395796c8dcSSimon Schubert static long
null_file_read(struct ui_file * file,char * buf,long sizeof_buf)1405796c8dcSSimon Schubert null_file_read (struct ui_file *file,
1415796c8dcSSimon Schubert 		char *buf,
1425796c8dcSSimon Schubert 		long sizeof_buf)
1435796c8dcSSimon Schubert {
1445796c8dcSSimon Schubert   errno = EBADF;
1455796c8dcSSimon Schubert   return 0;
1465796c8dcSSimon Schubert }
1475796c8dcSSimon Schubert 
1485796c8dcSSimon Schubert static void
null_file_fputs(const char * buf,struct ui_file * file)1495796c8dcSSimon Schubert null_file_fputs (const char *buf, struct ui_file *file)
1505796c8dcSSimon Schubert {
1515796c8dcSSimon Schubert   if (file->to_write == null_file_write)
1525796c8dcSSimon Schubert     /* Both the write and fputs methods are null.  Discard the
1535796c8dcSSimon Schubert        request.  */
1545796c8dcSSimon Schubert     return;
1555796c8dcSSimon Schubert   else
1565796c8dcSSimon Schubert     {
1575796c8dcSSimon Schubert       /* The write method was implemented, use that.  */
1585796c8dcSSimon Schubert       file->to_write (file, buf, strlen (buf));
1595796c8dcSSimon Schubert     }
1605796c8dcSSimon Schubert }
1615796c8dcSSimon Schubert 
1625796c8dcSSimon Schubert static void
null_file_write_async_safe(struct ui_file * file,const char * buf,long sizeof_buf)163a45ae5f8SJohn Marino null_file_write_async_safe (struct ui_file *file,
164a45ae5f8SJohn Marino 			    const char *buf,
165a45ae5f8SJohn Marino 			    long sizeof_buf)
166a45ae5f8SJohn Marino {
167a45ae5f8SJohn Marino   return;
168a45ae5f8SJohn Marino }
169a45ae5f8SJohn Marino 
170a45ae5f8SJohn Marino static void
null_file_delete(struct ui_file * file)1715796c8dcSSimon Schubert null_file_delete (struct ui_file *file)
1725796c8dcSSimon Schubert {
1735796c8dcSSimon Schubert   return;
1745796c8dcSSimon Schubert }
1755796c8dcSSimon Schubert 
176*ef5ccd6cSJohn Marino static int
null_file_fseek(struct ui_file * stream,long offset,int whence)177*ef5ccd6cSJohn Marino null_file_fseek (struct ui_file *stream, long offset, int whence)
178*ef5ccd6cSJohn Marino {
179*ef5ccd6cSJohn Marino   errno = EBADF;
180*ef5ccd6cSJohn Marino 
181*ef5ccd6cSJohn Marino   return -1;
182*ef5ccd6cSJohn Marino }
183*ef5ccd6cSJohn Marino 
1845796c8dcSSimon Schubert void *
ui_file_data(struct ui_file * file)1855796c8dcSSimon Schubert ui_file_data (struct ui_file *file)
1865796c8dcSSimon Schubert {
1875796c8dcSSimon Schubert   if (file->magic != &ui_file_magic)
1885796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
1895796c8dcSSimon Schubert 		    _("ui_file_data: bad magic number"));
1905796c8dcSSimon Schubert   return file->to_data;
1915796c8dcSSimon Schubert }
1925796c8dcSSimon Schubert 
1935796c8dcSSimon Schubert void
gdb_flush(struct ui_file * file)1945796c8dcSSimon Schubert gdb_flush (struct ui_file *file)
1955796c8dcSSimon Schubert {
1965796c8dcSSimon Schubert   file->to_flush (file);
1975796c8dcSSimon Schubert }
1985796c8dcSSimon Schubert 
1995796c8dcSSimon Schubert int
ui_file_isatty(struct ui_file * file)2005796c8dcSSimon Schubert ui_file_isatty (struct ui_file *file)
2015796c8dcSSimon Schubert {
2025796c8dcSSimon Schubert   return file->to_isatty (file);
2035796c8dcSSimon Schubert }
2045796c8dcSSimon Schubert 
2055796c8dcSSimon Schubert void
ui_file_rewind(struct ui_file * file)2065796c8dcSSimon Schubert ui_file_rewind (struct ui_file *file)
2075796c8dcSSimon Schubert {
2085796c8dcSSimon Schubert   file->to_rewind (file);
2095796c8dcSSimon Schubert }
2105796c8dcSSimon Schubert 
2115796c8dcSSimon Schubert void
ui_file_put(struct ui_file * file,ui_file_put_method_ftype * write,void * dest)2125796c8dcSSimon Schubert ui_file_put (struct ui_file *file,
2135796c8dcSSimon Schubert 	      ui_file_put_method_ftype *write,
2145796c8dcSSimon Schubert 	      void *dest)
2155796c8dcSSimon Schubert {
2165796c8dcSSimon Schubert   file->to_put (file, write, dest);
2175796c8dcSSimon Schubert }
2185796c8dcSSimon Schubert 
2195796c8dcSSimon Schubert void
ui_file_write(struct ui_file * file,const char * buf,long length_buf)2205796c8dcSSimon Schubert ui_file_write (struct ui_file *file,
2215796c8dcSSimon Schubert 		const char *buf,
2225796c8dcSSimon Schubert 		long length_buf)
2235796c8dcSSimon Schubert {
2245796c8dcSSimon Schubert   file->to_write (file, buf, length_buf);
2255796c8dcSSimon Schubert }
2265796c8dcSSimon Schubert 
227a45ae5f8SJohn Marino void
ui_file_write_async_safe(struct ui_file * file,const char * buf,long length_buf)228a45ae5f8SJohn Marino ui_file_write_async_safe (struct ui_file *file,
229a45ae5f8SJohn Marino 			  const char *buf,
230a45ae5f8SJohn Marino 			  long length_buf)
231a45ae5f8SJohn Marino {
232a45ae5f8SJohn Marino   file->to_write_async_safe (file, buf, length_buf);
233a45ae5f8SJohn Marino }
234a45ae5f8SJohn Marino 
2355796c8dcSSimon Schubert long
ui_file_read(struct ui_file * file,char * buf,long length_buf)2365796c8dcSSimon Schubert ui_file_read (struct ui_file *file, char *buf, long length_buf)
2375796c8dcSSimon Schubert {
2385796c8dcSSimon Schubert   return file->to_read (file, buf, length_buf);
2395796c8dcSSimon Schubert }
2405796c8dcSSimon Schubert 
241*ef5ccd6cSJohn Marino int
ui_file_fseek(struct ui_file * file,long offset,int whence)242*ef5ccd6cSJohn Marino ui_file_fseek (struct ui_file *file, long offset, int whence)
243*ef5ccd6cSJohn Marino {
244*ef5ccd6cSJohn Marino   return file->to_fseek (file, offset, whence);
245*ef5ccd6cSJohn Marino }
246*ef5ccd6cSJohn Marino 
2475796c8dcSSimon Schubert void
fputs_unfiltered(const char * buf,struct ui_file * file)2485796c8dcSSimon Schubert fputs_unfiltered (const char *buf, struct ui_file *file)
2495796c8dcSSimon Schubert {
2505796c8dcSSimon Schubert   file->to_fputs (buf, file);
2515796c8dcSSimon Schubert }
2525796c8dcSSimon Schubert 
2535796c8dcSSimon Schubert void
set_ui_file_flush(struct ui_file * file,ui_file_flush_ftype * flush_ptr)254*ef5ccd6cSJohn Marino set_ui_file_flush (struct ui_file *file, ui_file_flush_ftype *flush_ptr)
2555796c8dcSSimon Schubert {
256*ef5ccd6cSJohn Marino   file->to_flush = flush_ptr;
2575796c8dcSSimon Schubert }
2585796c8dcSSimon Schubert 
2595796c8dcSSimon Schubert void
set_ui_file_isatty(struct ui_file * file,ui_file_isatty_ftype * isatty_ptr)260*ef5ccd6cSJohn Marino set_ui_file_isatty (struct ui_file *file, ui_file_isatty_ftype *isatty_ptr)
2615796c8dcSSimon Schubert {
262*ef5ccd6cSJohn Marino   file->to_isatty = isatty_ptr;
2635796c8dcSSimon Schubert }
2645796c8dcSSimon Schubert 
2655796c8dcSSimon Schubert void
set_ui_file_rewind(struct ui_file * file,ui_file_rewind_ftype * rewind_ptr)266*ef5ccd6cSJohn Marino set_ui_file_rewind (struct ui_file *file, ui_file_rewind_ftype *rewind_ptr)
2675796c8dcSSimon Schubert {
268*ef5ccd6cSJohn Marino   file->to_rewind = rewind_ptr;
2695796c8dcSSimon Schubert }
2705796c8dcSSimon Schubert 
2715796c8dcSSimon Schubert void
set_ui_file_put(struct ui_file * file,ui_file_put_ftype * put_ptr)272*ef5ccd6cSJohn Marino set_ui_file_put (struct ui_file *file, ui_file_put_ftype *put_ptr)
2735796c8dcSSimon Schubert {
274*ef5ccd6cSJohn Marino   file->to_put = put_ptr;
2755796c8dcSSimon Schubert }
2765796c8dcSSimon Schubert 
2775796c8dcSSimon Schubert void
set_ui_file_write(struct ui_file * file,ui_file_write_ftype * write_ptr)2785796c8dcSSimon Schubert set_ui_file_write (struct ui_file *file,
279*ef5ccd6cSJohn Marino 		    ui_file_write_ftype *write_ptr)
2805796c8dcSSimon Schubert {
281*ef5ccd6cSJohn Marino   file->to_write = write_ptr;
2825796c8dcSSimon Schubert }
2835796c8dcSSimon Schubert 
2845796c8dcSSimon Schubert void
set_ui_file_write_async_safe(struct ui_file * file,ui_file_write_async_safe_ftype * write_async_safe_ptr)285a45ae5f8SJohn Marino set_ui_file_write_async_safe (struct ui_file *file,
286*ef5ccd6cSJohn Marino 			      ui_file_write_async_safe_ftype *write_async_safe_ptr)
287a45ae5f8SJohn Marino {
288*ef5ccd6cSJohn Marino   file->to_write_async_safe = write_async_safe_ptr;
289a45ae5f8SJohn Marino }
290a45ae5f8SJohn Marino 
291a45ae5f8SJohn Marino void
set_ui_file_read(struct ui_file * file,ui_file_read_ftype * read_ptr)292*ef5ccd6cSJohn Marino set_ui_file_read (struct ui_file *file, ui_file_read_ftype *read_ptr)
2935796c8dcSSimon Schubert {
294*ef5ccd6cSJohn Marino   file->to_read = read_ptr;
2955796c8dcSSimon Schubert }
2965796c8dcSSimon Schubert 
2975796c8dcSSimon Schubert void
set_ui_file_fputs(struct ui_file * file,ui_file_fputs_ftype * fputs_ptr)298*ef5ccd6cSJohn Marino set_ui_file_fputs (struct ui_file *file, ui_file_fputs_ftype *fputs_ptr)
2995796c8dcSSimon Schubert {
300*ef5ccd6cSJohn Marino   file->to_fputs = fputs_ptr;
301*ef5ccd6cSJohn Marino }
302*ef5ccd6cSJohn Marino 
303*ef5ccd6cSJohn Marino void
set_ui_file_fseek(struct ui_file * file,ui_file_fseek_ftype * fseek_ptr)304*ef5ccd6cSJohn Marino set_ui_file_fseek (struct ui_file *file, ui_file_fseek_ftype *fseek_ptr)
305*ef5ccd6cSJohn Marino {
306*ef5ccd6cSJohn Marino   file->to_fseek = fseek_ptr;
3075796c8dcSSimon Schubert }
3085796c8dcSSimon Schubert 
3095796c8dcSSimon Schubert void
set_ui_file_data(struct ui_file * file,void * data,ui_file_delete_ftype * delete_ptr)3105796c8dcSSimon Schubert set_ui_file_data (struct ui_file *file, void *data,
311*ef5ccd6cSJohn Marino 		  ui_file_delete_ftype *delete_ptr)
3125796c8dcSSimon Schubert {
3135796c8dcSSimon Schubert   file->to_data = data;
314*ef5ccd6cSJohn Marino   file->to_delete = delete_ptr;
3155796c8dcSSimon Schubert }
3165796c8dcSSimon Schubert 
3175796c8dcSSimon Schubert /* ui_file utility function for converting a ``struct ui_file'' into
318cf7f2e2dSJohn Marino    a memory buffer.  */
3195796c8dcSSimon Schubert 
3205796c8dcSSimon Schubert struct accumulated_ui_file
3215796c8dcSSimon Schubert {
3225796c8dcSSimon Schubert   char *buffer;
3235796c8dcSSimon Schubert   long length;
3245796c8dcSSimon Schubert };
3255796c8dcSSimon Schubert 
3265796c8dcSSimon Schubert static void
do_ui_file_xstrdup(void * context,const char * buffer,long length)3275796c8dcSSimon Schubert do_ui_file_xstrdup (void *context, const char *buffer, long length)
3285796c8dcSSimon Schubert {
3295796c8dcSSimon Schubert   struct accumulated_ui_file *acc = context;
330cf7f2e2dSJohn Marino 
3315796c8dcSSimon Schubert   if (acc->buffer == NULL)
3325796c8dcSSimon Schubert     acc->buffer = xmalloc (length + 1);
3335796c8dcSSimon Schubert   else
3345796c8dcSSimon Schubert     acc->buffer = xrealloc (acc->buffer, acc->length + length + 1);
3355796c8dcSSimon Schubert   memcpy (acc->buffer + acc->length, buffer, length);
3365796c8dcSSimon Schubert   acc->length += length;
3375796c8dcSSimon Schubert   acc->buffer[acc->length] = '\0';
3385796c8dcSSimon Schubert }
3395796c8dcSSimon Schubert 
3405796c8dcSSimon Schubert char *
ui_file_xstrdup(struct ui_file * file,long * length)3415796c8dcSSimon Schubert ui_file_xstrdup (struct ui_file *file, long *length)
3425796c8dcSSimon Schubert {
3435796c8dcSSimon Schubert   struct accumulated_ui_file acc;
344cf7f2e2dSJohn Marino 
3455796c8dcSSimon Schubert   acc.buffer = NULL;
3465796c8dcSSimon Schubert   acc.length = 0;
3475796c8dcSSimon Schubert   ui_file_put (file, do_ui_file_xstrdup, &acc);
3485796c8dcSSimon Schubert   if (acc.buffer == NULL)
3495796c8dcSSimon Schubert     acc.buffer = xstrdup ("");
3505796c8dcSSimon Schubert   if (length != NULL)
3515796c8dcSSimon Schubert     *length = acc.length;
3525796c8dcSSimon Schubert   return acc.buffer;
3535796c8dcSSimon Schubert }
354cf7f2e2dSJohn Marino 
355cf7f2e2dSJohn Marino static void
do_ui_file_obsavestring(void * context,const char * buffer,long length)356cf7f2e2dSJohn Marino do_ui_file_obsavestring (void *context, const char *buffer, long length)
357cf7f2e2dSJohn Marino {
358cf7f2e2dSJohn Marino   struct obstack *obstack = (struct obstack *) context;
359cf7f2e2dSJohn Marino 
360cf7f2e2dSJohn Marino   obstack_grow (obstack, buffer, length);
361cf7f2e2dSJohn Marino }
362cf7f2e2dSJohn Marino 
363cf7f2e2dSJohn Marino char *
ui_file_obsavestring(struct ui_file * file,struct obstack * obstack,long * length)364cf7f2e2dSJohn Marino ui_file_obsavestring (struct ui_file *file, struct obstack *obstack,
365cf7f2e2dSJohn Marino 		      long *length)
366cf7f2e2dSJohn Marino {
367cf7f2e2dSJohn Marino   ui_file_put (file, do_ui_file_obsavestring, obstack);
368cf7f2e2dSJohn Marino   *length = obstack_object_size (obstack);
369cf7f2e2dSJohn Marino   obstack_1grow (obstack, '\0');
370cf7f2e2dSJohn Marino   return obstack_finish (obstack);
371cf7f2e2dSJohn Marino }
3725796c8dcSSimon Schubert 
3735796c8dcSSimon Schubert /* A pure memory based ``struct ui_file'' that can be used an output
3745796c8dcSSimon Schubert    buffer.  The buffers accumulated contents are available via
3755796c8dcSSimon Schubert    ui_file_put().  */
3765796c8dcSSimon Schubert 
3775796c8dcSSimon Schubert struct mem_file
3785796c8dcSSimon Schubert   {
3795796c8dcSSimon Schubert     int *magic;
3805796c8dcSSimon Schubert     char *buffer;
3815796c8dcSSimon Schubert     int sizeof_buffer;
3825796c8dcSSimon Schubert     int length_buffer;
3835796c8dcSSimon Schubert   };
3845796c8dcSSimon Schubert 
3855796c8dcSSimon Schubert static ui_file_rewind_ftype mem_file_rewind;
3865796c8dcSSimon Schubert static ui_file_put_ftype mem_file_put;
3875796c8dcSSimon Schubert static ui_file_write_ftype mem_file_write;
3885796c8dcSSimon Schubert static ui_file_delete_ftype mem_file_delete;
3895796c8dcSSimon Schubert static struct ui_file *mem_file_new (void);
3905796c8dcSSimon Schubert static int mem_file_magic;
3915796c8dcSSimon Schubert 
3925796c8dcSSimon Schubert static struct ui_file *
mem_file_new(void)3935796c8dcSSimon Schubert mem_file_new (void)
3945796c8dcSSimon Schubert {
3955796c8dcSSimon Schubert   struct mem_file *stream = XMALLOC (struct mem_file);
3965796c8dcSSimon Schubert   struct ui_file *file = ui_file_new ();
397cf7f2e2dSJohn Marino 
3985796c8dcSSimon Schubert   set_ui_file_data (file, stream, mem_file_delete);
3995796c8dcSSimon Schubert   set_ui_file_rewind (file, mem_file_rewind);
4005796c8dcSSimon Schubert   set_ui_file_put (file, mem_file_put);
4015796c8dcSSimon Schubert   set_ui_file_write (file, mem_file_write);
4025796c8dcSSimon Schubert   stream->magic = &mem_file_magic;
4035796c8dcSSimon Schubert   stream->buffer = NULL;
4045796c8dcSSimon Schubert   stream->sizeof_buffer = 0;
4055796c8dcSSimon Schubert   stream->length_buffer = 0;
4065796c8dcSSimon Schubert   return file;
4075796c8dcSSimon Schubert }
4085796c8dcSSimon Schubert 
4095796c8dcSSimon Schubert static void
mem_file_delete(struct ui_file * file)4105796c8dcSSimon Schubert mem_file_delete (struct ui_file *file)
4115796c8dcSSimon Schubert {
4125796c8dcSSimon Schubert   struct mem_file *stream = ui_file_data (file);
413cf7f2e2dSJohn Marino 
4145796c8dcSSimon Schubert   if (stream->magic != &mem_file_magic)
4155796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
4165796c8dcSSimon Schubert 		    _("mem_file_delete: bad magic number"));
4175796c8dcSSimon Schubert   if (stream->buffer != NULL)
4185796c8dcSSimon Schubert     xfree (stream->buffer);
4195796c8dcSSimon Schubert   xfree (stream);
4205796c8dcSSimon Schubert }
4215796c8dcSSimon Schubert 
4225796c8dcSSimon Schubert struct ui_file *
mem_fileopen(void)4235796c8dcSSimon Schubert mem_fileopen (void)
4245796c8dcSSimon Schubert {
4255796c8dcSSimon Schubert   return mem_file_new ();
4265796c8dcSSimon Schubert }
4275796c8dcSSimon Schubert 
4285796c8dcSSimon Schubert static void
mem_file_rewind(struct ui_file * file)4295796c8dcSSimon Schubert mem_file_rewind (struct ui_file *file)
4305796c8dcSSimon Schubert {
4315796c8dcSSimon Schubert   struct mem_file *stream = ui_file_data (file);
432cf7f2e2dSJohn Marino 
4335796c8dcSSimon Schubert   if (stream->magic != &mem_file_magic)
4345796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
4355796c8dcSSimon Schubert 		    _("mem_file_rewind: bad magic number"));
4365796c8dcSSimon Schubert   stream->length_buffer = 0;
4375796c8dcSSimon Schubert }
4385796c8dcSSimon Schubert 
4395796c8dcSSimon Schubert static void
mem_file_put(struct ui_file * file,ui_file_put_method_ftype * write,void * dest)4405796c8dcSSimon Schubert mem_file_put (struct ui_file *file,
4415796c8dcSSimon Schubert 	      ui_file_put_method_ftype *write,
4425796c8dcSSimon Schubert 	      void *dest)
4435796c8dcSSimon Schubert {
4445796c8dcSSimon Schubert   struct mem_file *stream = ui_file_data (file);
445cf7f2e2dSJohn Marino 
4465796c8dcSSimon Schubert   if (stream->magic != &mem_file_magic)
4475796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
4485796c8dcSSimon Schubert 		    _("mem_file_put: bad magic number"));
4495796c8dcSSimon Schubert   if (stream->length_buffer > 0)
4505796c8dcSSimon Schubert     write (dest, stream->buffer, stream->length_buffer);
4515796c8dcSSimon Schubert }
4525796c8dcSSimon Schubert 
4535796c8dcSSimon Schubert void
mem_file_write(struct ui_file * file,const char * buffer,long length_buffer)4545796c8dcSSimon Schubert mem_file_write (struct ui_file *file,
4555796c8dcSSimon Schubert 		const char *buffer,
4565796c8dcSSimon Schubert 		long length_buffer)
4575796c8dcSSimon Schubert {
4585796c8dcSSimon Schubert   struct mem_file *stream = ui_file_data (file);
459cf7f2e2dSJohn Marino 
4605796c8dcSSimon Schubert   if (stream->magic != &mem_file_magic)
4615796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
4625796c8dcSSimon Schubert 		    _("mem_file_write: bad magic number"));
4635796c8dcSSimon Schubert   if (stream->buffer == NULL)
4645796c8dcSSimon Schubert     {
4655796c8dcSSimon Schubert       stream->length_buffer = length_buffer;
4665796c8dcSSimon Schubert       stream->sizeof_buffer = length_buffer;
4675796c8dcSSimon Schubert       stream->buffer = xmalloc (stream->sizeof_buffer);
4685796c8dcSSimon Schubert       memcpy (stream->buffer, buffer, length_buffer);
4695796c8dcSSimon Schubert     }
4705796c8dcSSimon Schubert   else
4715796c8dcSSimon Schubert     {
4725796c8dcSSimon Schubert       int new_length = stream->length_buffer + length_buffer;
473cf7f2e2dSJohn Marino 
4745796c8dcSSimon Schubert       if (new_length >= stream->sizeof_buffer)
4755796c8dcSSimon Schubert 	{
4765796c8dcSSimon Schubert 	  stream->sizeof_buffer = new_length;
4775796c8dcSSimon Schubert 	  stream->buffer = xrealloc (stream->buffer, stream->sizeof_buffer);
4785796c8dcSSimon Schubert 	}
4795796c8dcSSimon Schubert       memcpy (stream->buffer + stream->length_buffer, buffer, length_buffer);
4805796c8dcSSimon Schubert       stream->length_buffer = new_length;
4815796c8dcSSimon Schubert     }
4825796c8dcSSimon Schubert }
4835796c8dcSSimon Schubert 
4845796c8dcSSimon Schubert /* ``struct ui_file'' implementation that maps directly onto
4855796c8dcSSimon Schubert    <stdio.h>'s FILE.  */
4865796c8dcSSimon Schubert 
4875796c8dcSSimon Schubert static ui_file_write_ftype stdio_file_write;
488a45ae5f8SJohn Marino static ui_file_write_async_safe_ftype stdio_file_write_async_safe;
4895796c8dcSSimon Schubert static ui_file_fputs_ftype stdio_file_fputs;
4905796c8dcSSimon Schubert static ui_file_read_ftype stdio_file_read;
4915796c8dcSSimon Schubert static ui_file_isatty_ftype stdio_file_isatty;
4925796c8dcSSimon Schubert static ui_file_delete_ftype stdio_file_delete;
4935796c8dcSSimon Schubert static struct ui_file *stdio_file_new (FILE *file, int close_p);
4945796c8dcSSimon Schubert static ui_file_flush_ftype stdio_file_flush;
495*ef5ccd6cSJohn Marino static ui_file_fseek_ftype stdio_file_fseek;
4965796c8dcSSimon Schubert 
4975796c8dcSSimon Schubert static int stdio_file_magic;
4985796c8dcSSimon Schubert 
4995796c8dcSSimon Schubert struct stdio_file
5005796c8dcSSimon Schubert   {
5015796c8dcSSimon Schubert     int *magic;
5025796c8dcSSimon Schubert     FILE *file;
503a45ae5f8SJohn Marino     /* The associated file descriptor is extracted ahead of time for
504a45ae5f8SJohn Marino        stdio_file_write_async_safe's benefit, in case fileno isn't async-safe.  */
505a45ae5f8SJohn Marino     int fd;
5065796c8dcSSimon Schubert     int close_p;
5075796c8dcSSimon Schubert   };
5085796c8dcSSimon Schubert 
5095796c8dcSSimon Schubert static struct ui_file *
stdio_file_new(FILE * file,int close_p)5105796c8dcSSimon Schubert stdio_file_new (FILE *file, int close_p)
5115796c8dcSSimon Schubert {
5125796c8dcSSimon Schubert   struct ui_file *ui_file = ui_file_new ();
5135796c8dcSSimon Schubert   struct stdio_file *stdio = xmalloc (sizeof (struct stdio_file));
514cf7f2e2dSJohn Marino 
5155796c8dcSSimon Schubert   stdio->magic = &stdio_file_magic;
5165796c8dcSSimon Schubert   stdio->file = file;
517a45ae5f8SJohn Marino   stdio->fd = fileno (file);
5185796c8dcSSimon Schubert   stdio->close_p = close_p;
5195796c8dcSSimon Schubert   set_ui_file_data (ui_file, stdio, stdio_file_delete);
5205796c8dcSSimon Schubert   set_ui_file_flush (ui_file, stdio_file_flush);
5215796c8dcSSimon Schubert   set_ui_file_write (ui_file, stdio_file_write);
522a45ae5f8SJohn Marino   set_ui_file_write_async_safe (ui_file, stdio_file_write_async_safe);
5235796c8dcSSimon Schubert   set_ui_file_fputs (ui_file, stdio_file_fputs);
5245796c8dcSSimon Schubert   set_ui_file_read (ui_file, stdio_file_read);
5255796c8dcSSimon Schubert   set_ui_file_isatty (ui_file, stdio_file_isatty);
526*ef5ccd6cSJohn Marino   set_ui_file_fseek (ui_file, stdio_file_fseek);
5275796c8dcSSimon Schubert   return ui_file;
5285796c8dcSSimon Schubert }
5295796c8dcSSimon Schubert 
5305796c8dcSSimon Schubert static void
stdio_file_delete(struct ui_file * file)5315796c8dcSSimon Schubert stdio_file_delete (struct ui_file *file)
5325796c8dcSSimon Schubert {
5335796c8dcSSimon Schubert   struct stdio_file *stdio = ui_file_data (file);
534cf7f2e2dSJohn Marino 
5355796c8dcSSimon Schubert   if (stdio->magic != &stdio_file_magic)
5365796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
5375796c8dcSSimon Schubert 		    _("stdio_file_delete: bad magic number"));
5385796c8dcSSimon Schubert   if (stdio->close_p)
5395796c8dcSSimon Schubert     {
5405796c8dcSSimon Schubert       fclose (stdio->file);
5415796c8dcSSimon Schubert     }
5425796c8dcSSimon Schubert   xfree (stdio);
5435796c8dcSSimon Schubert }
5445796c8dcSSimon Schubert 
5455796c8dcSSimon Schubert static void
stdio_file_flush(struct ui_file * file)5465796c8dcSSimon Schubert stdio_file_flush (struct ui_file *file)
5475796c8dcSSimon Schubert {
5485796c8dcSSimon Schubert   struct stdio_file *stdio = ui_file_data (file);
549cf7f2e2dSJohn Marino 
5505796c8dcSSimon Schubert   if (stdio->magic != &stdio_file_magic)
5515796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
5525796c8dcSSimon Schubert 		    _("stdio_file_flush: bad magic number"));
5535796c8dcSSimon Schubert   fflush (stdio->file);
5545796c8dcSSimon Schubert }
5555796c8dcSSimon Schubert 
5565796c8dcSSimon Schubert static long
stdio_file_read(struct ui_file * file,char * buf,long length_buf)5575796c8dcSSimon Schubert stdio_file_read (struct ui_file *file, char *buf, long length_buf)
5585796c8dcSSimon Schubert {
5595796c8dcSSimon Schubert   struct stdio_file *stdio = ui_file_data (file);
560cf7f2e2dSJohn Marino 
5615796c8dcSSimon Schubert   if (stdio->magic != &stdio_file_magic)
5625796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
5635796c8dcSSimon Schubert 		    _("stdio_file_read: bad magic number"));
564cf7f2e2dSJohn Marino 
565cf7f2e2dSJohn Marino   /* For the benefit of Windows, call gdb_select before reading from
566cf7f2e2dSJohn Marino      the file.  Wait until at least one byte of data is available.
567cf7f2e2dSJohn Marino      Control-C can interrupt gdb_select, but not read.  */
568cf7f2e2dSJohn Marino   {
569cf7f2e2dSJohn Marino     fd_set readfds;
570cf7f2e2dSJohn Marino     FD_ZERO (&readfds);
571a45ae5f8SJohn Marino     FD_SET (stdio->fd, &readfds);
572a45ae5f8SJohn Marino     if (gdb_select (stdio->fd + 1, &readfds, NULL, NULL, NULL) == -1)
573cf7f2e2dSJohn Marino       return -1;
574cf7f2e2dSJohn Marino   }
575cf7f2e2dSJohn Marino 
576a45ae5f8SJohn Marino   return read (stdio->fd, buf, length_buf);
5775796c8dcSSimon Schubert }
5785796c8dcSSimon Schubert 
5795796c8dcSSimon Schubert static void
stdio_file_write(struct ui_file * file,const char * buf,long length_buf)5805796c8dcSSimon Schubert stdio_file_write (struct ui_file *file, const char *buf, long length_buf)
5815796c8dcSSimon Schubert {
5825796c8dcSSimon Schubert   struct stdio_file *stdio = ui_file_data (file);
583cf7f2e2dSJohn Marino 
5845796c8dcSSimon Schubert   if (stdio->magic != &stdio_file_magic)
5855796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
5865796c8dcSSimon Schubert 		    _("stdio_file_write: bad magic number"));
5875796c8dcSSimon Schubert   /* Calling error crashes when we are called from the exception framework.  */
5885796c8dcSSimon Schubert   if (fwrite (buf, length_buf, 1, stdio->file))
589*ef5ccd6cSJohn Marino     {
590*ef5ccd6cSJohn Marino       /* Nothing.  */
591*ef5ccd6cSJohn Marino     }
5925796c8dcSSimon Schubert }
5935796c8dcSSimon Schubert 
5945796c8dcSSimon Schubert static void
stdio_file_write_async_safe(struct ui_file * file,const char * buf,long length_buf)595a45ae5f8SJohn Marino stdio_file_write_async_safe (struct ui_file *file,
596a45ae5f8SJohn Marino 			     const char *buf, long length_buf)
597a45ae5f8SJohn Marino {
598a45ae5f8SJohn Marino   struct stdio_file *stdio = ui_file_data (file);
599a45ae5f8SJohn Marino 
600a45ae5f8SJohn Marino   if (stdio->magic != &stdio_file_magic)
601a45ae5f8SJohn Marino     {
602a45ae5f8SJohn Marino       /* gettext isn't necessarily async safe, so we can't use _("error message") here.
603a45ae5f8SJohn Marino 	 We could extract the correct translation ahead of time, but this is an extremely
604a45ae5f8SJohn Marino 	 rare event, and one of the other stdio_file_* routines will presumably catch
605a45ae5f8SJohn Marino 	 the problem anyway.  For now keep it simple and ignore the error here.  */
606a45ae5f8SJohn Marino       return;
607a45ae5f8SJohn Marino     }
608a45ae5f8SJohn Marino 
609a45ae5f8SJohn Marino   /* This is written the way it is to avoid a warning from gcc about not using the
610a45ae5f8SJohn Marino      result of write (since it can be declared with attribute warn_unused_result).
611a45ae5f8SJohn Marino      Alas casting to void doesn't work for this.  */
612a45ae5f8SJohn Marino   if (write (stdio->fd, buf, length_buf))
613*ef5ccd6cSJohn Marino     {
614*ef5ccd6cSJohn Marino       /* Nothing.  */
615*ef5ccd6cSJohn Marino     }
616a45ae5f8SJohn Marino }
617a45ae5f8SJohn Marino 
618a45ae5f8SJohn Marino static void
stdio_file_fputs(const char * linebuffer,struct ui_file * file)6195796c8dcSSimon Schubert stdio_file_fputs (const char *linebuffer, struct ui_file *file)
6205796c8dcSSimon Schubert {
6215796c8dcSSimon Schubert   struct stdio_file *stdio = ui_file_data (file);
622cf7f2e2dSJohn Marino 
6235796c8dcSSimon Schubert   if (stdio->magic != &stdio_file_magic)
6245796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
6255796c8dcSSimon Schubert 		    _("stdio_file_fputs: bad magic number"));
6265796c8dcSSimon Schubert   /* Calling error crashes when we are called from the exception framework.  */
6275796c8dcSSimon Schubert   if (fputs (linebuffer, stdio->file))
628*ef5ccd6cSJohn Marino     {
629*ef5ccd6cSJohn Marino       /* Nothing.  */
630*ef5ccd6cSJohn Marino     }
6315796c8dcSSimon Schubert }
6325796c8dcSSimon Schubert 
6335796c8dcSSimon Schubert static int
stdio_file_isatty(struct ui_file * file)6345796c8dcSSimon Schubert stdio_file_isatty (struct ui_file *file)
6355796c8dcSSimon Schubert {
6365796c8dcSSimon Schubert   struct stdio_file *stdio = ui_file_data (file);
637cf7f2e2dSJohn Marino 
6385796c8dcSSimon Schubert   if (stdio->magic != &stdio_file_magic)
6395796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
6405796c8dcSSimon Schubert 		    _("stdio_file_isatty: bad magic number"));
641a45ae5f8SJohn Marino   return (isatty (stdio->fd));
6425796c8dcSSimon Schubert }
6435796c8dcSSimon Schubert 
644*ef5ccd6cSJohn Marino static int
stdio_file_fseek(struct ui_file * file,long offset,int whence)645*ef5ccd6cSJohn Marino stdio_file_fseek (struct ui_file *file, long offset, int whence)
646*ef5ccd6cSJohn Marino {
647*ef5ccd6cSJohn Marino   struct stdio_file *stdio = ui_file_data (file);
648*ef5ccd6cSJohn Marino 
649*ef5ccd6cSJohn Marino   if (stdio->magic != &stdio_file_magic)
650*ef5ccd6cSJohn Marino     internal_error (__FILE__, __LINE__,
651*ef5ccd6cSJohn Marino 		    _("stdio_file_fseek: bad magic number"));
652*ef5ccd6cSJohn Marino 
653*ef5ccd6cSJohn Marino   return fseek (stdio->file, offset, whence);
654*ef5ccd6cSJohn Marino }
655*ef5ccd6cSJohn Marino 
6565796c8dcSSimon Schubert /* Like fdopen().  Create a ui_file from a previously opened FILE.  */
6575796c8dcSSimon Schubert 
6585796c8dcSSimon Schubert struct ui_file *
stdio_fileopen(FILE * file)6595796c8dcSSimon Schubert stdio_fileopen (FILE *file)
6605796c8dcSSimon Schubert {
6615796c8dcSSimon Schubert   return stdio_file_new (file, 0);
6625796c8dcSSimon Schubert }
6635796c8dcSSimon Schubert 
6645796c8dcSSimon Schubert struct ui_file *
gdb_fopen(char * name,char * mode)6655796c8dcSSimon Schubert gdb_fopen (char *name, char *mode)
6665796c8dcSSimon Schubert {
6675796c8dcSSimon Schubert   FILE *f = fopen (name, mode);
668cf7f2e2dSJohn Marino 
6695796c8dcSSimon Schubert   if (f == NULL)
6705796c8dcSSimon Schubert     return NULL;
6715796c8dcSSimon Schubert   return stdio_file_new (f, 1);
6725796c8dcSSimon Schubert }
6735796c8dcSSimon Schubert 
6745796c8dcSSimon Schubert /* ``struct ui_file'' implementation that maps onto two ui-file objects.  */
6755796c8dcSSimon Schubert 
6765796c8dcSSimon Schubert static ui_file_write_ftype tee_file_write;
6775796c8dcSSimon Schubert static ui_file_fputs_ftype tee_file_fputs;
6785796c8dcSSimon Schubert static ui_file_isatty_ftype tee_file_isatty;
6795796c8dcSSimon Schubert static ui_file_delete_ftype tee_file_delete;
6805796c8dcSSimon Schubert static ui_file_flush_ftype tee_file_flush;
6815796c8dcSSimon Schubert 
6825796c8dcSSimon Schubert static int tee_file_magic;
6835796c8dcSSimon Schubert 
6845796c8dcSSimon Schubert struct tee_file
6855796c8dcSSimon Schubert   {
6865796c8dcSSimon Schubert     int *magic;
6875796c8dcSSimon Schubert     struct ui_file *one, *two;
6885796c8dcSSimon Schubert     int close_one, close_two;
6895796c8dcSSimon Schubert   };
6905796c8dcSSimon Schubert 
6915796c8dcSSimon Schubert struct ui_file *
tee_file_new(struct ui_file * one,int close_one,struct ui_file * two,int close_two)6925796c8dcSSimon Schubert tee_file_new (struct ui_file *one, int close_one,
6935796c8dcSSimon Schubert 	      struct ui_file *two, int close_two)
6945796c8dcSSimon Schubert {
6955796c8dcSSimon Schubert   struct ui_file *ui_file = ui_file_new ();
6965796c8dcSSimon Schubert   struct tee_file *tee = xmalloc (sizeof (struct tee_file));
697cf7f2e2dSJohn Marino 
6985796c8dcSSimon Schubert   tee->magic = &tee_file_magic;
6995796c8dcSSimon Schubert   tee->one = one;
7005796c8dcSSimon Schubert   tee->two = two;
7015796c8dcSSimon Schubert   tee->close_one = close_one;
7025796c8dcSSimon Schubert   tee->close_two = close_two;
7035796c8dcSSimon Schubert   set_ui_file_data (ui_file, tee, tee_file_delete);
7045796c8dcSSimon Schubert   set_ui_file_flush (ui_file, tee_file_flush);
7055796c8dcSSimon Schubert   set_ui_file_write (ui_file, tee_file_write);
7065796c8dcSSimon Schubert   set_ui_file_fputs (ui_file, tee_file_fputs);
7075796c8dcSSimon Schubert   set_ui_file_isatty (ui_file, tee_file_isatty);
7085796c8dcSSimon Schubert   return ui_file;
7095796c8dcSSimon Schubert }
7105796c8dcSSimon Schubert 
7115796c8dcSSimon Schubert static void
tee_file_delete(struct ui_file * file)7125796c8dcSSimon Schubert tee_file_delete (struct ui_file *file)
7135796c8dcSSimon Schubert {
7145796c8dcSSimon Schubert   struct tee_file *tee = ui_file_data (file);
715cf7f2e2dSJohn Marino 
7165796c8dcSSimon Schubert   if (tee->magic != &tee_file_magic)
7175796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
7185796c8dcSSimon Schubert 		    _("tee_file_delete: bad magic number"));
7195796c8dcSSimon Schubert   if (tee->close_one)
7205796c8dcSSimon Schubert     ui_file_delete (tee->one);
7215796c8dcSSimon Schubert   if (tee->close_two)
7225796c8dcSSimon Schubert     ui_file_delete (tee->two);
7235796c8dcSSimon Schubert 
7245796c8dcSSimon Schubert   xfree (tee);
7255796c8dcSSimon Schubert }
7265796c8dcSSimon Schubert 
7275796c8dcSSimon Schubert static void
tee_file_flush(struct ui_file * file)7285796c8dcSSimon Schubert tee_file_flush (struct ui_file *file)
7295796c8dcSSimon Schubert {
7305796c8dcSSimon Schubert   struct tee_file *tee = ui_file_data (file);
731cf7f2e2dSJohn Marino 
7325796c8dcSSimon Schubert   if (tee->magic != &tee_file_magic)
7335796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
7345796c8dcSSimon Schubert 		    _("tee_file_flush: bad magic number"));
7355796c8dcSSimon Schubert   tee->one->to_flush (tee->one);
7365796c8dcSSimon Schubert   tee->two->to_flush (tee->two);
7375796c8dcSSimon Schubert }
7385796c8dcSSimon Schubert 
7395796c8dcSSimon Schubert static void
tee_file_write(struct ui_file * file,const char * buf,long length_buf)7405796c8dcSSimon Schubert tee_file_write (struct ui_file *file, const char *buf, long length_buf)
7415796c8dcSSimon Schubert {
7425796c8dcSSimon Schubert   struct tee_file *tee = ui_file_data (file);
743cf7f2e2dSJohn Marino 
7445796c8dcSSimon Schubert   if (tee->magic != &tee_file_magic)
7455796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
7465796c8dcSSimon Schubert 		    _("tee_file_write: bad magic number"));
7475796c8dcSSimon Schubert   ui_file_write (tee->one, buf, length_buf);
7485796c8dcSSimon Schubert   ui_file_write (tee->two, buf, length_buf);
7495796c8dcSSimon Schubert }
7505796c8dcSSimon Schubert 
7515796c8dcSSimon Schubert static void
tee_file_fputs(const char * linebuffer,struct ui_file * file)7525796c8dcSSimon Schubert tee_file_fputs (const char *linebuffer, struct ui_file *file)
7535796c8dcSSimon Schubert {
7545796c8dcSSimon Schubert   struct tee_file *tee = ui_file_data (file);
755cf7f2e2dSJohn Marino 
7565796c8dcSSimon Schubert   if (tee->magic != &tee_file_magic)
7575796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
7585796c8dcSSimon Schubert 		    _("tee_file_fputs: bad magic number"));
7595796c8dcSSimon Schubert   tee->one->to_fputs (linebuffer, tee->one);
7605796c8dcSSimon Schubert   tee->two->to_fputs (linebuffer, tee->two);
7615796c8dcSSimon Schubert }
7625796c8dcSSimon Schubert 
7635796c8dcSSimon Schubert static int
tee_file_isatty(struct ui_file * file)7645796c8dcSSimon Schubert tee_file_isatty (struct ui_file *file)
7655796c8dcSSimon Schubert {
7665796c8dcSSimon Schubert   struct tee_file *tee = ui_file_data (file);
767cf7f2e2dSJohn Marino 
7685796c8dcSSimon Schubert   if (tee->magic != &tee_file_magic)
7695796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
7705796c8dcSSimon Schubert 		    _("tee_file_isatty: bad magic number"));
771cf7f2e2dSJohn Marino 
772cf7f2e2dSJohn Marino   return ui_file_isatty (tee->one);
7735796c8dcSSimon Schubert }
774