1*b725ae77Skettenis /* UI_FILE - a generic STDIO like output stream.
2*b725ae77Skettenis
3*b725ae77Skettenis Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4*b725ae77Skettenis
5*b725ae77Skettenis This file is part of GDB.
6*b725ae77Skettenis
7*b725ae77Skettenis This program is free software; you can redistribute it and/or modify
8*b725ae77Skettenis it under the terms of the GNU General Public License as published by
9*b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
10*b725ae77Skettenis (at your option) any later version.
11*b725ae77Skettenis
12*b725ae77Skettenis This program is distributed in the hope that it will be useful,
13*b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
14*b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*b725ae77Skettenis GNU General Public License for more details.
16*b725ae77Skettenis
17*b725ae77Skettenis You should have received a copy of the GNU General Public License
18*b725ae77Skettenis along with this program; if not, write to the Free Software
19*b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
20*b725ae77Skettenis Boston, MA 02111-1307, USA. */
21*b725ae77Skettenis
22*b725ae77Skettenis /* Implement the ``struct ui_file'' object. */
23*b725ae77Skettenis
24*b725ae77Skettenis #include "defs.h"
25*b725ae77Skettenis #include "ui-file.h"
26*b725ae77Skettenis #include "gdb_string.h"
27*b725ae77Skettenis
28*b725ae77Skettenis #include <errno.h>
29*b725ae77Skettenis
30*b725ae77Skettenis static ui_file_isatty_ftype null_file_isatty;
31*b725ae77Skettenis static ui_file_write_ftype null_file_write;
32*b725ae77Skettenis static ui_file_fputs_ftype null_file_fputs;
33*b725ae77Skettenis static ui_file_read_ftype null_file_read;
34*b725ae77Skettenis static ui_file_flush_ftype null_file_flush;
35*b725ae77Skettenis static ui_file_delete_ftype null_file_delete;
36*b725ae77Skettenis static ui_file_rewind_ftype null_file_rewind;
37*b725ae77Skettenis static ui_file_put_ftype null_file_put;
38*b725ae77Skettenis
39*b725ae77Skettenis struct ui_file
40*b725ae77Skettenis {
41*b725ae77Skettenis int *magic;
42*b725ae77Skettenis ui_file_flush_ftype *to_flush;
43*b725ae77Skettenis ui_file_write_ftype *to_write;
44*b725ae77Skettenis ui_file_fputs_ftype *to_fputs;
45*b725ae77Skettenis ui_file_read_ftype *to_read;
46*b725ae77Skettenis ui_file_delete_ftype *to_delete;
47*b725ae77Skettenis ui_file_isatty_ftype *to_isatty;
48*b725ae77Skettenis ui_file_rewind_ftype *to_rewind;
49*b725ae77Skettenis ui_file_put_ftype *to_put;
50*b725ae77Skettenis void *to_data;
51*b725ae77Skettenis };
52*b725ae77Skettenis int ui_file_magic;
53*b725ae77Skettenis
54*b725ae77Skettenis struct ui_file *
ui_file_new(void)55*b725ae77Skettenis ui_file_new (void)
56*b725ae77Skettenis {
57*b725ae77Skettenis struct ui_file *file = xmalloc (sizeof (struct ui_file));
58*b725ae77Skettenis file->magic = &ui_file_magic;
59*b725ae77Skettenis set_ui_file_data (file, NULL, null_file_delete);
60*b725ae77Skettenis set_ui_file_flush (file, null_file_flush);
61*b725ae77Skettenis set_ui_file_write (file, null_file_write);
62*b725ae77Skettenis set_ui_file_fputs (file, null_file_fputs);
63*b725ae77Skettenis set_ui_file_read (file, null_file_read);
64*b725ae77Skettenis set_ui_file_isatty (file, null_file_isatty);
65*b725ae77Skettenis set_ui_file_rewind (file, null_file_rewind);
66*b725ae77Skettenis set_ui_file_put (file, null_file_put);
67*b725ae77Skettenis return file;
68*b725ae77Skettenis }
69*b725ae77Skettenis
70*b725ae77Skettenis void
ui_file_delete(struct ui_file * file)71*b725ae77Skettenis ui_file_delete (struct ui_file *file)
72*b725ae77Skettenis {
73*b725ae77Skettenis file->to_delete (file);
74*b725ae77Skettenis xfree (file);
75*b725ae77Skettenis }
76*b725ae77Skettenis
77*b725ae77Skettenis static int
null_file_isatty(struct ui_file * file)78*b725ae77Skettenis null_file_isatty (struct ui_file *file)
79*b725ae77Skettenis {
80*b725ae77Skettenis return 0;
81*b725ae77Skettenis }
82*b725ae77Skettenis
83*b725ae77Skettenis static void
null_file_rewind(struct ui_file * file)84*b725ae77Skettenis null_file_rewind (struct ui_file *file)
85*b725ae77Skettenis {
86*b725ae77Skettenis return;
87*b725ae77Skettenis }
88*b725ae77Skettenis
89*b725ae77Skettenis static void
null_file_put(struct ui_file * file,ui_file_put_method_ftype * write,void * dest)90*b725ae77Skettenis null_file_put (struct ui_file *file,
91*b725ae77Skettenis ui_file_put_method_ftype *write,
92*b725ae77Skettenis void *dest)
93*b725ae77Skettenis {
94*b725ae77Skettenis return;
95*b725ae77Skettenis }
96*b725ae77Skettenis
97*b725ae77Skettenis static void
null_file_flush(struct ui_file * file)98*b725ae77Skettenis null_file_flush (struct ui_file *file)
99*b725ae77Skettenis {
100*b725ae77Skettenis return;
101*b725ae77Skettenis }
102*b725ae77Skettenis
103*b725ae77Skettenis static void
null_file_write(struct ui_file * file,const char * buf,long sizeof_buf)104*b725ae77Skettenis null_file_write (struct ui_file *file,
105*b725ae77Skettenis const char *buf,
106*b725ae77Skettenis long sizeof_buf)
107*b725ae77Skettenis {
108*b725ae77Skettenis if (file->to_fputs == null_file_fputs)
109*b725ae77Skettenis /* Both the write and fputs methods are null. Discard the
110*b725ae77Skettenis request. */
111*b725ae77Skettenis return;
112*b725ae77Skettenis else
113*b725ae77Skettenis {
114*b725ae77Skettenis /* The fputs method isn't null, slowly pass the write request
115*b725ae77Skettenis onto that. FYI, this isn't as bad as it may look - the
116*b725ae77Skettenis current (as of 1999-11-07) printf_* function calls fputc and
117*b725ae77Skettenis fputc does exactly the below. By having a write function it
118*b725ae77Skettenis is possible to clean up that code. */
119*b725ae77Skettenis int i;
120*b725ae77Skettenis char b[2];
121*b725ae77Skettenis b[1] = '\0';
122*b725ae77Skettenis for (i = 0; i < sizeof_buf; i++)
123*b725ae77Skettenis {
124*b725ae77Skettenis b[0] = buf[i];
125*b725ae77Skettenis file->to_fputs (b, file);
126*b725ae77Skettenis }
127*b725ae77Skettenis return;
128*b725ae77Skettenis }
129*b725ae77Skettenis }
130*b725ae77Skettenis
131*b725ae77Skettenis static long
null_file_read(struct ui_file * file,char * buf,long sizeof_buf)132*b725ae77Skettenis null_file_read (struct ui_file *file,
133*b725ae77Skettenis char *buf,
134*b725ae77Skettenis long sizeof_buf)
135*b725ae77Skettenis {
136*b725ae77Skettenis errno = EBADF;
137*b725ae77Skettenis return 0;
138*b725ae77Skettenis }
139*b725ae77Skettenis
140*b725ae77Skettenis static void
null_file_fputs(const char * buf,struct ui_file * file)141*b725ae77Skettenis null_file_fputs (const char *buf, struct ui_file *file)
142*b725ae77Skettenis {
143*b725ae77Skettenis if (file->to_write == null_file_write)
144*b725ae77Skettenis /* Both the write and fputs methods are null. Discard the
145*b725ae77Skettenis request. */
146*b725ae77Skettenis return;
147*b725ae77Skettenis else
148*b725ae77Skettenis {
149*b725ae77Skettenis /* The write method was implemented, use that. */
150*b725ae77Skettenis file->to_write (file, buf, strlen (buf));
151*b725ae77Skettenis }
152*b725ae77Skettenis }
153*b725ae77Skettenis
154*b725ae77Skettenis static void
null_file_delete(struct ui_file * file)155*b725ae77Skettenis null_file_delete (struct ui_file *file)
156*b725ae77Skettenis {
157*b725ae77Skettenis return;
158*b725ae77Skettenis }
159*b725ae77Skettenis
160*b725ae77Skettenis void *
ui_file_data(struct ui_file * file)161*b725ae77Skettenis ui_file_data (struct ui_file *file)
162*b725ae77Skettenis {
163*b725ae77Skettenis if (file->magic != &ui_file_magic)
164*b725ae77Skettenis internal_error (__FILE__, __LINE__,
165*b725ae77Skettenis "ui_file_data: bad magic number");
166*b725ae77Skettenis return file->to_data;
167*b725ae77Skettenis }
168*b725ae77Skettenis
169*b725ae77Skettenis void
gdb_flush(struct ui_file * file)170*b725ae77Skettenis gdb_flush (struct ui_file *file)
171*b725ae77Skettenis {
172*b725ae77Skettenis file->to_flush (file);
173*b725ae77Skettenis }
174*b725ae77Skettenis
175*b725ae77Skettenis int
ui_file_isatty(struct ui_file * file)176*b725ae77Skettenis ui_file_isatty (struct ui_file *file)
177*b725ae77Skettenis {
178*b725ae77Skettenis return file->to_isatty (file);
179*b725ae77Skettenis }
180*b725ae77Skettenis
181*b725ae77Skettenis void
ui_file_rewind(struct ui_file * file)182*b725ae77Skettenis ui_file_rewind (struct ui_file *file)
183*b725ae77Skettenis {
184*b725ae77Skettenis file->to_rewind (file);
185*b725ae77Skettenis }
186*b725ae77Skettenis
187*b725ae77Skettenis void
ui_file_put(struct ui_file * file,ui_file_put_method_ftype * write,void * dest)188*b725ae77Skettenis ui_file_put (struct ui_file *file,
189*b725ae77Skettenis ui_file_put_method_ftype *write,
190*b725ae77Skettenis void *dest)
191*b725ae77Skettenis {
192*b725ae77Skettenis file->to_put (file, write, dest);
193*b725ae77Skettenis }
194*b725ae77Skettenis
195*b725ae77Skettenis void
ui_file_write(struct ui_file * file,const char * buf,long length_buf)196*b725ae77Skettenis ui_file_write (struct ui_file *file,
197*b725ae77Skettenis const char *buf,
198*b725ae77Skettenis long length_buf)
199*b725ae77Skettenis {
200*b725ae77Skettenis file->to_write (file, buf, length_buf);
201*b725ae77Skettenis }
202*b725ae77Skettenis
203*b725ae77Skettenis long
ui_file_read(struct ui_file * file,char * buf,long length_buf)204*b725ae77Skettenis ui_file_read (struct ui_file *file, char *buf, long length_buf)
205*b725ae77Skettenis {
206*b725ae77Skettenis return file->to_read (file, buf, length_buf);
207*b725ae77Skettenis }
208*b725ae77Skettenis
209*b725ae77Skettenis void
fputs_unfiltered(const char * buf,struct ui_file * file)210*b725ae77Skettenis fputs_unfiltered (const char *buf, struct ui_file *file)
211*b725ae77Skettenis {
212*b725ae77Skettenis file->to_fputs (buf, file);
213*b725ae77Skettenis }
214*b725ae77Skettenis
215*b725ae77Skettenis void
set_ui_file_flush(struct ui_file * file,ui_file_flush_ftype * flush)216*b725ae77Skettenis set_ui_file_flush (struct ui_file *file, ui_file_flush_ftype *flush)
217*b725ae77Skettenis {
218*b725ae77Skettenis file->to_flush = flush;
219*b725ae77Skettenis }
220*b725ae77Skettenis
221*b725ae77Skettenis void
set_ui_file_isatty(struct ui_file * file,ui_file_isatty_ftype * isatty)222*b725ae77Skettenis set_ui_file_isatty (struct ui_file *file, ui_file_isatty_ftype *isatty)
223*b725ae77Skettenis {
224*b725ae77Skettenis file->to_isatty = isatty;
225*b725ae77Skettenis }
226*b725ae77Skettenis
227*b725ae77Skettenis void
set_ui_file_rewind(struct ui_file * file,ui_file_rewind_ftype * rewind)228*b725ae77Skettenis set_ui_file_rewind (struct ui_file *file, ui_file_rewind_ftype *rewind)
229*b725ae77Skettenis {
230*b725ae77Skettenis file->to_rewind = rewind;
231*b725ae77Skettenis }
232*b725ae77Skettenis
233*b725ae77Skettenis void
set_ui_file_put(struct ui_file * file,ui_file_put_ftype * put)234*b725ae77Skettenis set_ui_file_put (struct ui_file *file, ui_file_put_ftype *put)
235*b725ae77Skettenis {
236*b725ae77Skettenis file->to_put = put;
237*b725ae77Skettenis }
238*b725ae77Skettenis
239*b725ae77Skettenis void
set_ui_file_write(struct ui_file * file,ui_file_write_ftype * write)240*b725ae77Skettenis set_ui_file_write (struct ui_file *file,
241*b725ae77Skettenis ui_file_write_ftype *write)
242*b725ae77Skettenis {
243*b725ae77Skettenis file->to_write = write;
244*b725ae77Skettenis }
245*b725ae77Skettenis
246*b725ae77Skettenis void
set_ui_file_read(struct ui_file * file,ui_file_read_ftype * read)247*b725ae77Skettenis set_ui_file_read (struct ui_file *file, ui_file_read_ftype *read)
248*b725ae77Skettenis {
249*b725ae77Skettenis file->to_read = read;
250*b725ae77Skettenis }
251*b725ae77Skettenis
252*b725ae77Skettenis void
set_ui_file_fputs(struct ui_file * file,ui_file_fputs_ftype * fputs)253*b725ae77Skettenis set_ui_file_fputs (struct ui_file *file, ui_file_fputs_ftype *fputs)
254*b725ae77Skettenis {
255*b725ae77Skettenis file->to_fputs = fputs;
256*b725ae77Skettenis }
257*b725ae77Skettenis
258*b725ae77Skettenis void
set_ui_file_data(struct ui_file * file,void * data,ui_file_delete_ftype * delete)259*b725ae77Skettenis set_ui_file_data (struct ui_file *file, void *data,
260*b725ae77Skettenis ui_file_delete_ftype *delete)
261*b725ae77Skettenis {
262*b725ae77Skettenis file->to_data = data;
263*b725ae77Skettenis file->to_delete = delete;
264*b725ae77Skettenis }
265*b725ae77Skettenis
266*b725ae77Skettenis /* ui_file utility function for converting a ``struct ui_file'' into
267*b725ae77Skettenis a memory buffer''. */
268*b725ae77Skettenis
269*b725ae77Skettenis struct accumulated_ui_file
270*b725ae77Skettenis {
271*b725ae77Skettenis char *buffer;
272*b725ae77Skettenis long length;
273*b725ae77Skettenis };
274*b725ae77Skettenis
275*b725ae77Skettenis static void
do_ui_file_xstrdup(void * context,const char * buffer,long length)276*b725ae77Skettenis do_ui_file_xstrdup (void *context, const char *buffer, long length)
277*b725ae77Skettenis {
278*b725ae77Skettenis struct accumulated_ui_file *acc = context;
279*b725ae77Skettenis if (acc->buffer == NULL)
280*b725ae77Skettenis acc->buffer = xmalloc (length + 1);
281*b725ae77Skettenis else
282*b725ae77Skettenis acc->buffer = xrealloc (acc->buffer, acc->length + length + 1);
283*b725ae77Skettenis memcpy (acc->buffer + acc->length, buffer, length);
284*b725ae77Skettenis acc->length += length;
285*b725ae77Skettenis acc->buffer[acc->length] = '\0';
286*b725ae77Skettenis }
287*b725ae77Skettenis
288*b725ae77Skettenis char *
ui_file_xstrdup(struct ui_file * file,long * length)289*b725ae77Skettenis ui_file_xstrdup (struct ui_file *file,
290*b725ae77Skettenis long *length)
291*b725ae77Skettenis {
292*b725ae77Skettenis struct accumulated_ui_file acc;
293*b725ae77Skettenis acc.buffer = NULL;
294*b725ae77Skettenis acc.length = 0;
295*b725ae77Skettenis ui_file_put (file, do_ui_file_xstrdup, &acc);
296*b725ae77Skettenis if (acc.buffer == NULL)
297*b725ae77Skettenis acc.buffer = xstrdup ("");
298*b725ae77Skettenis *length = acc.length;
299*b725ae77Skettenis return acc.buffer;
300*b725ae77Skettenis }
301*b725ae77Skettenis
302*b725ae77Skettenis /* A pure memory based ``struct ui_file'' that can be used an output
303*b725ae77Skettenis buffer. The buffers accumulated contents are available via
304*b725ae77Skettenis ui_file_put(). */
305*b725ae77Skettenis
306*b725ae77Skettenis struct mem_file
307*b725ae77Skettenis {
308*b725ae77Skettenis int *magic;
309*b725ae77Skettenis char *buffer;
310*b725ae77Skettenis int sizeof_buffer;
311*b725ae77Skettenis int length_buffer;
312*b725ae77Skettenis };
313*b725ae77Skettenis
314*b725ae77Skettenis static ui_file_rewind_ftype mem_file_rewind;
315*b725ae77Skettenis static ui_file_put_ftype mem_file_put;
316*b725ae77Skettenis static ui_file_write_ftype mem_file_write;
317*b725ae77Skettenis static ui_file_delete_ftype mem_file_delete;
318*b725ae77Skettenis static struct ui_file *mem_file_new (void);
319*b725ae77Skettenis static int mem_file_magic;
320*b725ae77Skettenis
321*b725ae77Skettenis static struct ui_file *
mem_file_new(void)322*b725ae77Skettenis mem_file_new (void)
323*b725ae77Skettenis {
324*b725ae77Skettenis struct mem_file *stream = XMALLOC (struct mem_file);
325*b725ae77Skettenis struct ui_file *file = ui_file_new ();
326*b725ae77Skettenis set_ui_file_data (file, stream, mem_file_delete);
327*b725ae77Skettenis set_ui_file_rewind (file, mem_file_rewind);
328*b725ae77Skettenis set_ui_file_put (file, mem_file_put);
329*b725ae77Skettenis set_ui_file_write (file, mem_file_write);
330*b725ae77Skettenis stream->magic = &mem_file_magic;
331*b725ae77Skettenis stream->buffer = NULL;
332*b725ae77Skettenis stream->sizeof_buffer = 0;
333*b725ae77Skettenis stream->length_buffer = 0;
334*b725ae77Skettenis return file;
335*b725ae77Skettenis }
336*b725ae77Skettenis
337*b725ae77Skettenis static void
mem_file_delete(struct ui_file * file)338*b725ae77Skettenis mem_file_delete (struct ui_file *file)
339*b725ae77Skettenis {
340*b725ae77Skettenis struct mem_file *stream = ui_file_data (file);
341*b725ae77Skettenis if (stream->magic != &mem_file_magic)
342*b725ae77Skettenis internal_error (__FILE__, __LINE__,
343*b725ae77Skettenis "mem_file_delete: bad magic number");
344*b725ae77Skettenis if (stream->buffer != NULL)
345*b725ae77Skettenis xfree (stream->buffer);
346*b725ae77Skettenis xfree (stream);
347*b725ae77Skettenis }
348*b725ae77Skettenis
349*b725ae77Skettenis struct ui_file *
mem_fileopen(void)350*b725ae77Skettenis mem_fileopen (void)
351*b725ae77Skettenis {
352*b725ae77Skettenis return mem_file_new ();
353*b725ae77Skettenis }
354*b725ae77Skettenis
355*b725ae77Skettenis static void
mem_file_rewind(struct ui_file * file)356*b725ae77Skettenis mem_file_rewind (struct ui_file *file)
357*b725ae77Skettenis {
358*b725ae77Skettenis struct mem_file *stream = ui_file_data (file);
359*b725ae77Skettenis if (stream->magic != &mem_file_magic)
360*b725ae77Skettenis internal_error (__FILE__, __LINE__,
361*b725ae77Skettenis "mem_file_rewind: bad magic number");
362*b725ae77Skettenis stream->length_buffer = 0;
363*b725ae77Skettenis }
364*b725ae77Skettenis
365*b725ae77Skettenis static void
mem_file_put(struct ui_file * file,ui_file_put_method_ftype * write,void * dest)366*b725ae77Skettenis mem_file_put (struct ui_file *file,
367*b725ae77Skettenis ui_file_put_method_ftype *write,
368*b725ae77Skettenis void *dest)
369*b725ae77Skettenis {
370*b725ae77Skettenis struct mem_file *stream = ui_file_data (file);
371*b725ae77Skettenis if (stream->magic != &mem_file_magic)
372*b725ae77Skettenis internal_error (__FILE__, __LINE__,
373*b725ae77Skettenis "mem_file_put: bad magic number");
374*b725ae77Skettenis if (stream->length_buffer > 0)
375*b725ae77Skettenis write (dest, stream->buffer, stream->length_buffer);
376*b725ae77Skettenis }
377*b725ae77Skettenis
378*b725ae77Skettenis void
mem_file_write(struct ui_file * file,const char * buffer,long length_buffer)379*b725ae77Skettenis mem_file_write (struct ui_file *file,
380*b725ae77Skettenis const char *buffer,
381*b725ae77Skettenis long length_buffer)
382*b725ae77Skettenis {
383*b725ae77Skettenis struct mem_file *stream = ui_file_data (file);
384*b725ae77Skettenis if (stream->magic != &mem_file_magic)
385*b725ae77Skettenis internal_error (__FILE__, __LINE__,
386*b725ae77Skettenis "mem_file_write: bad magic number");
387*b725ae77Skettenis if (stream->buffer == NULL)
388*b725ae77Skettenis {
389*b725ae77Skettenis stream->length_buffer = length_buffer;
390*b725ae77Skettenis stream->sizeof_buffer = length_buffer;
391*b725ae77Skettenis stream->buffer = xmalloc (stream->sizeof_buffer);
392*b725ae77Skettenis memcpy (stream->buffer, buffer, length_buffer);
393*b725ae77Skettenis }
394*b725ae77Skettenis else
395*b725ae77Skettenis {
396*b725ae77Skettenis int new_length = stream->length_buffer + length_buffer;
397*b725ae77Skettenis if (new_length >= stream->sizeof_buffer)
398*b725ae77Skettenis {
399*b725ae77Skettenis stream->sizeof_buffer = new_length;
400*b725ae77Skettenis stream->buffer = xrealloc (stream->buffer, stream->sizeof_buffer);
401*b725ae77Skettenis }
402*b725ae77Skettenis memcpy (stream->buffer + stream->length_buffer, buffer, length_buffer);
403*b725ae77Skettenis stream->length_buffer = new_length;
404*b725ae77Skettenis }
405*b725ae77Skettenis }
406*b725ae77Skettenis
407*b725ae77Skettenis /* ``struct ui_file'' implementation that maps directly onto
408*b725ae77Skettenis <stdio.h>'s FILE. */
409*b725ae77Skettenis
410*b725ae77Skettenis static ui_file_write_ftype stdio_file_write;
411*b725ae77Skettenis static ui_file_fputs_ftype stdio_file_fputs;
412*b725ae77Skettenis static ui_file_read_ftype stdio_file_read;
413*b725ae77Skettenis static ui_file_isatty_ftype stdio_file_isatty;
414*b725ae77Skettenis static ui_file_delete_ftype stdio_file_delete;
415*b725ae77Skettenis static struct ui_file *stdio_file_new (FILE * file, int close_p);
416*b725ae77Skettenis static ui_file_flush_ftype stdio_file_flush;
417*b725ae77Skettenis
418*b725ae77Skettenis static int stdio_file_magic;
419*b725ae77Skettenis
420*b725ae77Skettenis struct stdio_file
421*b725ae77Skettenis {
422*b725ae77Skettenis int *magic;
423*b725ae77Skettenis FILE *file;
424*b725ae77Skettenis int close_p;
425*b725ae77Skettenis };
426*b725ae77Skettenis
427*b725ae77Skettenis static struct ui_file *
stdio_file_new(FILE * file,int close_p)428*b725ae77Skettenis stdio_file_new (FILE *file, int close_p)
429*b725ae77Skettenis {
430*b725ae77Skettenis struct ui_file *ui_file = ui_file_new ();
431*b725ae77Skettenis struct stdio_file *stdio = xmalloc (sizeof (struct stdio_file));
432*b725ae77Skettenis stdio->magic = &stdio_file_magic;
433*b725ae77Skettenis stdio->file = file;
434*b725ae77Skettenis stdio->close_p = close_p;
435*b725ae77Skettenis set_ui_file_data (ui_file, stdio, stdio_file_delete);
436*b725ae77Skettenis set_ui_file_flush (ui_file, stdio_file_flush);
437*b725ae77Skettenis set_ui_file_write (ui_file, stdio_file_write);
438*b725ae77Skettenis set_ui_file_fputs (ui_file, stdio_file_fputs);
439*b725ae77Skettenis set_ui_file_read (ui_file, stdio_file_read);
440*b725ae77Skettenis set_ui_file_isatty (ui_file, stdio_file_isatty);
441*b725ae77Skettenis return ui_file;
442*b725ae77Skettenis }
443*b725ae77Skettenis
444*b725ae77Skettenis static void
stdio_file_delete(struct ui_file * file)445*b725ae77Skettenis stdio_file_delete (struct ui_file *file)
446*b725ae77Skettenis {
447*b725ae77Skettenis struct stdio_file *stdio = ui_file_data (file);
448*b725ae77Skettenis if (stdio->magic != &stdio_file_magic)
449*b725ae77Skettenis internal_error (__FILE__, __LINE__,
450*b725ae77Skettenis "stdio_file_delete: bad magic number");
451*b725ae77Skettenis if (stdio->close_p)
452*b725ae77Skettenis {
453*b725ae77Skettenis fclose (stdio->file);
454*b725ae77Skettenis }
455*b725ae77Skettenis xfree (stdio);
456*b725ae77Skettenis }
457*b725ae77Skettenis
458*b725ae77Skettenis static void
stdio_file_flush(struct ui_file * file)459*b725ae77Skettenis stdio_file_flush (struct ui_file *file)
460*b725ae77Skettenis {
461*b725ae77Skettenis struct stdio_file *stdio = ui_file_data (file);
462*b725ae77Skettenis if (stdio->magic != &stdio_file_magic)
463*b725ae77Skettenis internal_error (__FILE__, __LINE__,
464*b725ae77Skettenis "stdio_file_flush: bad magic number");
465*b725ae77Skettenis fflush (stdio->file);
466*b725ae77Skettenis }
467*b725ae77Skettenis
468*b725ae77Skettenis static long
stdio_file_read(struct ui_file * file,char * buf,long length_buf)469*b725ae77Skettenis stdio_file_read (struct ui_file *file, char *buf, long length_buf)
470*b725ae77Skettenis {
471*b725ae77Skettenis struct stdio_file *stdio = ui_file_data (file);
472*b725ae77Skettenis if (stdio->magic != &stdio_file_magic)
473*b725ae77Skettenis internal_error (__FILE__, __LINE__,
474*b725ae77Skettenis "stdio_file_read: bad magic number");
475*b725ae77Skettenis return read (fileno (stdio->file), buf, length_buf);
476*b725ae77Skettenis }
477*b725ae77Skettenis
478*b725ae77Skettenis static void
stdio_file_write(struct ui_file * file,const char * buf,long length_buf)479*b725ae77Skettenis stdio_file_write (struct ui_file *file, const char *buf, long length_buf)
480*b725ae77Skettenis {
481*b725ae77Skettenis struct stdio_file *stdio = ui_file_data (file);
482*b725ae77Skettenis if (stdio->magic != &stdio_file_magic)
483*b725ae77Skettenis internal_error (__FILE__, __LINE__,
484*b725ae77Skettenis "stdio_file_write: bad magic number");
485*b725ae77Skettenis fwrite (buf, length_buf, 1, stdio->file);
486*b725ae77Skettenis }
487*b725ae77Skettenis
488*b725ae77Skettenis static void
stdio_file_fputs(const char * linebuffer,struct ui_file * file)489*b725ae77Skettenis stdio_file_fputs (const char *linebuffer, struct ui_file *file)
490*b725ae77Skettenis {
491*b725ae77Skettenis struct stdio_file *stdio = ui_file_data (file);
492*b725ae77Skettenis if (stdio->magic != &stdio_file_magic)
493*b725ae77Skettenis internal_error (__FILE__, __LINE__,
494*b725ae77Skettenis "stdio_file_fputs: bad magic number");
495*b725ae77Skettenis fputs (linebuffer, stdio->file);
496*b725ae77Skettenis }
497*b725ae77Skettenis
498*b725ae77Skettenis static int
stdio_file_isatty(struct ui_file * file)499*b725ae77Skettenis stdio_file_isatty (struct ui_file *file)
500*b725ae77Skettenis {
501*b725ae77Skettenis struct stdio_file *stdio = ui_file_data (file);
502*b725ae77Skettenis if (stdio->magic != &stdio_file_magic)
503*b725ae77Skettenis internal_error (__FILE__, __LINE__,
504*b725ae77Skettenis "stdio_file_isatty: bad magic number");
505*b725ae77Skettenis return (isatty (fileno (stdio->file)));
506*b725ae77Skettenis }
507*b725ae77Skettenis
508*b725ae77Skettenis /* Like fdopen(). Create a ui_file from a previously opened FILE. */
509*b725ae77Skettenis
510*b725ae77Skettenis struct ui_file *
stdio_fileopen(FILE * file)511*b725ae77Skettenis stdio_fileopen (FILE *file)
512*b725ae77Skettenis {
513*b725ae77Skettenis return stdio_file_new (file, 0);
514*b725ae77Skettenis }
515*b725ae77Skettenis
516*b725ae77Skettenis struct ui_file *
gdb_fopen(char * name,char * mode)517*b725ae77Skettenis gdb_fopen (char *name, char *mode)
518*b725ae77Skettenis {
519*b725ae77Skettenis FILE *f = fopen (name, mode);
520*b725ae77Skettenis if (f == NULL)
521*b725ae77Skettenis return NULL;
522*b725ae77Skettenis return stdio_file_new (f, 1);
523*b725ae77Skettenis }
524*b725ae77Skettenis
525*b725ae77Skettenis /* ``struct ui_file'' implementation that maps onto two ui-file objects. */
526*b725ae77Skettenis
527*b725ae77Skettenis static ui_file_write_ftype tee_file_write;
528*b725ae77Skettenis static ui_file_fputs_ftype tee_file_fputs;
529*b725ae77Skettenis static ui_file_isatty_ftype tee_file_isatty;
530*b725ae77Skettenis static ui_file_delete_ftype tee_file_delete;
531*b725ae77Skettenis static ui_file_flush_ftype tee_file_flush;
532*b725ae77Skettenis
533*b725ae77Skettenis static int tee_file_magic;
534*b725ae77Skettenis
535*b725ae77Skettenis struct tee_file
536*b725ae77Skettenis {
537*b725ae77Skettenis int *magic;
538*b725ae77Skettenis struct ui_file *one, *two;
539*b725ae77Skettenis int close_one, close_two;
540*b725ae77Skettenis };
541*b725ae77Skettenis
542*b725ae77Skettenis struct ui_file *
tee_file_new(struct ui_file * one,int close_one,struct ui_file * two,int close_two)543*b725ae77Skettenis tee_file_new (struct ui_file *one, int close_one,
544*b725ae77Skettenis struct ui_file *two, int close_two)
545*b725ae77Skettenis {
546*b725ae77Skettenis struct ui_file *ui_file = ui_file_new ();
547*b725ae77Skettenis struct tee_file *tee = xmalloc (sizeof (struct tee_file));
548*b725ae77Skettenis tee->magic = &tee_file_magic;
549*b725ae77Skettenis tee->one = one;
550*b725ae77Skettenis tee->two = two;
551*b725ae77Skettenis tee->close_one = close_one;
552*b725ae77Skettenis tee->close_two = close_two;
553*b725ae77Skettenis set_ui_file_data (ui_file, tee, tee_file_delete);
554*b725ae77Skettenis set_ui_file_flush (ui_file, tee_file_flush);
555*b725ae77Skettenis set_ui_file_write (ui_file, tee_file_write);
556*b725ae77Skettenis set_ui_file_fputs (ui_file, tee_file_fputs);
557*b725ae77Skettenis set_ui_file_isatty (ui_file, tee_file_isatty);
558*b725ae77Skettenis return ui_file;
559*b725ae77Skettenis }
560*b725ae77Skettenis
561*b725ae77Skettenis static void
tee_file_delete(struct ui_file * file)562*b725ae77Skettenis tee_file_delete (struct ui_file *file)
563*b725ae77Skettenis {
564*b725ae77Skettenis struct tee_file *tee = ui_file_data (file);
565*b725ae77Skettenis if (tee->magic != &tee_file_magic)
566*b725ae77Skettenis internal_error (__FILE__, __LINE__,
567*b725ae77Skettenis "tee_file_delete: bad magic number");
568*b725ae77Skettenis if (tee->close_one)
569*b725ae77Skettenis ui_file_delete (tee->one);
570*b725ae77Skettenis if (tee->close_two)
571*b725ae77Skettenis ui_file_delete (tee->two);
572*b725ae77Skettenis
573*b725ae77Skettenis xfree (tee);
574*b725ae77Skettenis }
575*b725ae77Skettenis
576*b725ae77Skettenis static void
tee_file_flush(struct ui_file * file)577*b725ae77Skettenis tee_file_flush (struct ui_file *file)
578*b725ae77Skettenis {
579*b725ae77Skettenis struct tee_file *tee = ui_file_data (file);
580*b725ae77Skettenis if (tee->magic != &tee_file_magic)
581*b725ae77Skettenis internal_error (__FILE__, __LINE__,
582*b725ae77Skettenis "tee_file_flush: bad magic number");
583*b725ae77Skettenis tee->one->to_flush (tee->one);
584*b725ae77Skettenis tee->two->to_flush (tee->two);
585*b725ae77Skettenis }
586*b725ae77Skettenis
587*b725ae77Skettenis static void
tee_file_write(struct ui_file * file,const char * buf,long length_buf)588*b725ae77Skettenis tee_file_write (struct ui_file *file, const char *buf, long length_buf)
589*b725ae77Skettenis {
590*b725ae77Skettenis struct tee_file *tee = ui_file_data (file);
591*b725ae77Skettenis if (tee->magic != &tee_file_magic)
592*b725ae77Skettenis internal_error (__FILE__, __LINE__,
593*b725ae77Skettenis "tee_file_write: bad magic number");
594*b725ae77Skettenis ui_file_write (tee->one, buf, length_buf);
595*b725ae77Skettenis ui_file_write (tee->two, buf, length_buf);
596*b725ae77Skettenis }
597*b725ae77Skettenis
598*b725ae77Skettenis static void
tee_file_fputs(const char * linebuffer,struct ui_file * file)599*b725ae77Skettenis tee_file_fputs (const char *linebuffer, struct ui_file *file)
600*b725ae77Skettenis {
601*b725ae77Skettenis struct tee_file *tee = ui_file_data (file);
602*b725ae77Skettenis if (tee->magic != &tee_file_magic)
603*b725ae77Skettenis internal_error (__FILE__, __LINE__,
604*b725ae77Skettenis "tee_file_fputs: bad magic number");
605*b725ae77Skettenis tee->one->to_fputs (linebuffer, tee->one);
606*b725ae77Skettenis tee->two->to_fputs (linebuffer, tee->two);
607*b725ae77Skettenis }
608*b725ae77Skettenis
609*b725ae77Skettenis static int
tee_file_isatty(struct ui_file * file)610*b725ae77Skettenis tee_file_isatty (struct ui_file *file)
611*b725ae77Skettenis {
612*b725ae77Skettenis struct tee_file *tee = ui_file_data (file);
613*b725ae77Skettenis if (tee->magic != &tee_file_magic)
614*b725ae77Skettenis internal_error (__FILE__, __LINE__,
615*b725ae77Skettenis "tee_file_isatty: bad magic number");
616*b725ae77Skettenis return (0);
617*b725ae77Skettenis }
618