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