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