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