summaryrefslogtreecommitdiff
path: root/gdb/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/utils.c')
-rw-r--r--gdb/utils.c346
1 files changed, 305 insertions, 41 deletions
diff --git a/gdb/utils.c b/gdb/utils.c
index 9ccdfed12de..b9b0a9ec36e 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -1536,11 +1536,155 @@ begin_line ()
}
}
-int
-gdb_file_isatty (stream)
- GDB_FILE *stream;
+
+/* ``struct gdb_file'' implementation that maps directly onto
+ <stdio.h>'s FILE. */
+
+static gdb_file_fputs_ftype stdio_file_fputs;
+static gdb_file_isatty_ftype stdio_file_isatty;
+static gdb_file_delete_ftype stdio_file_delete;
+static struct gdb_file *stdio_file_new PARAMS ((FILE *file, int close_p));
+static gdb_file_flush_ftype stdio_file_flush;
+
+static int stdio_file_magic;
+
+struct stdio_file
+{
+ int *magic;
+ FILE *file;
+ int close_p;
+};
+
+static struct gdb_file *
+stdio_file_new (file, close_p)
+ FILE *file;
+ int close_p;
+{
+ struct gdb_file *gdb_file = gdb_file_new ();
+ struct stdio_file *stdio = xmalloc (sizeof (struct stdio_file));
+ stdio->magic = &stdio_file_magic;
+ stdio->file = file;
+ stdio->close_p = close_p;
+ set_gdb_file_data (gdb_file, stdio, stdio_file_delete);
+ set_gdb_file_flush (gdb_file, stdio_file_flush);
+ set_gdb_file_fputs (gdb_file, stdio_file_fputs);
+ set_gdb_file_isatty (gdb_file, stdio_file_isatty);
+ return gdb_file;
+}
+
+static void
+stdio_file_delete (file)
+ struct gdb_file *file;
+{
+ struct stdio_file *stdio = gdb_file_data (file);
+ if (stdio->magic != &stdio_file_magic)
+ error ("Internal error: bad magic number");
+ if (stdio->close_p)
+ {
+ fclose (stdio->file);
+ }
+ free (stdio);
+}
+
+static void
+stdio_file_flush (file)
+ struct gdb_file *file;
{
+ struct stdio_file *stdio = gdb_file_data (file);
+ if (stdio->magic != &stdio_file_magic)
+ error ("Internal error: bad magic number");
+ fflush (stdio->file);
+}
+
+static void
+stdio_file_fputs (linebuffer, file)
+ const char *linebuffer;
+ struct gdb_file *file;
+{
+ struct stdio_file *stdio = gdb_file_data (file);
+ if (stdio->magic != &stdio_file_magic)
+ error ("Internal error: bad magic number");
+ fputs (linebuffer, stdio->file);
+}
+
+static int
+stdio_file_isatty (file)
+ struct gdb_file *file;
+{
+ struct stdio_file *stdio = gdb_file_data (file);
+ if (stdio->magic != &stdio_file_magic)
+ error ("Internal error: bad magic number");
+ return (isatty (fileno (stdio->file)));
+}
+
+/* Like fdopen(). Create a gdb_file from a previously opened FILE. */
+
+struct gdb_file *
+stdio_fileopen (file)
+ FILE *file;
+{
+ return stdio_file_new (file, 0);
+}
+
+
+/* A ``struct gdb_file'' that is compatible with all the legacy
+ code. */
+static gdb_file_flush_ftype tui_file_flush;
+extern gdb_file_fputs_ftype tui_file_fputs;
+static gdb_file_isatty_ftype tui_file_isatty;
+static gdb_file_delete_ftype tui_file_delete;
+static struct gdb_file *tui_file_new PARAMS ((void));
+static int tui_file_magic;
+
+static struct gdb_file *
+tui_file_new ()
+{
+ struct tui_stream *tui = xmalloc (sizeof (struct tui_stream));
+ struct gdb_file *file = gdb_file_new ();
+ set_gdb_file_data (file, tui, tui_file_delete);
+ set_gdb_file_flush (file, tui_file_flush);
+ set_gdb_file_fputs (file, tui_file_fputs);
+ set_gdb_file_isatty (file, tui_file_isatty);
+ tui->ts_magic = &tui_file_magic;
+ return file;
+}
+
+static void
+tui_file_delete (file)
+ struct gdb_file *file;
+{
+ struct tui_stream *tmpstream = gdb_file_data (file);
+ if (tmpstream->ts_magic != &tui_file_magic)
+ error ("Internal error: bad magic number");
+ if ((tmpstream->ts_streamtype == astring) &&
+ (tmpstream->ts_strbuf != NULL))
+ {
+ free (tmpstream->ts_strbuf);
+ }
+ free (tmpstream);
+}
+
+struct gdb_file *
+tui_fileopen (stream)
+ FILE *stream;
+{
+ struct gdb_file *file = tui_file_new ();
+ struct tui_stream *tmpstream = gdb_file_data (file);
+ tmpstream->ts_streamtype = afile;
+ tmpstream->ts_filestream = stream;
+ tmpstream->ts_strbuf = NULL;
+ tmpstream->ts_buflen = 0;
+ return file;
+}
+
+static int
+tui_file_isatty (file)
+ struct gdb_file *file;
+{
+ struct tui_stream *stream = gdb_file_data (file);
+ if (stream->ts_magic != &tui_file_magic)
+ error ("Internal error: bad magic number");
if (stream->ts_streamtype == afile)
return (isatty(fileno(stream->ts_filestream)));
else return 0;
@@ -1550,9 +1694,11 @@ GDB_FILE *
gdb_file_init_astring (n)
int n;
{
- GDB_FILE *tmpstream;
+ struct gdb_file *file = tui_file_new ();
+ struct tui_stream *tmpstream = gdb_file_data (file);
+ if (tmpstream->ts_magic != &tui_file_magic)
+ error ("Internal error: bad magic number");
- tmpstream = xmalloc (sizeof(GDB_FILE));
tmpstream->ts_streamtype = astring;
tmpstream->ts_filestream = NULL;
if (n > 0)
@@ -1564,41 +1710,38 @@ gdb_file_init_astring (n)
tmpstream->ts_strbuf = NULL;
tmpstream->ts_buflen = n;
- return tmpstream;
+ return file;
}
void
gdb_file_deallocate (streamptr)
GDB_FILE **streamptr;
{
- GDB_FILE *tmpstream;
-
- tmpstream = *streamptr;
- if ((tmpstream->ts_streamtype == astring) &&
- (tmpstream->ts_strbuf != NULL))
- {
- free (tmpstream->ts_strbuf);
- }
-
- free (tmpstream);
+ gdb_file_delete (*streamptr);
*streamptr = NULL;
}
char *
-gdb_file_get_strbuf (stream)
- GDB_FILE *stream;
+gdb_file_get_strbuf (file)
+ GDB_FILE *file;
{
+ struct tui_stream *stream = gdb_file_data (file);
+ if (stream->ts_magic != &tui_file_magic)
+ error ("Internal error: bad magic number");
return (stream->ts_strbuf);
}
/* adjust the length of the buffer by the amount necessary
to accomodate appending a string of length N to the buffer contents */
void
-gdb_file_adjust_strbuf (n, stream)
+gdb_file_adjust_strbuf (n, file)
int n;
- GDB_FILE *stream;
+ GDB_FILE *file;
{
+ struct tui_stream *stream = gdb_file_data (file);
int non_null_chars;
+ if (stream->ts_magic != &tui_file_magic)
+ error ("Internal error: bad magic number");
if (stream->ts_streamtype != astring)
return;
@@ -1624,28 +1767,24 @@ gdb_fopen (name, mode)
char * name;
char * mode;
{
- int gdb_file_size;
- GDB_FILE *tmp;
-
- gdb_file_size = sizeof(GDB_FILE);
- tmp = (GDB_FILE *) xmalloc (gdb_file_size);
- tmp->ts_streamtype = afile;
- tmp->ts_filestream = fopen (name, mode);
- tmp->ts_strbuf = NULL;
- tmp->ts_buflen = 0;
-
- return tmp;
+ FILE *f = fopen (name, mode);
+ if (f == NULL)
+ return NULL;
+ return stdio_file_new (f, 1);
}
-void
-gdb_flush (stream)
- GDB_FILE *stream;
+static void
+tui_file_flush (file)
+ GDB_FILE *file;
{
+ struct tui_stream *stream = gdb_file_data (file);
+ if (stream->ts_magic != &tui_file_magic)
+ error ("Internal error: bad magic number");
if (flush_hook
- && (stream == gdb_stdout
- || stream == gdb_stderr))
+ && (file == gdb_stdout
+ || file == gdb_stderr))
{
- flush_hook (stream);
+ flush_hook (file);
return;
}
@@ -1656,11 +1795,136 @@ void
gdb_fclose(streamptr)
GDB_FILE **streamptr;
{
- GDB_FILE *tmpstream;
+ gdb_file_delete (*streamptr);
+ *streamptr = NULL;
+}
+
+
+/* Implement the ``struct gdb_file'' object. */
+
+static gdb_file_isatty_ftype null_file_isatty;
+static gdb_file_fputs_ftype null_file_fputs;
+static gdb_file_flush_ftype null_file_flush;
+static gdb_file_delete_ftype null_file_delete;
+
+struct gdb_file
+{
+ gdb_file_flush_ftype *to_flush;
+ gdb_file_fputs_ftype *to_fputs;
+ gdb_file_delete_ftype *to_delete;
+ gdb_file_isatty_ftype *to_isatty;
+ void *to_data;
+};
+
+struct gdb_file *
+gdb_file_new ()
+{
+ struct gdb_file *file = xmalloc (sizeof (struct gdb_file));
+ set_gdb_file_data (file, NULL, null_file_delete);
+ set_gdb_file_flush (file, null_file_flush);
+ set_gdb_file_fputs (file, null_file_fputs);
+ set_gdb_file_isatty (file, null_file_isatty);
+ return file;
+}
- tmpstream = *streamptr;
- fclose (tmpstream->ts_filestream);
- gdb_file_deallocate (streamptr);
+void
+gdb_file_delete (file)
+ struct gdb_file *file;
+{
+ file->to_delete (file);
+ free (file);
+}
+
+static int
+null_file_isatty (file)
+ struct gdb_file *file;
+{
+ return 0;
+}
+
+static void
+null_file_flush (file)
+ struct gdb_file *file;
+{
+ return;
+}
+
+static void
+null_file_fputs (buf, file)
+ const char *buf;
+ struct gdb_file *file;
+{
+ return;
+}
+
+static void
+null_file_delete (file)
+ struct gdb_file *file;
+{
+ return;
+}
+
+void *
+gdb_file_data (file)
+ struct gdb_file *file;
+{
+ return file->to_data;
+}
+
+void
+gdb_flush (file)
+ struct gdb_file *file;
+{
+ file->to_flush (file);
+}
+
+int
+gdb_file_isatty (file)
+ struct gdb_file *file;
+{
+ return file->to_isatty (file);
+}
+
+void
+fputs_unfiltered (buf, file)
+ const char *buf;
+ struct gdb_file *file;
+{
+ file->to_fputs (buf, file);
+}
+
+void
+set_gdb_file_flush (file, flush)
+ struct gdb_file *file;
+ gdb_file_flush_ftype *flush;
+{
+ file->to_flush = flush;
+}
+
+void
+set_gdb_file_isatty (file, isatty)
+ struct gdb_file *file;
+ gdb_file_isatty_ftype *isatty;
+{
+ file->to_isatty = isatty;
+}
+
+void
+set_gdb_file_fputs (file, fputs)
+ struct gdb_file *file;
+ gdb_file_fputs_ftype *fputs;
+{
+ file->to_fputs = fputs;
+}
+
+void
+set_gdb_file_data (file, data, delete)
+ struct gdb_file *file;
+ void *data;
+ gdb_file_delete_ftype *delete;
+{
+ file->to_data = data;
+ file->to_delete = delete;
}
/* Like fputs but if FILTER is true, pause after every screenful.