OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [ui-file.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* UI_FILE - a generic STDIO like output stream.
2
   Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
3
 
4
   This file is part of GDB.
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 2 of the License, or
9
   (at your option) any later version.
10
 
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 59 Temple Place - Suite 330,
19
   Boston, MA 02111-1307, USA.  */
20
 
21
/* Implement the ``struct ui_file'' object. */
22
 
23
#include "defs.h"
24
#include "ui-file.h"
25
#include "gdb_string.h"
26
 
27
#undef XMALLOC
28
#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
29
 
30
static ui_file_isatty_ftype null_file_isatty;
31
static ui_file_write_ftype null_file_write;
32
static ui_file_fputs_ftype null_file_fputs;
33
static ui_file_flush_ftype null_file_flush;
34
static ui_file_delete_ftype null_file_delete;
35
static ui_file_rewind_ftype null_file_rewind;
36
static ui_file_put_ftype null_file_put;
37
 
38
struct 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;
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_isatty (file, null_file_isatty);
62
  set_ui_file_rewind (file, null_file_rewind);
63
  set_ui_file_put (file, null_file_put);
64
  return file;
65
}
66
 
67
void
68
ui_file_delete (struct ui_file *file)
69
{
70
  file->to_delete (file);
71
  xfree (file);
72
}
73
 
74
static int
75
null_file_isatty (struct ui_file *file)
76
{
77
  return 0;
78
}
79
 
80
static void
81
null_file_rewind (struct ui_file *file)
82
{
83
  return;
84
}
85
 
86
static void
87
null_file_put (struct ui_file *file,
88
               ui_file_put_method_ftype *write,
89
               void *dest)
90
{
91
  return;
92
}
93
 
94
static void
95
null_file_flush (struct ui_file *file)
96
{
97
  return;
98
}
99
 
100
static void
101
null_file_write (struct ui_file *file,
102
                 const char *buf,
103
                 long sizeof_buf)
104
{
105
  if (file->to_fputs == null_file_fputs)
106
    /* Both the write and fputs methods are null. Discard the
107
       request. */
108
    return;
109
  else
110
    {
111
      /* The fputs method isn't null, slowly pass the write request
112
         onto that.  FYI, this isn't as bad as it may look - the
113
         current (as of 1999-11-07) printf_* function calls fputc and
114
         fputc does exactly the below.  By having a write function it
115
         is possible to clean up that code.  */
116
      int i;
117
      char b[2];
118
      b[1] = '\0';
119
      for (i = 0; i < sizeof_buf; i++)
120
        {
121
          b[0] = buf[i];
122
          file->to_fputs (b, file);
123
        }
124
      return;
125
    }
126
}
127
 
128
static void
129
null_file_fputs (const char *buf, struct ui_file *file)
130
{
131
  if (file->to_write == null_file_write)
132
    /* Both the write and fputs methods are null. Discard the
133
       request. */
134
    return;
135
  else
136
    {
137
      /* The write method was implemented, use that. */
138
      file->to_write (file, buf, strlen (buf));
139
    }
140
}
141
 
142
static void
143
null_file_delete (struct ui_file *file)
144
{
145
  return;
146
}
147
 
148
void *
149
ui_file_data (struct ui_file *file)
150
{
151
  if (file->magic != &ui_file_magic)
152
    internal_error (__FILE__, __LINE__,
153
                    "ui_file_data: bad magic number");
154
  return file->to_data;
155
}
156
 
157
void
158
gdb_flush (struct ui_file *file)
159
{
160
  file->to_flush (file);
161
}
162
 
163
int
164
ui_file_isatty (struct ui_file *file)
165
{
166
  return file->to_isatty (file);
167
}
168
 
169
void
170
ui_file_rewind (struct ui_file *file)
171
{
172
  file->to_rewind (file);
173
}
174
 
175
void
176
ui_file_put (struct ui_file *file,
177
              ui_file_put_method_ftype *write,
178
              void *dest)
179
{
180
  file->to_put (file, write, dest);
181
}
182
 
183
void
184
ui_file_write (struct ui_file *file,
185
                const char *buf,
186
                long length_buf)
187
{
188
  file->to_write (file, buf, length_buf);
189
}
190
 
191
void
192
fputs_unfiltered (const char *buf, struct ui_file *file)
193
{
194
  file->to_fputs (buf, file);
195
}
196
 
197
void
198
set_ui_file_flush (struct ui_file *file, ui_file_flush_ftype *flush)
199
{
200
  file->to_flush = flush;
201
}
202
 
203
void
204
set_ui_file_isatty (struct ui_file *file, ui_file_isatty_ftype *isatty)
205
{
206
  file->to_isatty = isatty;
207
}
208
 
