Switch the license of all .c files to GPLv3.
[deliverable/binutils-gdb.git] / gdb / ui-file.c
1 /* UI_FILE - a generic STDIO like output stream.
2
3 Copyright (C) 1999, 2000, 2001, 2002, 2007 Free Software Foundation, Inc.
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
9 the Free Software Foundation; either version 3 of the License, or
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
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 /* Implement the ``struct ui_file'' object. */
21
22 #include "defs.h"
23 #include "ui-file.h"
24 #include "gdb_string.h"
25
26 #include <errno.h>
27
28 static ui_file_isatty_ftype null_file_isatty;
29 static ui_file_write_ftype null_file_write;
30 static ui_file_fputs_ftype null_file_fputs;
31 static ui_file_read_ftype null_file_read;
32 static ui_file_flush_ftype null_file_flush;
33 static ui_file_delete_ftype null_file_delete;
34 static ui_file_rewind_ftype null_file_rewind;
35 static ui_file_put_ftype null_file_put;
36
37 struct 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;
43 ui_file_read_ftype *to_read;
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 };
50 int ui_file_magic;
51
52 struct ui_file *
53 ui_file_new (void)
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);
61 set_ui_file_read (file, null_file_read);
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
68 void
69 ui_file_delete (struct ui_file *file)
70 {
71 file->to_delete (file);
72 xfree (file);
73 }
74
75 static int
76 null_file_isatty (struct ui_file *file)
77 {
78 return 0;
79 }
80
81 static void
82 null_file_rewind (struct ui_file *file)
83 {
84 return;
85 }
86
87 static void
88 null_file_put (struct ui_file *file,
89 ui_file_put_method_ftype *write,
90 void *dest)
91 {
92 return;
93 }
94
95 static void
96 null_file_flush (struct ui_file *file)
97 {
98 return;
99 }
100
101 static void
102 null_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
129 static long
130 null_file_read (struct ui_file *file,
131 char *buf,
132 long sizeof_buf)
133 {
134 errno = EBADF;
135 return 0;
136 }
137
138 static void
139 null_file_fputs (const char *buf, struct ui_file *file)
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
152 static void
153 null_file_delete (struct ui_file *file)
154 {
155 return;
156 }
157
158 void *
159 ui_file_data (struct ui_file *file)
160 {
161 if (file->magic != &ui_file_magic)
162 internal_error (__FILE__, __LINE__,
163 _("ui_file_data: bad magic number"));
164 return file->to_data;
165 }
166
167 void
168 gdb_flush (struct ui_file *file)
169 {
170 file->to_flush (file);
171 }
172
173 int
174 ui_file_isatty (struct ui_file *file)
175 {
176 return file->to_isatty (file);
177 }
178
179 void
180 ui_file_rewind (struct ui_file *file)
181 {
182 file->to_rewind (file);
183 }
184
185 void
186 ui_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
193 void
194 ui_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
201 long
202 ui_file_read (struct ui_file *file, char *buf, long length_buf)
203 {
204 return file->to_read (file, buf, length_buf);
205 }
206
207 void
208 fputs_unfiltered (const char *buf, struct ui_file *file)
209 {
210 file->to_fputs (buf, file);
211 }
212
213 void
214 set_ui_file_flush (struct ui_file *file, ui_file_flush_ftype *flush)
215 {
216 file->to_flush = flush;
217 }
218
219 void
220 set_ui_file_isatty (struct ui_file *file, ui_file_isatty_ftype *isatty)
221 {
222 file->to_isatty = isatty;
223 }
224
225 void
226 set_ui_file_rewind (struct ui_file *file, ui_file_rewind_ftype *rewind)
227 {
228 file->to_rewind = rewind;
229 }
230
231 void
232 set_ui_file_put (struct ui_file *file, ui_file_put_ftype *put)
233 {
234 file->to_put = put;
235 }
236
237 void
238 set_ui_file_write (struct ui_file *file,
239 ui_file_write_ftype *write)
240 {
241 file->to_write = write;
242 }
243
244 void
245 set_ui_file_read (struct ui_file *file, ui_file_read_ftype *read)
246 {
247 file->to_read = read;
248 }
249
250 void
251 set_ui_file_fputs (struct ui_file *file, ui_file_fputs_ftype *fputs)
252 {
253 file->to_fputs = fputs;
254 }
255
256 void
257 set_ui_file_data (struct ui_file *file, void *data,
258 ui_file_delete_ftype *delete)
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
267 struct accumulated_ui_file
268 {
269 char *buffer;
270 long length;
271 };
272
273 static void
274 do_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
286 char *
287 ui_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
304 struct mem_file
305 {
306 int *magic;
307 char *buffer;
308 int sizeof_buffer;
309 int length_buffer;
310 };
311
312 static ui_file_rewind_ftype mem_file_rewind;
313 static ui_file_put_ftype mem_file_put;
314 static ui_file_write_ftype mem_file_write;
315 static ui_file_delete_ftype mem_file_delete;
316 static struct ui_file *mem_file_new (void);
317 static int mem_file_magic;
318
319 static struct ui_file *
320 mem_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
335 static void
336 mem_file_delete (struct ui_file *file)
337 {
338 struct mem_file *stream = ui_file_data (file);
339 if (stream->magic != &mem_file_magic)
340 internal_error (__FILE__, __LINE__,
341 _("mem_file_delete: bad magic number"));
342 if (stream->buffer != NULL)
343 xfree (stream->buffer);
344 xfree (stream);
345 }
346
347 struct ui_file *
348 mem_fileopen (void)
349 {
350 return mem_file_new ();
351 }
352
353 static void
354 mem_file_rewind (struct ui_file *file)
355 {
356 struct mem_file *stream = ui_file_data (file);
357 if (stream->magic != &mem_file_magic)
358 internal_error (__FILE__, __LINE__,
359 _("mem_file_rewind: bad magic number"));
360 stream->length_buffer = 0;
361 }
362
363 static void
364 mem_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)
370 internal_error (__FILE__, __LINE__,
371 _("mem_file_put: bad magic number"));
372 if (stream->length_buffer > 0)
373 write (dest, stream->buffer, stream->length_buffer);
374 }
375
376 void
377 mem_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)
383 internal_error (__FILE__, __LINE__,
384 _("mem_file_write: bad magic number"));
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
408 static ui_file_write_ftype stdio_file_write;
409 static ui_file_fputs_ftype stdio_file_fputs;
410 static ui_file_read_ftype stdio_file_read;
411 static ui_file_isatty_ftype stdio_file_isatty;
412 static ui_file_delete_ftype stdio_file_delete;
413 static struct ui_file *stdio_file_new (FILE * file, int close_p);
414 static ui_file_flush_ftype stdio_file_flush;
415
416 static int stdio_file_magic;
417
418 struct stdio_file
419 {
420 int *magic;
421 FILE *file;
422 int close_p;
423 };
424
425 static struct ui_file *
426 stdio_file_new (FILE *file, int close_p)
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);
437 set_ui_file_read (ui_file, stdio_file_read);
438 set_ui_file_isatty (ui_file, stdio_file_isatty);
439 return ui_file;
440 }
441
442 static void
443 stdio_file_delete (struct ui_file *file)
444 {
445 struct stdio_file *stdio = ui_file_data (file);
446 if (stdio->magic != &stdio_file_magic)
447 internal_error (__FILE__, __LINE__,
448 _("stdio_file_delete: bad magic number"));
449 if (stdio->close_p)
450 {
451 fclose (stdio->file);
452 }
453 xfree (stdio);
454 }
455
456 static void
457 stdio_file_flush (struct ui_file *file)
458 {
459 struct stdio_file *stdio = ui_file_data (file);
460 if (stdio->magic != &stdio_file_magic)
461 internal_error (__FILE__, __LINE__,
462 _("stdio_file_flush: bad magic number"));
463 fflush (stdio->file);
464 }
465
466 static long
467 stdio_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__,
472 _("stdio_file_read: bad magic number"));
473 return read (fileno (stdio->file), buf, length_buf);
474 }
475
476 static void
477 stdio_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)
481 internal_error (__FILE__, __LINE__,
482 _("stdio_file_write: bad magic number"));
483 fwrite (buf, length_buf, 1, stdio->file);
484 }
485
486 static void
487 stdio_file_fputs (const char *linebuffer, struct ui_file *file)
488 {
489 struct stdio_file *stdio = ui_file_data (file);
490 if (stdio->magic != &stdio_file_magic)
491 internal_error (__FILE__, __LINE__,
492 _("stdio_file_fputs: bad magic number"));
493 fputs (linebuffer, stdio->file);
494 }
495
496 static int
497 stdio_file_isatty (struct ui_file *file)
498 {
499 struct stdio_file *stdio = ui_file_data (file);
500 if (stdio->magic != &stdio_file_magic)
501 internal_error (__FILE__, __LINE__,
502 _("stdio_file_isatty: bad magic number"));
503 return (isatty (fileno (stdio->file)));
504 }
505
506 /* Like fdopen(). Create a ui_file from a previously opened FILE. */
507
508 struct ui_file *
509 stdio_fileopen (FILE *file)
510 {
511 return stdio_file_new (file, 0);
512 }
513
514 struct ui_file *
515 gdb_fopen (char *name, char *mode)
516 {
517 FILE *f = fopen (name, mode);
518 if (f == NULL)
519 return NULL;
520 return stdio_file_new (f, 1);
521 }
522
523 /* ``struct ui_file'' implementation that maps onto two ui-file objects. */
524
525 static ui_file_write_ftype tee_file_write;
526 static ui_file_fputs_ftype tee_file_fputs;
527 static ui_file_isatty_ftype tee_file_isatty;
528 static ui_file_delete_ftype tee_file_delete;
529 static ui_file_flush_ftype tee_file_flush;
530
531 static int tee_file_magic;
532
533 struct tee_file
534 {
535 int *magic;
536 struct ui_file *one, *two;
537 int close_one, close_two;
538 };
539
540 struct ui_file *
541 tee_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
559 static void
560 tee_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__,
565 _("tee_file_delete: bad magic number"));
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
574 static void
575 tee_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__,
580 _("tee_file_flush: bad magic number"));
581 tee->one->to_flush (tee->one);
582 tee->two->to_flush (tee->two);
583 }
584
585 static void
586 tee_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__,
591 _("tee_file_write: bad magic number"));
592 ui_file_write (tee->one, buf, length_buf);
593 ui_file_write (tee->two, buf, length_buf);
594 }
595
596 static void
597 tee_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__,
602 _("tee_file_fputs: bad magic number"));
603 tee->one->to_fputs (linebuffer, tee->one);
604 tee->two->to_fputs (linebuffer, tee->two);
605 }
606
607 static int
608 tee_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__,
613 _("tee_file_isatty: bad magic number"));
614 return (0);
615 }
This page took 0.052429 seconds and 5 git commands to generate.