summaryrefslogtreecommitdiff
path: root/gdb/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/utils.c')
-rw-r--r--gdb/utils.c181
1 files changed, 117 insertions, 64 deletions
diff --git a/gdb/utils.c b/gdb/utils.c
index 339b26a31b0..9760cab4756 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -523,31 +523,38 @@ error_begin ()
and the remaining args are passed as arguments to it. */
NORETURN void
+verror (const char *string, va_list args)
+{
+ /* FIXME: cagney/1999-11-10: All error calls should come here.
+ Unfortunatly some code uses the sequence: error_begin(); print
+ error message; return_to_top_level. That code should be
+ flushed. */
+ error_begin ();
+ vfprintf_filtered (gdb_stderr, string, args);
+ fprintf_filtered (gdb_stderr, "\n");
+ /* Save it as the last error as well (no newline) */
+ gdb_file_rewind (gdb_lasterr);
+ vfprintf_filtered (gdb_lasterr, string, args);
+ va_end (args);
+ return_to_top_level (RETURN_ERROR);
+}
+
+NORETURN void
error (const char *string,...)
{
va_list args;
va_start (args, string);
- if (error_hook)
- (*error_hook) ();
- else
- {
- error_begin ();
- vfprintf_filtered (gdb_stderr, string, args);
- fprintf_filtered (gdb_stderr, "\n");
- /* Save it as the last error as well (no newline) */
- gdb_file_rewind (gdb_lasterr);
- vfprintf_filtered (gdb_lasterr, string, args);
- va_end (args);
- return_to_top_level (RETURN_ERROR);
- }
+ verror (string, args);
+ va_end (args);
}
-/* Allows the error message to be passed on a stream buffer */
-
NORETURN void
error_stream (GDB_FILE *stream)
{
- error (tui_file_get_strbuf (stream));
+ long size;
+ char *msg = gdb_file_xstrdup (stream, &size);
+ make_cleanup (free, msg);
+ error ("%s", msg);
}
/* Get the last error message issued by gdb */
@@ -555,26 +562,26 @@ error_stream (GDB_FILE *stream)
char *
error_last_message (void)
{
- return (tui_file_get_strbuf (gdb_lasterr));
+ long len;
+ return gdb_file_xstrdup (gdb_lasterr, &len);
}
-
+
/* This is to be called by main() at the very beginning */
void
error_init (void)
{
- gdb_lasterr = tui_sfileopen (132);
+ gdb_lasterr = mem_fileopen ();
}
/* Print a message reporting an internal error. Ask the user if they
want to continue, dump core, or just exit. */
NORETURN void
-internal_error (char *string, ...)
+internal_verror (const char *fmt, va_list ap)
{
static char msg[] = "Internal GDB error: recursive internal error.\n";
static int dejavu = 0;
- va_list args;
int continue_p;
int dump_core_p;
@@ -596,9 +603,7 @@ internal_error (char *string, ...)
/* Try to get the message out */
fputs_unfiltered ("gdb-internal-error: ", gdb_stderr);
- va_start (args, string);
- vfprintf_unfiltered (gdb_stderr, string, args);
- va_end (args);
+ vfprintf_unfiltered (gdb_stderr, fmt, ap);
fputs_unfiltered ("\n", gdb_stderr);
/* Default (no case) is to quit GDB. When in batch mode this
@@ -632,6 +637,15 @@ Create a core file containing the current state of GDB? ");
return_to_top_level (RETURN_ERROR);
}
+NORETURN void
+internal_error (char *string, ...)
+{
+ va_list ap;
+ va_start (ap, string);
+ internal_verror (string, ap);
+ va_end (ap);
+}
+
/* The strerror() function can return NULL for errno values that are
out of range. Provide a "safe" version that always returns a
printable string. */
@@ -787,7 +801,7 @@ notice_quit ()
immediate_quit = 1;
}
-#else /* !defined(__GO32__) && !defined(_MSC_VER) */
+#else /* !defined(_MSC_VER) */
void
notice_quit ()
@@ -795,7 +809,7 @@ notice_quit ()
/* Done by signals */
}
-#endif /* !defined(__GO32__) && !defined(_MSC_VER) */
+#endif /* !defined(_MSC_VER) */
/* Control C comes here */
void
@@ -1754,19 +1768,20 @@ 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(). */
+ buffer. The buffers accumulated contents are available via
+ gdb_file_put(). */
struct mem_file
{
int *magic;
char *buffer;
int sizeof_buffer;
- int strlen_buffer;
+ int length_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_write_ftype mem_file_write;
static gdb_file_delete_ftype mem_file_delete;
static struct gdb_file *mem_file_new PARAMS ((void));
static int mem_file_magic;
@@ -1777,12 +1792,13 @@ 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);
+ set_gdb_file_write (file, mem_file_write);
stream->magic = &mem_file_magic;
stream->buffer = NULL;
stream->sizeof_buffer = 0;
+ stream->length_buffer = 0;
return file;
}
@@ -1809,52 +1825,49 @@ 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;
- }
+ stream->length_buffer = 0;
}
static void
-mem_file_put (struct gdb_file *file, struct gdb_file *dest)
+mem_file_put (struct gdb_file *file,
+ gdb_file_put_method_ftype *write,
+ void *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);
+ if (stream->length_buffer > 0)
+ write (dest, stream->buffer, stream->length_buffer);
}
void
-mem_file_fputs (const char *linebuffer, struct gdb_file *file)
+mem_file_write (struct gdb_file *file,
+ const char *buffer,
+ long length_buffer)
{
struct mem_file *stream = gdb_file_data (file);
if (stream->magic != &mem_file_magic)
- internal_error ("mem_file_fputs: bad magic number");
+ internal_error ("mem_file_write: bad magic number");
if (stream->buffer == NULL)
{
- stream->strlen_buffer = strlen (linebuffer);
- stream->sizeof_buffer = stream->strlen_buffer + 1;
+ stream->length_buffer = length_buffer;
+ stream->sizeof_buffer = length_buffer;
stream->buffer = xmalloc (stream->sizeof_buffer);
- strcpy (stream->buffer, linebuffer);
+ memcpy (stream->buffer, buffer, length_buffer);
}
else
{
- int len = strlen (linebuffer);
- int new_strlen = stream->strlen_buffer + len;
- int new_sizeof = new_strlen + 1;
- if (new_sizeof >= stream->sizeof_buffer)
+ int new_length = stream->length_buffer + length_buffer;
+ if (new_length >= stream->sizeof_buffer)
{
- stream->sizeof_buffer = new_sizeof;
+ stream->sizeof_buffer = new_length;
stream->buffer = xrealloc (stream->buffer, stream->sizeof_buffer);
}
- strcpy (stream->buffer + stream->strlen_buffer, linebuffer);
- stream->strlen_buffer = new_strlen;
+ memcpy (stream->buffer + stream->length_buffer, buffer, length_buffer);
+ stream->length_buffer = new_length;
}
}
-
/* A ``struct gdb_file'' that is compatible with all the legacy
code. */
@@ -1972,17 +1985,15 @@ tui_file_rewind (file)
}
static void
-tui_file_put (file, dest)
- struct gdb_file *file;
- struct gdb_file *dest;
+tui_file_put (struct gdb_file *file,
+ gdb_file_put_method_ftype *write,
+ void *dest)
{
struct tui_stream *stream = gdb_file_data (file);
if (stream->ts_magic != &tui_file_magic)
internal_error ("tui_file_put: bad magic number");
if (stream->ts_streamtype == astring)
- {
- fputs_unfiltered (stream->ts_strbuf, dest);
- }
+ write (dest, stream->ts_strbuf, strlen (stream->ts_strbuf));
}
/* All TUI I/O sent to the *_filtered and *_unfiltered functions
@@ -2149,6 +2160,7 @@ static gdb_file_put_ftype null_file_put;
struct gdb_file
{
+ int *magic;
gdb_file_flush_ftype *to_flush;
gdb_file_write_ftype *to_write;
gdb_file_fputs_ftype *to_fputs;
@@ -2158,11 +2170,13 @@ struct gdb_file
gdb_file_put_ftype *to_put;
void *to_data;
};
+int gdb_file_magic;
struct gdb_file *
gdb_file_new ()
{
struct gdb_file *file = xmalloc (sizeof (struct gdb_file));
+ file->magic = &gdb_file_magic;
set_gdb_file_data (file, NULL, null_file_delete);
set_gdb_file_flush (file, null_file_flush);
set_gdb_file_write (file, null_file_write);
@@ -2196,9 +2210,9 @@ null_file_rewind (file)
}
static void
-null_file_put (file, src)
- struct gdb_file *file;
- struct gdb_file *src;
+null_file_put (struct gdb_file *file,
+ gdb_file_put_method_ftype *write,
+ void *dest)
{
return;
}
@@ -2265,6 +2279,8 @@ void *
gdb_file_data (file)
struct gdb_file *file;
{
+ if (file->magic != &gdb_file_magic)
+ internal_error ("gdb_file_data: bad magic number");
return file->to_data;
}
@@ -2290,11 +2306,11 @@ gdb_file_rewind (file)
}
void
-gdb_file_put (file, dest)
- struct gdb_file *file;
- struct gdb_file *dest;
+gdb_file_put (struct gdb_file *file,
+ gdb_file_put_method_ftype *write,
+ void *dest)
{
- file->to_put (file, dest);
+ file->to_put (file, write, dest);
}
void
@@ -2370,6 +2386,43 @@ set_gdb_file_data (file, data, delete)
file->to_delete = delete;
}
+/* gdb_file utility function for converting a ``struct gdb_file'' into
+ a memory buffer''. */
+
+struct accumulated_gdb_file
+{
+ char *buffer;
+ long length;
+};
+
+static void
+do_gdb_file_xstrdup (void *context, const char *buffer, long length)
+{
+ struct accumulated_gdb_file *acc = context;
+ if (acc->buffer == NULL)
+ acc->buffer = xmalloc (length + 1);
+ else
+ acc->buffer = xrealloc (acc->buffer, acc->length + length + 1);
+ memcpy (acc->buffer + acc->length, buffer, length);
+ acc->length += length;
+ acc->buffer[acc->length] = '\0';
+}
+
+char *
+gdb_file_xstrdup (struct gdb_file *file,
+ long *length)
+{
+ struct accumulated_gdb_file acc;
+ acc.buffer = NULL;
+ acc.length = 0;
+ gdb_file_put (file, do_gdb_file_xstrdup, &acc);
+ if (acc.buffer == NULL)
+ acc.buffer = xstrdup ("");
+ *length = acc.length;
+ return acc.buffer;
+}
+
+
/* Like fputs but if FILTER is true, pause after every screenful.
Regardless of FILTER can wrap at points other than the final