209
void
210
set_ui_file_rewind (struct ui_file *file, ui_file_rewind_ftype *rewind)
211
{
212
  file->to_rewind = rewind;
213
}
214
 
215
void
216
set_ui_file_put (struct ui_file *file, ui_file_put_ftype *put)
217
{
218
  file->to_put = put;
219
}
220
 
221
void
222
set_ui_file_write (struct ui_file *file,
223
                    ui_file_write_ftype *write)
224
{
225
  file->to_write = write;
226
}
227
 
228
void
229
set_ui_file_fputs (struct ui_file *file, ui_file_fputs_ftype *fputs)
230
{
231
  file->to_fputs = fputs;
232
}
233
 
234
void
235
set_ui_file_data (struct ui_file *file, void *data,
236
                  ui_file_delete_ftype *delete)
237
{
238
  file->to_data = data;
239
  file->to_delete = delete;
240
}
241
 
242
/* ui_file utility function for converting a ``struct ui_file'' into
243
   a memory buffer''. */
244
 
245
struct accumulated_ui_file
246
{
247
  char *buffer;
248
  long length;
249
};
250
 
251
static void
252
do_ui_file_xstrdup (void *context, const char *buffer, long length)
253
{
254
  struct accumulated_ui_file *acc = context;
255
  if (acc->buffer == NULL)
256
    acc->buffer = xmalloc (length + 1);
257
  else
258
    acc->buffer = xrealloc (acc->buffer, acc->length + length + 1);
259
  memcpy (acc->buffer + acc->length, buffer, length);
260
  acc->length += length;
261
  acc->buffer[acc->length] = '\0';
262
}
263
 
264
char *
265
ui_file_xstrdup (struct ui_file *file,
266
                  long *length)
267
{
268
  struct accumulated_ui_file acc;
269
  acc.buffer = NULL;
270
  acc.length = 0;
271
  ui_file_put (file, do_ui_file_xstrdup, &acc);
272
  if (acc.buffer == NULL)
273
    acc.buffer = xstrdup ("");
274
  *length = acc.length;
275
  return acc.buffer;
276
}
277
 
278
/* A pure memory based ``struct ui_file'' that can be used an output
279
   buffer. The buffers accumulated contents are available via
280
   ui_file_put(). */
281
 
282
struct mem_file
283
  {
284
    int *magic;
285
    char *buffer;
286
    int sizeof_buffer;
287
    int length_buffer;
288
  };
289
 
290
static ui_file_rewind_ftype mem_file_rewind;
291
static ui_file_put_ftype mem_file_put;
292
static ui_file_write_ftype mem_file_write;
293
static ui_file_delete_ftype mem_file_delete;
294
static struct ui_file *mem_file_new (void);
295
static int mem_file_magic;
296
 
297
static struct ui_file *
298
mem_file_new (void)
299
{
300
  struct mem_file *stream = XMALLOC (struct mem_file);
301
  struct ui_file *file = ui_file_new ();
302
  set_ui_file_data (file, stream, mem_file_delete);
303
  set_ui_file_rewind (file, mem_file_rewind);
304
  set_ui_file_put (file, mem_file_put);
305
  set_ui_file_write (file, mem_file_write);
306
  stream->magic = &mem_file_magic;
307
  stream->buffer = NULL;
308
  stream->sizeof_buffer = 0;
309
  stream->length_buffer = 0;
310
  return file;
311
}
312
 
313
static void
314
mem_file_delete (struct ui_file *file)
315
{
316
  struct mem_file *stream = ui_file_data (file);
317
  if (stream->magic != &mem_file_magic)
318
    internal_error (__FILE__, __LINE__,
319
                    "mem_file_delete: bad magic number");
320
  if (stream->buffer != NULL)
321
    xfree (stream->buffer);
322
  xfree (stream);
323
}
324
 
325
struct ui_file *
326
mem_fileopen (void)
327
{
328
  return mem_file_new ();
329
}
330
 
331
static void
332
mem_file_rewind (struct ui_file *file)
333
{
334
  struct mem_file *stream = ui_file_data (file);
335
  if (stream->magic != &mem_file_magic)
336
    internal_error (__FILE__, __LINE__,
337
                    "mem_file_rewind: bad magic number");
338
  stream->length_buffer = 0;
339
}
340
 
341
static void
342
mem_file_put (struct ui_file *file,
343
              ui_file_put_method_ftype *write,
344
              void *dest)
345
{
346
  struct mem_file *stream = ui_file_data (file);
347
  if (stream->magic != &mem_file_magic)
348
    internal_error (__FILE__, __LINE__,
349
                    "mem_file_put: bad magic number");
350
  if (stream->length_buffer > 0)
351
    write (dest, stream->buffer, stream->length_buffer);
352
}
353
 
354
void
355
mem_file_write (struct ui_file *file,
356
                const char *buffer,
357
                long length_buffer)
