Silence a few -Wmissing-prototypes warnings.
[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"
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"));
bf1d7d9c
JB
484 /* Calling error crashes when we are called from the exception framework. */
485 if (fwrite (buf, length_buf, 1, stdio->file))
486 ;
d9fcf2fb
JM
487}
488
489static void
fba45db2 490stdio_file_fputs (const char *linebuffer, struct ui_file *file)
d9fcf2fb
JM
491{
492 struct stdio_file *stdio = ui_file_data (file);
493 if (stdio->magic != &stdio_file_magic)
8e65ff28 494 internal_error (__FILE__, __LINE__,
e2e0b3e5 495 _("stdio_file_fputs: bad magic number"));
bf1d7d9c
JB
496 /* Calling error crashes when we are called from the exception framework. */
497 if (fputs (linebuffer, stdio->file))
498 ;
d9fcf2fb
JM
499}
500
501static int
fba45db2 502stdio_file_isatty (struct ui_file *file)
d9fcf2fb
JM
503{
504 struct stdio_file *stdio = ui_file_data (file);
505 if (stdio->magic != &stdio_file_magic)
8e65ff28 506 internal_error (__FILE__, __LINE__,
e2e0b3e5 507 _("stdio_file_isatty: bad magic number"));
d9fcf2fb
JM
508 return (isatty (fileno (stdio->file)));
509}
510
511/* Like fdopen(). Create a ui_file from a previously opened FILE. */
512
513struct ui_file *
fba45db2 514stdio_fileopen (FILE *file)
d9fcf2fb
JM
515{
516 return stdio_file_new (file, 0);
517}
518
519struct ui_file *
fba45db2 520gdb_fopen (char *name, char *mode)
d9fcf2fb
JM
521{
522 FILE *f = fopen (name, mode);
523 if (f == NULL)
524 return NULL;
525 return stdio_file_new (f, 1);
526}
e4c242d9
DJ
527
528/* ``struct ui_file'' implementation that maps onto two ui-file objects. */
529
530static ui_file_write_ftype tee_file_write;
531static ui_file_fputs_ftype tee_file_fputs;
532static ui_file_isatty_ftype tee_file_isatty;
533static ui_file_delete_ftype tee_file_delete;
534static ui_file_flush_ftype tee_file_flush;
535
536static int tee_file_magic;
537
538struct tee_file
539 {
540 int *magic;
541 struct ui_file *one, *two;
542 int close_one, close_two;
543 };
544
545struct ui_file *
546tee_file_new (struct ui_file *one, int close_one,
547 struct ui_file *two, int close_two)
548{
549 struct ui_file *ui_file = ui_file_new ();
550 struct tee_file *tee = xmalloc (sizeof (struct tee_file));
551 tee->magic = &tee_file_magic;
552 tee->one = one;
553 tee->two = two;
554 tee->close_one = close_one;
555 tee->close_two = close_two;
556 set_ui_file_data (ui_file, tee, tee_file_delete);
557 set_ui_file_flush (ui_file, tee_file_flush);
558 set_ui_file_write (ui_file, tee_file_write);
559 set_ui_file_fputs (ui_file, tee_file_fputs);
560 set_ui_file_isatty (ui_file, tee_file_isatty);
561 return ui_file;
562}
563
564static void
565tee_file_delete (struct ui_file *file)
566{
567 struct tee_file *tee = ui_file_data (file);
568 if (tee->magic != &tee_file_magic)
569 internal_error (__FILE__, __LINE__,
e2e0b3e5 570 _("tee_file_delete: bad magic number"));
e4c242d9
DJ
571 if (tee->close_one)
572 ui_file_delete (tee->one);
573 if (tee->close_two)
574 ui_file_delete (tee->two);
575
576 xfree (tee);
577}
578
579static void
580tee_file_flush (struct ui_file *file)
581{
582 struct tee_file *tee = ui_file_data (file);
583 if (tee->magic != &tee_file_magic)
584 internal_error (__FILE__, __LINE__,
e2e0b3e5 585 _("tee_file_flush: bad magic number"));
e4c242d9
DJ
586 tee->one->to_flush (tee->one);
587 tee->two->to_flush (tee->two);
588}
589
590static void
591tee_file_write (struct ui_file *file, const char *buf, long length_buf)
592{
593 struct tee_file *tee = ui_file_data (file);
594 if (tee->magic != &tee_file_magic)
595 internal_error (__FILE__, __LINE__,
e2e0b3e5 596 _("tee_file_write: bad magic number"));
e4c242d9
DJ
597 ui_file_write (tee->one, buf, length_buf);
598 ui_file_write (tee->two, buf, length_buf);
599}
600
601static void
602tee_file_fputs (const char *linebuffer, struct ui_file *file)
603{
604 struct tee_file *tee = ui_file_data (file);
605 if (tee->magic != &tee_file_magic)
606 internal_error (__FILE__, __LINE__,
e2e0b3e5 607 _("tee_file_fputs: bad magic number"));
e4c242d9
DJ
608 tee->one->to_fputs (linebuffer, tee->one);
609 tee->two->to_fputs (linebuffer, tee->two);
610}
611
612static int
613tee_file_isatty (struct ui_file *file)
614{
615 struct tee_file *tee = ui_file_data (file);
616 if (tee->magic != &tee_file_magic)
617 internal_error (__FILE__, __LINE__,
e2e0b3e5 618 _("tee_file_isatty: bad magic number"));
e4c242d9
DJ
619 return (0);
620}
This page took 1.477031 seconds and 4 git commands to generate.