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