358
{
359
  struct mem_file *stream = ui_file_data (file);
360
  if (stream->magic != &mem_file_magic)
361
    internal_error (__FILE__, __LINE__,
362
                    "mem_file_write: bad magic number");
363
  if (stream->buffer == NULL)
364
    {
365
      stream->length_buffer = length_buffer;
366
      stream->sizeof_buffer = length_buffer;
367
      stream->buffer = xmalloc (stream->sizeof_buffer);
368
      memcpy (stream->buffer, buffer, length_buffer);
369
    }
370
  else
371
    {
372
      int new_length = stream->length_buffer + length_buffer;
373
      if (new_length >= stream->sizeof_buffer)
374
        {
375
          stream->sizeof_buffer = new_length;
376
          stream->buffer = xrealloc (stream->buffer, stream->sizeof_buffer);
377
        }
378
      memcpy (stream->buffer + stream->length_buffer, buffer, length_buffer);
379
      stream->length_buffer = new_length;
380
    }
381
}
382
 
383
/* ``struct ui_file'' implementation that maps directly onto
384
   <stdio.h>'s FILE. */
385
 
386
static ui_file_write_ftype stdio_file_write;
387
static ui_file_fputs_ftype stdio_file_fputs;
388
static ui_file_isatty_ftype stdio_file_isatty;
389
static ui_file_delete_ftype stdio_file_delete;
390
static struct ui_file *stdio_file_new (FILE * file, int close_p);
391
static ui_file_flush_ftype stdio_file_flush;
392
 
393
static int stdio_file_magic;
394
 
395
struct stdio_file
396
  {
397
    int *magic;
398
    FILE *file;
399
    int close_p;
400
  };
401
 
402
static struct ui_file *
403
stdio_file_new (FILE *file, int close_p)
404
{
405
  struct ui_file *ui_file = ui_file_new ();
406
  struct stdio_file *stdio = xmalloc (sizeof (struct stdio_file));
407
  stdio->magic = &stdio_file_magic;
408
  stdio->file = file;
409
  stdio->close_p = close_p;
410
  set_ui_file_data (ui_file, stdio, stdio_file_delete);
411
  set_ui_file_flush (ui_file, stdio_file_flush);
412
  set_ui_file_write (ui_file, stdio_file_write);
413
  set_ui_file_fputs (ui_file, stdio_file_fputs);
414
  set_ui_file_isatty (ui_file, stdio_file_isatty);
415
  return ui_file;
416
}
417
 
418
static void
419
stdio_file_delete (struct ui_file *file)
420
{
421
  struct stdio_file *stdio = ui_file_data (file);
422
  if (stdio->magic != &stdio_file_magic)
423
    internal_error (__FILE__, __LINE__,
424
                    "stdio_file_delete: bad magic number");
425
  if (stdio->close_p)
426
    {
427
      fclose (stdio->file);
428
    }
429
  xfree (stdio);
430
}
431
 
432
static void
433
stdio_file_flush (struct ui_file *file)
434
{
435
  struct stdio_file *stdio = ui_file_data (file);
436
  if (stdio->magic != &stdio_file_magic)
437
    internal_error (__FILE__, __LINE__,
438
                    "stdio_file_flush: bad magic number");
439
  fflush (stdio->file);
440
}
441
 
442
static void
443
stdio_file_write (struct ui_file *file, const char *buf, long length_buf)
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_write: bad magic number");
449
  fwrite (buf, length_buf, 1, stdio->file);
450
}
451
 
452
static void
453
stdio_file_fputs (const char *linebuffer, struct ui_file *file)
454
{
455
  struct stdio_file *stdio = ui_file_data (file);
456
  if (stdio->magic != &stdio_file_magic)
457
    internal_error (__FILE__, __LINE__,
458
                    "stdio_file_fputs: bad magic number");
459
  fputs (linebuffer, stdio->file);
460
}
461
 
462
static int
463
stdio_file_isatty (struct ui_file *file)
464
{
465
  struct stdio_file *stdio = ui_file_data (file);
466
  if (stdio->magic != &stdio_file_magic)
467
    internal_error (__FILE__, __LINE__,
468
                    "stdio_file_isatty: bad magic number");
469
  return (isatty (fileno (stdio->file)));
470
}
471
 
472
/* Like fdopen().  Create a ui_file from a previously opened FILE. */
473
 
474
struct ui_file *
475
stdio_fileopen (FILE *file)
476
{
477
  return stdio_file_new (file, 0);
478
}
479
 
480
struct ui_file *
481
gdb_fopen (char *name, char *mode)
482
{
483
  FILE *f = fopen (name, mode);
484
  if (f == NULL)
485
    return NULL;
486
  return stdio_file_new (f, 1);
487
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.