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