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