summaryrefslogtreecommitdiff
path: root/gdb/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/utils.c')
-rw-r--r--gdb/utils.c138
1 files changed, 124 insertions, 14 deletions
diff --git a/gdb/utils.c b/gdb/utils.c
index f486199febf..61d9e46796e 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -47,6 +47,9 @@
#include <readline/readline.h>
+#undef XMALLOC
+#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
+
/* readline defines this. */
#undef savestring
@@ -1727,6 +1730,108 @@ stdio_fileopen (file)
}
+/* A pure memory based ``struct gdb_file'' that can be used an output
+ collector. It's input is available through gdb_file_put(). */
+
+struct mem_file
+ {
+ int *magic;
+ char *buffer;
+ int sizeof_buffer;
+ int strlen_buffer;
+ };
+
+extern gdb_file_fputs_ftype mem_file_fputs;
+static gdb_file_rewind_ftype mem_file_rewind;
+static gdb_file_put_ftype mem_file_put;
+static gdb_file_delete_ftype mem_file_delete;
+static struct gdb_file *mem_file_new PARAMS ((void));
+static int mem_file_magic;
+
+static struct gdb_file *
+mem_file_new (void)
+{
+ struct mem_file *stream = XMALLOC (struct mem_file);
+ struct gdb_file *file = gdb_file_new ();
+ set_gdb_file_data (file, stream, mem_file_delete);
+ set_gdb_file_fputs (file, mem_file_fputs);
+ set_gdb_file_rewind (file, mem_file_rewind);
+ set_gdb_file_put (file, mem_file_put);
+ stream->magic = &mem_file_magic;
+ stream->buffer = NULL;
+ stream->sizeof_buffer = 0;
+ return file;
+}
+
+static void
+mem_file_delete (struct gdb_file *file)
+{
+ struct mem_file *stream = gdb_file_data (file);
+ if (stream->magic != &mem_file_magic)
+ internal_error ("mem_file_delete: bad magic number");
+ if (stream->buffer != NULL)
+ free (stream->buffer);
+ free (stream);
+}
+
+struct gdb_file *
+mem_fileopen (void)
+{
+ return mem_file_new ();
+}
+
+static void
+mem_file_rewind (struct gdb_file *file)
+{
+ struct mem_file *stream = gdb_file_data (file);
+ if (stream->magic != &mem_file_magic)
+ internal_error ("mem_file_rewind: bad magic number");
+ if (stream->buffer != NULL)
+ {
+ stream->buffer[0] = '\0';
+ stream->strlen_buffer = 0;
+ }
+}
+
+static void
+mem_file_put (struct gdb_file *file, struct gdb_file *dest)
+{
+ struct mem_file *stream = gdb_file_data (file);
+ if (stream->magic != &mem_file_magic)
+ internal_error ("mem_file_put: bad magic number");
+ if (stream->buffer != NULL)
+ fputs_unfiltered (stream->buffer, dest);
+}
+
+void
+mem_file_fputs (const char *linebuffer, struct gdb_file *file)
+{
+ struct mem_file *stream = gdb_file_data (file);
+ if (stream->magic != &mem_file_magic)
+ internal_error ("mem_file_fputs: bad magic number");
+ if (stream->buffer == NULL)
+ {
+ stream->strlen_buffer = strlen (linebuffer);
+ stream->sizeof_buffer = stream->strlen_buffer + 1;
+ stream->buffer = xmalloc (stream->sizeof_buffer);
+ strcpy (stream->buffer, linebuffer);
+ }
+ else
+ {
+ int len = strlen (linebuffer);
+ int new_strlen = stream->strlen_buffer + len;
+ int new_sizeof = new_strlen + 1;
+ if (new_sizeof >= stream->sizeof_buffer)
+ {
+ stream->sizeof_buffer = new_sizeof;
+ stream->buffer = xrealloc (stream->buffer, stream->sizeof_buffer);
+ }
+ strcpy (stream->buffer + stream->strlen_buffer, linebuffer);
+ stream->strlen_buffer = new_strlen;
+ }
+}
+
+
/* A ``struct gdb_file'' that is compatible with all the legacy
code. */
@@ -1875,12 +1980,10 @@ tui_file_fputs (linebuffer, file)
#if defined(TUI)
extern int tui_owns_terminal;
#endif
- /* If anything (GUI, TUI) wants to capture GDB output, this is
- * the place... the way to do it is to set up
- * fputs_unfiltered_hook.
- * Our TUI ("gdb -tui") used to hook output, but in the
- * new (XDB style) scheme, we do not do that anymore... - RT
- */
+ /* NOTE: cagney/1999-10-13: The use of fputs_unfiltered_hook is
+ seriously discouraged. Those wanting to hook output should
+ instead implement their own gdb_file object and install that. See
+ also tui_file_flush(). */
if (fputs_unfiltered_hook
&& (file == gdb_stdout
|| file == gdb_stderr))
@@ -2028,16 +2131,23 @@ tui_file_flush (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
- && (file == gdb_stdout
- || file == gdb_stderr))
+ internal_error ("tui_file_flush: bad magic number");
+
+ /* NOTE: cagney/1999-10-12: If we've been linked with code that uses
+ fputs_unfiltered_hook then we assume that it doesn't need to know
+ about flushes. Code that does need to know about flushes can
+ implement a proper gdb_file object. */
+ if (fputs_unfiltered_hook)
+ return;
+
+ switch (stream->ts_streamtype)
{
- flush_hook (file);
- return;
+ case astring:
+ break;
+ case afile:
+ fflush (stream->ts_filestream);
+ break;
}
-
- fflush (stream->ts_filestream);
}
void