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