gdb/
[deliverable/binutils-gdb.git] / gdb / ui-file.c
CommitLineData
d9fcf2fb 1/* UI_FILE - a generic STDIO like output stream.
349c5d5f 2
c5a57081 3 Copyright (C) 1999-2002, 2007-2012 Free Software Foundation, Inc.
d9fcf2fb
JM
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
d9fcf2fb
JM
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
d9fcf2fb 19
581e13c1 20/* Implement the ``struct ui_file'' object. */
d9fcf2fb
JM
21
22#include "defs.h"
23#include "ui-file.h"
94af9270 24#include "gdb_obstack.h"
1d1358b6 25#include "gdb_string.h"
ad960ed2 26#include "gdb_select.h"
d9fcf2fb 27
449092f6
CV
28#include <errno.h>
29
d9fcf2fb
JM
30static ui_file_isatty_ftype null_file_isatty;
31static ui_file_write_ftype null_file_write;
01124a23 32static ui_file_write_ftype null_file_write_async_safe;
d9fcf2fb 33static ui_file_fputs_ftype null_file_fputs;
449092f6 34static ui_file_read_ftype null_file_read;
d9fcf2fb
JM
35static ui_file_flush_ftype null_file_flush;
36static ui_file_delete_ftype null_file_delete;
37static ui_file_rewind_ftype null_file_rewind;
38static ui_file_put_ftype null_file_put;
39
40struct ui_file
41 {
42 int *magic;
43 ui_file_flush_ftype *to_flush;
44 ui_file_write_ftype *to_write;
01124a23 45 ui_file_write_async_safe_ftype *to_write_async_safe;
d9fcf2fb 46 ui_file_fputs_ftype *to_fputs;
449092f6 47 ui_file_read_ftype *to_read;
d9fcf2fb
JM
48 ui_file_delete_ftype *to_delete;
49 ui_file_isatty_ftype *to_isatty;
50 ui_file_rewind_ftype *to_rewind;
51 ui_file_put_ftype *to_put;
52 void *to_data;
53 };
54int ui_file_magic;
55
56struct ui_file *
fba45db2 57ui_file_new (void)
d9fcf2fb
JM
58{
59 struct ui_file *file = xmalloc (sizeof (struct ui_file));
5d502164 60
d9fcf2fb
JM
61 file->magic = &ui_file_magic;
62 set_ui_file_data (file, NULL, null_file_delete);
63 set_ui_file_flush (file, null_file_flush);
64 set_ui_file_write (file, null_file_write);
01124a23 65 set_ui_file_write_async_safe (file, null_file_write_async_safe);
d9fcf2fb 66 set_ui_file_fputs (file, null_file_fputs);
449092f6 67 set_ui_file_read (file, null_file_read);
d9fcf2fb
JM
68 set_ui_file_isatty (file, null_file_isatty);
69 set_ui_file_rewind (file, null_file_rewind);
70 set_ui_file_put (file, null_file_put);
71 return file;
72}
73
74void
fba45db2 75ui_file_delete (struct ui_file *file)
d9fcf2fb
JM
76{
77 file->to_delete (file);
b8c9b27d 78 xfree (file);
d9fcf2fb
JM
79}
80
81static int
fba45db2 82null_file_isatty (struct ui_file *file)
d9fcf2fb
JM
83{
84 return 0;
85}
86
87static void
fba45db2 88null_file_rewind (struct ui_file *file)
d9fcf2fb
JM
89{
90 return;
91}
92
93static void
94null_file_put (struct ui_file *file,
95 ui_file_put_method_ftype *write,
96 void *dest)
97{
98 return;
99}
100
101static void
fba45db2 102null_file_flush (struct ui_file *file)
d9fcf2fb
JM
103{
104 return;
105}
106
107static void
108null_file_write (struct ui_file *file,
109 const char *buf,
110 long sizeof_buf)
111{
112 if (file->to_fputs == null_file_fputs)
581e13c1
MS
113 /* Both the write and fputs methods are null. Discard the
114 request. */
d9fcf2fb
JM
115 return;
116 else
117 {
118 /* The fputs method isn't null, slowly pass the write request
119 onto that. FYI, this isn't as bad as it may look - the
120 current (as of 1999-11-07) printf_* function calls fputc and
121 fputc does exactly the below. By having a write function it
122 is possible to clean up that code. */
123 int i;
124 char b[2];
5d502164 125
d9fcf2fb
JM
126 b[1] = '\0';
127 for (i = 0; i < sizeof_buf; i++)
128 {
129 b[0] = buf[i];
130 file->to_fputs (b, file);
131 }
132 return;
133 }
134}
135
449092f6
CV
136static long
137null_file_read (struct ui_file *file,
138 char *buf,
139 long sizeof_buf)
140{
141 errno = EBADF;
142 return 0;
143}
144
d9fcf2fb 145static void
fba45db2 146null_file_fputs (const char *buf, struct ui_file *file)
d9fcf2fb
JM
147{
148 if (file->to_write == null_file_write)
581e13c1
MS
149 /* Both the write and fputs methods are null. Discard the
150 request. */
d9fcf2fb
JM
151 return;
152 else
153 {
581e13c1 154 /* The write method was implemented, use that. */
d9fcf2fb
JM
155 file->to_write (file, buf, strlen (buf));
156 }
157}
158
01124a23
DE
159static void
160null_file_write_async_safe (struct ui_file *file,
161 const char *buf,
162 long sizeof_buf)
163{
164 return;
165}
166
d9fcf2fb 167static void
fba45db2 168null_file_delete (struct ui_file *file)
d9fcf2fb
JM
169{
170 return;
171}
172
173void *
fba45db2 174ui_file_data (struct ui_file *file)
d9fcf2fb
JM
175{
176 if (file->magic != &ui_file_magic)
8e65ff28 177 internal_error (__FILE__, __LINE__,
e2e0b3e5 178 _("ui_file_data: bad magic number"));
d9fcf2fb
JM
179 return file->to_data;
180}
181
182void
fba45db2 183gdb_flush (struct ui_file *file)
d9fcf2fb
JM
184{
185 file->to_flush (file);
186}
187
188int
fba45db2 189ui_file_isatty (struct ui_file *file)
d9fcf2fb
JM
190{
191 return file->to_isatty (file);
192}
193
194void
fba45db2 195ui_file_rewind (struct ui_file *file)
d9fcf2fb
JM
196{
197 file->to_rewind (file);
198}
199
200void
201ui_file_put (struct ui_file *file,
202 ui_file_put_method_ftype *write,
203 void *dest)
204{
205 file->to_put (file, write, dest);
206}
207
208void
209ui_file_write (struct ui_file *file,
210 const char *buf,
211 long length_buf)
212{
213 file->to_write (file, buf, length_buf);
214}
215
01124a23
DE
216void
217ui_file_write_async_safe (struct ui_file *file,
218 const char *buf,
219 long length_buf)
220{
221 file->to_write_async_safe (file, buf, length_buf);
222}
223
449092f6
CV
224long
225ui_file_read (struct ui_file *file, char *buf, long length_buf)
226{
227 return file->to_read (file, buf, length_buf);
228}
229
d9fcf2fb 230void
fba45db2 231fputs_unfiltered (const char *buf, struct ui_file *file)
d9fcf2fb
JM
232{
233 file->to_fputs (buf, file);
234}
235
236void
fba45db2 237set_ui_file_flush (struct ui_file *file, ui_file_flush_ftype *flush)
d9fcf2fb
JM
238{
239 file->to_flush = flush;
240}
241
242void
fba45db2 243set_ui_file_isatty (struct ui_file *file, ui_file_isatty_ftype *isatty)
d9fcf2fb
JM
244{
245 file->to_isatty = isatty;
246}
247
248void
fba45db2 249set_ui_file_rewind (struct ui_file *file, ui_file_rewind_ftype *rewind)
d9fcf2fb
JM
250{
251 file->to_rewind = rewind;
252}
253
254void
fba45db2 255set_ui_file_put (struct ui_file *file, ui_file_put_ftype *put)
d9fcf2fb
JM
256{
257 file->to_put = put;
258}
259
260void
261set_ui_file_write (struct ui_file *file,
262 ui_file_write_ftype *write)
263{
264 file->to_write = write;
265}
266
01124a23
DE
267void
268set_ui_file_write_async_safe (struct ui_file *file,
269 ui_file_write_async_safe_ftype *write_async_safe)
270{
271 file->to_write_async_safe = write_async_safe;
272}
273
449092f6
CV
274void
275set_ui_file_read (struct ui_file *file, ui_file_read_ftype *read)
276{
277 file->to_read = read;
278}
279
d9fcf2fb 280void
fba45db2 281set_ui_file_fputs (struct ui_file *file, ui_file_fputs_ftype *fputs)
d9fcf2fb
JM
282{
283 file->to_fputs = fputs;
284}
285
286void
fba45db2
KB
287set_ui_file_data (struct ui_file *file, void *data,
288 ui_file_delete_ftype *delete)
d9fcf2fb
JM
289{
290 file->to_data = data;
291 file->to_delete = delete;
292}
293
294/* ui_file utility function for converting a ``struct ui_file'' into
581e13c1 295 a memory buffer. */
d9fcf2fb
JM
296
297struct accumulated_ui_file
298{
299 char *buffer;
300 long length;
301};
302
303static void
304do_ui_file_xstrdup (void *context, const char *buffer, long length)
305{
306 struct accumulated_ui_file *acc = context;
5d502164 307
d9fcf2fb
JM
308 if (acc->buffer == NULL)
309 acc->buffer = xmalloc (length + 1);
310 else
311 acc->buffer = xrealloc (acc->buffer, acc->length + length + 1);
312 memcpy (acc->buffer + acc->length, buffer, length);
313 acc->length += length;
314 acc->buffer[acc->length] = '\0';
315}
316
317char *
759ef836 318ui_file_xstrdup (struct ui_file *file, long *length)
d9fcf2fb
JM
319{
320 struct accumulated_ui_file acc;
5d502164 321
d9fcf2fb
JM
322 acc.buffer = NULL;
323 acc.length = 0;
324 ui_file_put (file, do_ui_file_xstrdup, &acc);
325 if (acc.buffer == NULL)
326 acc.buffer = xstrdup ("");
759ef836
PA
327 if (length != NULL)
328 *length = acc.length;
d9fcf2fb
JM
329 return acc.buffer;
330}
94af9270
KS
331
332static void
333do_ui_file_obsavestring (void *context, const char *buffer, long length)
334{
335 struct obstack *obstack = (struct obstack *) context;
5d502164 336
94af9270
KS
337 obstack_grow (obstack, buffer, length);
338}
339
340char *
341ui_file_obsavestring (struct ui_file *file, struct obstack *obstack,
342 long *length)
343{
344 ui_file_put (file, do_ui_file_obsavestring, obstack);
345 *length = obstack_object_size (obstack);
346 obstack_1grow (obstack, '\0');
347 return obstack_finish (obstack);
348}
d9fcf2fb
JM
349\f
350/* A pure memory based ``struct ui_file'' that can be used an output
581e13c1
MS
351 buffer. The buffers accumulated contents are available via
352 ui_file_put(). */
d9fcf2fb
JM
353
354struct mem_file
355 {
356 int *magic;
357 char *buffer;
358 int sizeof_buffer;
359 int length_buffer;
360 };
361
362static ui_file_rewind_ftype mem_file_rewind;
363static ui_file_put_ftype mem_file_put;
364static ui_file_write_ftype mem_file_write;
365static ui_file_delete_ftype mem_file_delete;
a14ed312 366static struct ui_file *mem_file_new (void);
d9fcf2fb
JM
367static int mem_file_magic;
368
369static struct ui_file *
370mem_file_new (void)
371{
372 struct mem_file *stream = XMALLOC (struct mem_file);
373 struct ui_file *file = ui_file_new ();
5d502164 374
d9fcf2fb
JM
375 set_ui_file_data (file, stream, mem_file_delete);
376 set_ui_file_rewind (file, mem_file_rewind);
377 set_ui_file_put (file, mem_file_put);
378 set_ui_file_write (file, mem_file_write);
379 stream->magic = &mem_file_magic;
380 stream->buffer = NULL;
381 stream->sizeof_buffer = 0;
382 stream->length_buffer = 0;
383 return file;
384}
385
386static void
387mem_file_delete (struct ui_file *file)
388{
389 struct mem_file *stream = ui_file_data (file);
5d502164 390
d9fcf2fb 391 if (stream->magic != &mem_file_magic)
8e65ff28 392 internal_error (__FILE__, __LINE__,
e2e0b3e5 393 _("mem_file_delete: bad magic number"));
d9fcf2fb 394 if (stream->buffer != NULL)
b8c9b27d
KB
395 xfree (stream->buffer);
396 xfree (stream);
d9fcf2fb
JM
397}
398
399struct ui_file *
400mem_fileopen (void)
401{
402 return mem_file_new ();
403}
404
405static void
406mem_file_rewind (struct ui_file *file)
407{
408 struct mem_file *stream = ui_file_data (file);
5d502164 409
d9fcf2fb 410 if (stream->magic != &mem_file_magic)
8e65ff28 411 internal_error (__FILE__, __LINE__,
e2e0b3e5 412 _("mem_file_rewind: bad magic number"));
d9fcf2fb
JM
413 stream->length_buffer = 0;
414}
415
416static void
417mem_file_put (struct ui_file *file,
418 ui_file_put_method_ftype *write,
419 void *dest)
420{
421 struct mem_file *stream = ui_file_data (file);
5d502164 422
d9fcf2fb 423 if (stream->magic != &mem_file_magic)
8e65ff28 424 internal_error (__FILE__, __LINE__,
e2e0b3e5 425 _("mem_file_put: bad magic number"));
d9fcf2fb
JM
426 if (stream->length_buffer > 0)
427 write (dest, stream->buffer, stream->length_buffer);
428}
429
430void
431mem_file_write (struct ui_file *file,
432 const char *buffer,
433 long length_buffer)
434{
435 struct mem_file *stream = ui_file_data (file);
5d502164 436
d9fcf2fb 437 if (stream->magic != &mem_file_magic)
8e65ff28 438 internal_error (__FILE__, __LINE__,
e2e0b3e5 439 _("mem_file_write: bad magic number"));
d9fcf2fb
JM
440 if (stream->buffer == NULL)
441 {
442 stream->length_buffer = length_buffer;
443 stream->sizeof_buffer = length_buffer;
444 stream->buffer = xmalloc (stream->sizeof_buffer);
445 memcpy (stream->buffer, buffer, length_buffer);
446 }
447 else
448 {
449 int new_length = stream->length_buffer + length_buffer;
5d502164 450
d9fcf2fb
JM
451 if (new_length >= stream->sizeof_buffer)
452 {
453 stream->sizeof_buffer = new_length;
454 stream->buffer = xrealloc (stream->buffer, stream->sizeof_buffer);
455 }
456 memcpy (stream->buffer + stream->length_buffer, buffer, length_buffer);
457 stream->length_buffer = new_length;
458 }
459}
460\f
461/* ``struct ui_file'' implementation that maps directly onto
581e13c1 462 <stdio.h>'s FILE. */
d9fcf2fb
JM
463
464static ui_file_write_ftype stdio_file_write;
01124a23 465static ui_file_write_async_safe_ftype stdio_file_write_async_safe;
d9fcf2fb 466static ui_file_fputs_ftype stdio_file_fputs;
449092f6 467static ui_file_read_ftype stdio_file_read;
d9fcf2fb
JM
468static ui_file_isatty_ftype stdio_file_isatty;
469static ui_file_delete_ftype stdio_file_delete;
3e43a32a 470static struct ui_file *stdio_file_new (FILE *file, int close_p);
d9fcf2fb
JM
471static ui_file_flush_ftype stdio_file_flush;
472
473static int stdio_file_magic;
474
475struct stdio_file
476 {
477 int *magic;
478 FILE *file;
01124a23
DE
479 /* The associated file descriptor is extracted ahead of time for
480 stdio_file_write_async_safe's benefit, in case fileno isn't async-safe. */
481 int fd;
d9fcf2fb
JM
482 int close_p;
483 };
484
485static struct ui_file *
fba45db2 486stdio_file_new (FILE *file, int close_p)
d9fcf2fb
JM
487{
488 struct ui_file *ui_file = ui_file_new ();
489 struct stdio_file *stdio = xmalloc (sizeof (struct stdio_file));
5d502164 490
d9fcf2fb
JM
491 stdio->magic = &stdio_file_magic;
492 stdio->file = file;
01124a23 493 stdio->fd = fileno (file);
d9fcf2fb
JM
494 stdio->close_p = close_p;
495 set_ui_file_data (ui_file, stdio, stdio_file_delete);
496 set_ui_file_flush (ui_file, stdio_file_flush);
497 set_ui_file_write (ui_file, stdio_file_write);
01124a23 498 set_ui_file_write_async_safe (ui_file, stdio_file_write_async_safe);
d9fcf2fb 499 set_ui_file_fputs (ui_file, stdio_file_fputs);
449092f6 500 set_ui_file_read (ui_file, stdio_file_read);
d9fcf2fb
JM
501 set_ui_file_isatty (ui_file, stdio_file_isatty);
502 return ui_file;
503}
504
505static void
fba45db2 506stdio_file_delete (struct ui_file *file)
d9fcf2fb
JM
507{
508 struct stdio_file *stdio = ui_file_data (file);
5d502164 509
d9fcf2fb 510 if (stdio->magic != &stdio_file_magic)
8e65ff28 511 internal_error (__FILE__, __LINE__,
e2e0b3e5 512 _("stdio_file_delete: bad magic number"));
d9fcf2fb
JM
513 if (stdio->close_p)
514 {
515 fclose (stdio->file);
516 }
b8c9b27d 517 xfree (stdio);
d9fcf2fb
JM
518}
519
520static void
fba45db2 521stdio_file_flush (struct ui_file *file)
d9fcf2fb
JM
522{
523 struct stdio_file *stdio = ui_file_data (file);
5d502164 524
d9fcf2fb 525 if (stdio->magic != &stdio_file_magic)
8e65ff28 526 internal_error (__FILE__, __LINE__,
e2e0b3e5 527 _("stdio_file_flush: bad magic number"));
d9fcf2fb
JM
528 fflush (stdio->file);
529}
530
449092f6
CV
531static long
532stdio_file_read (struct ui_file *file, char *buf, long length_buf)
533{
534 struct stdio_file *stdio = ui_file_data (file);
5d502164 535
449092f6
CV
536 if (stdio->magic != &stdio_file_magic)
537 internal_error (__FILE__, __LINE__,
e2e0b3e5 538 _("stdio_file_read: bad magic number"));
ad960ed2
DJ
539
540 /* For the benefit of Windows, call gdb_select before reading from
541 the file. Wait until at least one byte of data is available.
542 Control-C can interrupt gdb_select, but not read. */
543 {
ad960ed2
DJ
544 fd_set readfds;
545 FD_ZERO (&readfds);
01124a23
DE
546 FD_SET (stdio->fd, &readfds);
547 if (gdb_select (stdio->fd + 1, &readfds, NULL, NULL, NULL) == -1)
ad960ed2
DJ
548 return -1;
549 }
550
01124a23 551 return read (stdio->fd, buf, length_buf);
449092f6
CV
552}
553
d9fcf2fb
JM
554static void
555stdio_file_write (struct ui_file *file, const char *buf, long length_buf)
556{
557 struct stdio_file *stdio = ui_file_data (file);
5d502164 558
d9fcf2fb 559 if (stdio->magic != &stdio_file_magic)
8e65ff28 560 internal_error (__FILE__, __LINE__,
e2e0b3e5 561 _("stdio_file_write: bad magic number"));
bf1d7d9c
JB
562 /* Calling error crashes when we are called from the exception framework. */
563 if (fwrite (buf, length_buf, 1, stdio->file))
d4fb63e1
TT
564 {
565 /* Nothing. */
566 }
d9fcf2fb
JM
567}
568
01124a23
DE
569static void
570stdio_file_write_async_safe (struct ui_file *file,
571 const char *buf, long length_buf)
572{
573 struct stdio_file *stdio = ui_file_data (file);
574
575 if (stdio->magic != &stdio_file_magic)
576 {
577 /* gettext isn't necessarily async safe, so we can't use _("error message") here.
578 We could extract the correct translation ahead of time, but this is an extremely
579 rare event, and one of the other stdio_file_* routines will presumably catch
580 the problem anyway. For now keep it simple and ignore the error here. */
581 return;
582 }
583
9f7bc587
DE
584 /* This is written the way it is to avoid a warning from gcc about not using the
585 result of write (since it can be declared with attribute warn_unused_result).
586 Alas casting to void doesn't work for this. */
093cee7d 587 if (write (stdio->fd, buf, length_buf))
d4fb63e1
TT
588 {
589 /* Nothing. */
590 }
01124a23
DE
591}
592
d9fcf2fb 593static void
fba45db2 594stdio_file_fputs (const char *linebuffer, struct ui_file *file)
d9fcf2fb
JM
595{
596 struct stdio_file *stdio = ui_file_data (file);
5d502164 597
d9fcf2fb 598 if (stdio->magic != &stdio_file_magic)
8e65ff28 599 internal_error (__FILE__, __LINE__,
e2e0b3e5 600 _("stdio_file_fputs: bad magic number"));
bf1d7d9c
JB
601 /* Calling error crashes when we are called from the exception framework. */
602 if (fputs (linebuffer, stdio->file))
d4fb63e1
TT
603 {
604 /* Nothing. */
605 }
d9fcf2fb
JM
606}
607
608static int
fba45db2 609stdio_file_isatty (struct ui_file *file)
d9fcf2fb
JM
610{
611 struct stdio_file *stdio = ui_file_data (file);
5d502164 612
d9fcf2fb 613 if (stdio->magic != &stdio_file_magic)
8e65ff28 614 internal_error (__FILE__, __LINE__,
e2e0b3e5 615 _("stdio_file_isatty: bad magic number"));
01124a23 616 return (isatty (stdio->fd));
d9fcf2fb
JM
617}
618
581e13c1 619/* Like fdopen(). Create a ui_file from a previously opened FILE. */
d9fcf2fb
JM
620
621struct ui_file *
fba45db2 622stdio_fileopen (FILE *file)
d9fcf2fb
JM
623{
624 return stdio_file_new (file, 0);
625}
626
627struct ui_file *
fba45db2 628gdb_fopen (char *name, char *mode)
d9fcf2fb
JM
629{
630 FILE *f = fopen (name, mode);
5d502164 631
d9fcf2fb
JM
632 if (f == NULL)
633 return NULL;
634 return stdio_file_new (f, 1);
635}
e4c242d9
DJ
636
637/* ``struct ui_file'' implementation that maps onto two ui-file objects. */
638
639static ui_file_write_ftype tee_file_write;
640static ui_file_fputs_ftype tee_file_fputs;
641static ui_file_isatty_ftype tee_file_isatty;
642static ui_file_delete_ftype tee_file_delete;
643static ui_file_flush_ftype tee_file_flush;
644
645static int tee_file_magic;
646
647struct tee_file
648 {
649 int *magic;
650 struct ui_file *one, *two;
651 int close_one, close_two;
652 };
653
654struct ui_file *
655tee_file_new (struct ui_file *one, int close_one,
656 struct ui_file *two, int close_two)
657{
658 struct ui_file *ui_file = ui_file_new ();
659 struct tee_file *tee = xmalloc (sizeof (struct tee_file));
5d502164 660
e4c242d9
DJ
661 tee->magic = &tee_file_magic;
662 tee->one = one;
663 tee->two = two;
664 tee->close_one = close_one;
665 tee->close_two = close_two;
666 set_ui_file_data (ui_file, tee, tee_file_delete);
667 set_ui_file_flush (ui_file, tee_file_flush);
668 set_ui_file_write (ui_file, tee_file_write);
669 set_ui_file_fputs (ui_file, tee_file_fputs);
670 set_ui_file_isatty (ui_file, tee_file_isatty);
671 return ui_file;
672}
673
674static void
675tee_file_delete (struct ui_file *file)
676{
677 struct tee_file *tee = ui_file_data (file);
5d502164 678
e4c242d9
DJ
679 if (tee->magic != &tee_file_magic)
680 internal_error (__FILE__, __LINE__,
e2e0b3e5 681 _("tee_file_delete: bad magic number"));
e4c242d9
DJ
682 if (tee->close_one)
683 ui_file_delete (tee->one);
684 if (tee->close_two)
685 ui_file_delete (tee->two);
686
687 xfree (tee);
688}
689
690static void
691tee_file_flush (struct ui_file *file)
692{
693 struct tee_file *tee = ui_file_data (file);
5d502164 694
e4c242d9
DJ
695 if (tee->magic != &tee_file_magic)
696 internal_error (__FILE__, __LINE__,
e2e0b3e5 697 _("tee_file_flush: bad magic number"));
e4c242d9
DJ
698 tee->one->to_flush (tee->one);
699 tee->two->to_flush (tee->two);
700}
701
702static void
703tee_file_write (struct ui_file *file, const char *buf, long length_buf)
704{
705 struct tee_file *tee = ui_file_data (file);
5d502164 706
e4c242d9
DJ
707 if (tee->magic != &tee_file_magic)
708 internal_error (__FILE__, __LINE__,
e2e0b3e5 709 _("tee_file_write: bad magic number"));
e4c242d9
DJ
710 ui_file_write (tee->one, buf, length_buf);
711 ui_file_write (tee->two, buf, length_buf);
712}
713
714static void
715tee_file_fputs (const char *linebuffer, struct ui_file *file)
716{
717 struct tee_file *tee = ui_file_data (file);
5d502164 718
e4c242d9
DJ
719 if (tee->magic != &tee_file_magic)
720 internal_error (__FILE__, __LINE__,
e2e0b3e5 721 _("tee_file_fputs: bad magic number"));
e4c242d9
DJ
722 tee->one->to_fputs (linebuffer, tee->one);
723 tee->two->to_fputs (linebuffer, tee->two);
724}
725
726static int
727tee_file_isatty (struct ui_file *file)
728{
729 struct tee_file *tee = ui_file_data (file);
5d502164 730
e4c242d9
DJ
731 if (tee->magic != &tee_file_magic)
732 internal_error (__FILE__, __LINE__,
e2e0b3e5 733 _("tee_file_isatty: bad magic number"));
172240dd
PA
734
735 return ui_file_isatty (tee->one);
e4c242d9 736}
This page took 1.371685 seconds and 4 git commands to generate.