* xtensa-modules.c: Remove comment indicating that this is a
[deliverable/binutils-gdb.git] / gdb / utils.c
index 6d164e45ae35e9a6aec88428f2abe703fe8e3f20..f8ac0fd41a82654fbf009b2edb6503cbd4b830cc 100644 (file)
@@ -1,7 +1,8 @@
 /* General utility routines for GDB, the GNU debugger.
-   Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001
-   Free Software Foundation, Inc.
+
+   Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
+   Foundation, Inc.
 
    This file is part of GDB.
 
 #include "gdb_string.h"
 #include "event-top.h"
 
-#ifdef HAVE_CURSES_H
-#include <curses.h>
-#endif
-#ifdef HAVE_TERM_H
-#include <term.h>
-#endif
-
 #ifdef __GO32__
 #include <pc.h>
 #endif
 #include "demangle.h"
 #include "expression.h"
 #include "language.h"
+#include "charset.h"
 #include "annotate.h"
+#include "filenames.h"
 
-#include "inferior.h" /* for signed_pointer_to_address */
+#include "inferior.h"          /* for signed_pointer_to_address */
+
+#include <sys/param.h>         /* For MAXPATHLEN */
+
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#ifdef HAVE_TERM_H
+#include <term.h>
+#endif
 
 #include <readline/readline.h>
 
-#ifndef MALLOC_INCOMPATIBLE
+#ifdef USE_MMALLOC
+#include "mmalloc.h"
+#endif
+
+#ifdef NEED_DECLARATION_MALLOC
+extern PTR malloc ();          /* OK: PTR */
+#endif
 #ifdef NEED_DECLARATION_REALLOC
-extern PTR realloc ();
+extern PTR realloc ();         /* OK: PTR */
 #endif
 #ifdef NEED_DECLARATION_FREE
 extern void free ();
 #endif
+/* Actually, we'll never have the decl, since we don't define _GNU_SOURCE.  */
+#if defined(HAVE_CANONICALIZE_FILE_NAME) \
+    && defined(NEED_DECLARATION_CANONICALIZE_FILE_NAME)
+extern char *canonicalize_file_name (const char *);
 #endif
 
-#undef XMALLOC
-#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
-
 /* readline defines this.  */
 #undef savestring
 
@@ -102,7 +114,7 @@ static struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */
 static struct cleanup *run_cleanup_chain;      /* cleaned up on each 'run' */
 static struct cleanup *exec_cleanup_chain;     /* cleaned up on each execution command */
 /* cleaned up on each error from within an execution command */
-static struct cleanup *exec_error_cleanup_chain; 
+static struct cleanup *exec_error_cleanup_chain;
 
 /* Pointer to what is left to do for an execution command after the
    target stops. Used only in asynchronous mode, by targets that
@@ -132,13 +144,13 @@ int quit_flag;
 
 int immediate_quit;
 
-/* Nonzero means that encoded C++ names should be printed out in their
-   C++ form rather than raw.  */
+/* Nonzero means that encoded C++/ObjC names should be printed out in their
+   C++/ObjC form rather than raw.  */
 
 int demangle = 1;
 
-/* Nonzero means that encoded C++ names should be printed out in their
-   C++ form even in assembler language displays.  If this is set, but
+/* Nonzero means that encoded C++/ObjC names should be printed out in their
+   C++/ObjC form even in assembler language displays.  If this is set, but
    DEMANGLE is zero, names are printed raw, i.e. DEMANGLE controls.  */
 
 int asm_demangle = 0;
@@ -256,7 +268,7 @@ make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
                 void *arg)
 {
   register struct cleanup *new
-  = (struct cleanup *) xmalloc (sizeof (struct cleanup));
+    = (struct cleanup *) xmalloc (sizeof (struct cleanup));
   register struct cleanup *old_chain = *pmy_chain;
 
   new->next = *pmy_chain;
@@ -430,7 +442,8 @@ add_continuation (void (*continuation_hook) (struct continuation_arg *),
 {
   struct continuation *continuation_ptr;
 
-  continuation_ptr = (struct continuation *) xmalloc (sizeof (struct continuation));
+  continuation_ptr =
+    (struct continuation *) xmalloc (sizeof (struct continuation));
   continuation_ptr->continuation_hook = continuation_hook;
   continuation_ptr->arg_list = arg_list;
   continuation_ptr->next = cmd_continuation;
@@ -460,12 +473,12 @@ do_all_continuations (void)
 
   /* Work now on the list we have set aside. */
   while (continuation_ptr)
-     {
-       (continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
-       saved_continuation = continuation_ptr;
-       continuation_ptr = continuation_ptr->next;
-       xfree (saved_continuation);
-     }
+    {
+      (continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
+      saved_continuation = continuation_ptr;
+      continuation_ptr = continuation_ptr->next;
+      xfree (saved_continuation);
+    }
 }
 
 /* Walk down the cmd_continuation list, and get rid of all the
@@ -492,7 +505,8 @@ add_intermediate_continuation (void (*continuation_hook)
 {
   struct continuation *continuation_ptr;
 
-  continuation_ptr = (struct continuation *) xmalloc (sizeof (struct continuation));
+  continuation_ptr =
+    (struct continuation *) xmalloc (sizeof (struct continuation));
   continuation_ptr->continuation_hook = continuation_hook;
   continuation_ptr->arg_list = arg_list;
   continuation_ptr->next = intermediate_continuation;
@@ -522,12 +536,12 @@ do_all_intermediate_continuations (void)
 
   /* Work now on the list we have set aside. */
   while (continuation_ptr)
-     {
-       (continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
-       saved_continuation = continuation_ptr;
-       continuation_ptr = continuation_ptr->next;
-       xfree (saved_continuation);
-     }
+    {
+      (continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
+      saved_continuation = continuation_ptr;
+      continuation_ptr = continuation_ptr->next;
+      xfree (saved_continuation);
+    }
 }
 
 /* Walk down the cmd_continuation list, and get rid of all the
@@ -544,71 +558,46 @@ discard_all_intermediate_continuations (void)
       xfree (continuation_ptr);
     }
 }
-
 \f
 
-/* Print a warning message.  Way to use this is to call warning_begin,
-   output the warning message (use unfiltered output to gdb_stderr),
-   ending in a newline.  There is not currently a warning_end that you
-   call afterwards, but such a thing might be added if it is useful
-   for a GUI to separate warning messages from other output.
-
-   FIXME: Why do warnings use unfiltered output and errors filtered?
-   Is this anything other than a historical accident?  */
-
-void
-warning_begin (void)
-{
-  target_terminal_ours ();
-  wrap_here ("");              /* Force out any buffered output */
-  gdb_flush (gdb_stdout);
-  if (warning_pre_print)
-    fprintf_unfiltered (gdb_stderr, warning_pre_print);
-}
 
-/* Print a warning message.
-   The first argument STRING is the warning message, used as a fprintf string,
-   and the remaining args are passed as arguments to it.
-   The primary difference between warnings and errors is that a warning
-   does not force the return to command level.  */
+/* Print a warning message.  The first argument STRING is the warning
+   message, used as an fprintf format string, the second is the
+   va_list of arguments for that string.  A warning is unfiltered (not
+   paginated) so that the user does not need to page through each
+   screen full of warnings when there are lots of them.  */
 
 void
-warning (const char *string,...)
+vwarning (const char *string, va_list args)
 {
-  va_list args;
-  va_start (args, string);
   if (warning_hook)
     (*warning_hook) (string, args);
   else
     {
-      warning_begin ();
+      target_terminal_ours ();
+      wrap_here ("");          /* Force out any buffered output */
+      gdb_flush (gdb_stdout);
+      if (warning_pre_print)
+       fprintf_unfiltered (gdb_stderr, warning_pre_print);
       vfprintf_unfiltered (gdb_stderr, string, args);
       fprintf_unfiltered (gdb_stderr, "\n");
       va_end (args);
     }
 }
 
-/* Start the printing of an error message.  Way to use this is to call
-   this, output the error message (use filtered output to gdb_stderr
-   (FIXME: Some callers, like memory_error, use gdb_stdout)), ending
-   in a newline, and then call return_to_top_level (RETURN_ERROR).
-   error() provides a convenient way to do this for the special case
-   that the error message can be formatted with a single printf call,
-   but this is more general.  */
+/* Print a warning message.
+   The first argument STRING is the warning message, used as a fprintf string,
+   and the remaining args are passed as arguments to it.
+   The primary difference between warnings and errors is that a warning
+   does not force the return to command level.  */
+
 void
-error_begin (void)
+warning (const char *string, ...)
 {
-  if (error_begin_hook)
-    error_begin_hook ();
-
-  target_terminal_ours ();
-  wrap_here ("");              /* Force out any buffered output */
-  gdb_flush (gdb_stdout);
-
-  annotate_error_begin ();
-
-  if (error_pre_print)
-    fprintf_filtered (gdb_stderr, error_pre_print);
+  va_list args;
+  va_start (args, string);
+  vwarning (string, args);
+  va_end (args);
 }
 
 /* Print an error message and return to command level.
@@ -618,33 +607,14 @@ error_begin (void)
 NORETURN void
 verror (const char *string, va_list args)
 {
-  char *err_string;
-  struct cleanup *err_string_cleanup;
-  /* FIXME: cagney/1999-11-10: All error calls should come here.
-     Unfortunately some code uses the sequence: error_begin(); print
-     error message; return_to_top_level.  That code should be
-     flushed. */
-  error_begin ();
-  /* NOTE: It's tempting to just do the following...
-       vfprintf_filtered (gdb_stderr, string, args);
-     and then follow with a similar looking statement to cause the message
-     to also go to gdb_lasterr.  But if we do this, we'll be traversing the
-     va_list twice which works on some platforms and fails miserably on
-     others. */
-  /* Save it as the last error */
-  ui_file_rewind (gdb_lasterr);
-  vfprintf_filtered (gdb_lasterr, string, args);
-  /* Retrieve the last error and print it to gdb_stderr */
-  err_string = error_last_message ();
-  err_string_cleanup = make_cleanup (xfree, err_string);
-  fputs_filtered (err_string, gdb_stderr);
-  fprintf_filtered (gdb_stderr, "\n");
-  do_cleanups (err_string_cleanup);
-  return_to_top_level (RETURN_ERROR);
+  struct ui_file *tmp_stream = mem_fileopen ();
+  make_cleanup_ui_file_delete (tmp_stream);
+  vfprintf_unfiltered (tmp_stream, string, args);
+  error_stream (tmp_stream);
 }
 
 NORETURN void
-error (const char *string,...)
+error (const char *string, ...)
 {
   va_list args;
   va_start (args, string);
@@ -652,13 +622,33 @@ error (const char *string,...)
   va_end (args);
 }
 
+static void
+do_write (void *data, const char *buffer, long length_buffer)
+{
+  ui_file_write (data, buffer, length_buffer);
+}
+
 NORETURN void
 error_stream (struct ui_file *stream)
 {
-  long size;
-  char *msg = ui_file_xstrdup (stream, &size);
-  make_cleanup (xfree, msg);
-  error ("%s", msg);
+  if (error_begin_hook)
+    error_begin_hook ();
+
+  /* Copy the stream into the GDB_LASTERR buffer.  */
+  ui_file_rewind (gdb_lasterr);
+  ui_file_put (stream, do_write, gdb_lasterr);
+
+  /* Write the message plus any error_pre_print to gdb_stderr.  */
+  target_terminal_ours ();
+  wrap_here ("");              /* Force out any buffered output */
+  gdb_flush (gdb_stdout);
+  annotate_error_begin ();
+  if (error_pre_print)
+    fprintf_filtered (gdb_stderr, error_pre_print);
+  ui_file_put (stream, do_write, gdb_stderr);
+  fprintf_filtered (gdb_stderr, "\n");
+
+  throw_exception (RETURN_ERROR);
 }
 
 /* Get the last error message issued by gdb */
@@ -669,7 +659,7 @@ error_last_message (void)
   long len;
   return ui_file_xstrdup (gdb_lasterr, &len);
 }
-  
+
 /* This is to be called by main() at the very beginning */
 
 void
@@ -678,19 +668,33 @@ error_init (void)
   gdb_lasterr = mem_fileopen ();
 }
 
-/* Print a message reporting an internal error. Ask the user if they
-   want to continue, dump core, or just exit. */
+/* Print a message reporting an internal error/warning. Ask the user
+   if they want to continue, dump core, or just exit.  Return
+   something to indicate a quit.  */
 
-NORETURN void
-internal_verror (const char *file, int line,
-                const char *fmt, va_list ap)
+struct internal_problem
+{
+  const char *name;
+  /* FIXME: cagney/2002-08-15: There should be ``maint set/show''
+     commands available for controlling these variables.  */
+  enum auto_boolean should_quit;
+  enum auto_boolean should_dump_core;
+};
+
+/* Report a problem, internal to GDB, to the user.  Once the problem
+   has been reported, and assuming GDB didn't quit, the caller can
+   either allow execution to resume or throw an error.  */
+
+static void
+internal_vproblem (struct internal_problem *problem,
+                  const char *file, int line, const char *fmt, va_list ap)
 {
-  static char msg[] = "Internal GDB error: recursive internal error.\n";
-  static int dejavu = 0;
-  int continue_p;
+  static char msg[] = "Recursive internal problem.\n";
+  static int dejavu;
+  int quit_p;
   int dump_core_p;
 
-  /* don't allow infinite error recursion. */
+  /* Don't allow infinite error/warning recursion.  */
   switch (dejavu)
     {
     case 0:
@@ -699,48 +703,94 @@ internal_verror (const char *file, int line,
     case 1:
       dejavu = 2;
       fputs_unfiltered (msg, gdb_stderr);
-      internal_error (__FILE__, __LINE__, "failed internal consistency check");
+      abort ();                        /* NOTE: GDB has only three calls to abort().  */
     default:
       dejavu = 3;
       write (STDERR_FILENO, msg, sizeof (msg));
       exit (1);
     }
 
-  /* Try to get the message out */
+  /* Try to get the message out and at the start of a new line.  */
   target_terminal_ours ();
-  fprintf_unfiltered (gdb_stderr, "%s:%d: gdb-internal-error: ", file, line);
+  begin_line ();
+
+  /* The error/warning message.  Format using a style similar to a
+     compiler error message.  */
+  fprintf_unfiltered (gdb_stderr, "%s:%d: %s: ", file, line, problem->name);
   vfprintf_unfiltered (gdb_stderr, fmt, ap);
   fputs_unfiltered ("\n", gdb_stderr);
 
-  /* Default (no case) is to quit GDB.  When in batch mode this
-     lessens the likelhood of GDB going into an infinate loop. */
-  continue_p = query ("\
-An internal GDB error was detected.  This may make further\n\
-debugging unreliable.  Continue this debugging session? ");
+  /* Provide more details so that the user knows that they are living
+     on the edge.  */
+  fprintf_unfiltered (gdb_stderr, "\
+A problem internal to GDB has been detected.  Further\n\
+debugging may prove unreliable.\n");
 
-  /* Default (no case) is to not dump core.  Lessen the chance of GDB
-     leaving random core files around. */
-  dump_core_p = query ("\
-Create a core file containing the current state of GDB? ");
+  switch (problem->should_quit)
+    {
+    case AUTO_BOOLEAN_AUTO:
+      /* Default (yes/batch case) is to quit GDB.  When in batch mode
+         this lessens the likelhood of GDB going into an infinate
+         loop.  */
+      quit_p = query ("Quit this debugging session? ");
+      break;
+    case AUTO_BOOLEAN_TRUE:
+      quit_p = 1;
+      break;
+    case AUTO_BOOLEAN_FALSE:
+      quit_p = 0;
+      break;
+    default:
+      internal_error (__FILE__, __LINE__, "bad switch");
+    }
 
-  if (continue_p)
+  switch (problem->should_dump_core)
     {
-      if (dump_core_p)
-       {
-         if (fork () == 0)
-           internal_error (__FILE__, __LINE__, "failed internal consistency check");
-       }
+    case AUTO_BOOLEAN_AUTO:
+      /* Default (yes/batch case) is to dump core.  This leaves a GDB
+         `dropping' so that it is easier to see that something went
+         wrong in GDB.  */
+      dump_core_p = query ("Create a core file of GDB? ");
+      break;
+      break;
+    case AUTO_BOOLEAN_TRUE:
+      dump_core_p = 1;
+      break;
+    case AUTO_BOOLEAN_FALSE:
+      dump_core_p = 0;
+      break;
+    default:
+      internal_error (__FILE__, __LINE__, "bad switch");
     }
-  else
+
+  if (quit_p)
     {
       if (dump_core_p)
-       internal_error (__FILE__, __LINE__, "failed internal consistency check");
+       abort ();               /* NOTE: GDB has only three calls to abort().  */
       else
        exit (1);
     }
+  else
+    {
+      if (dump_core_p)
+       {
+         if (fork () == 0)
+           abort ();           /* NOTE: GDB has only three calls to abort().  */
+       }
+    }
 
   dejavu = 0;
-  return_to_top_level (RETURN_ERROR);
+}
+
+static struct internal_problem internal_error_problem = {
+  "internal-error", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
+};
+
+NORETURN void
+internal_verror (const char *file, int line, const char *fmt, va_list ap)
+{
+  internal_vproblem (&internal_error_problem, file, line, fmt, ap);
+  throw_exception (RETURN_ERROR);
 }
 
 NORETURN void
@@ -748,11 +798,29 @@ internal_error (const char *file, int line, const char *string, ...)
 {
   va_list ap;
   va_start (ap, string);
-
   internal_verror (file, line, string, ap);
   va_end (ap);
 }
 
+static struct internal_problem internal_warning_problem = {
+  "internal-error", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
+};
+
+void
+internal_vwarning (const char *file, int line, const char *fmt, va_list ap)
+{
+  internal_vproblem (&internal_warning_problem, file, line, fmt, ap);
+}
+
+void
+internal_warning (const char *file, int line, const char *string, ...)
+{
+  va_list ap;
+  va_start (ap, string);
+  internal_vwarning (file, line, 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. */
@@ -763,7 +831,8 @@ safe_strerror (int errnum)
   char *msg;
   static char buf[32];
 
-  if ((msg = strerror (errnum)) == NULL)
+  msg = strerror (errnum);
+  if (msg == NULL)
     {
       sprintf (buf, "(undocumented errno %d)", errnum);
       msg = buf;
@@ -776,7 +845,7 @@ safe_strerror (int errnum)
    Then return to command level.  */
 
 NORETURN void
-perror_with_name (char *string)
+perror_with_name (const char *string)
 {
   char *err;
   char *combined;
@@ -800,7 +869,7 @@ perror_with_name (char *string)
    as the file name for which the error was encountered.  */
 
 void
-print_sys_errmsg (char *string, int errcode)
+print_sys_errmsg (const char *string, int errcode)
 {
   char *err;
   char *combined;
@@ -822,7 +891,7 @@ print_sys_errmsg (char *string, int errcode)
 void
 quit (void)
 {
-  serial_t gdb_stdout_serial = serial_fdopen (1);
+  struct serial *gdb_stdout_serial = serial_fdopen (1);
 
   target_terminal_ours ();
 
@@ -839,8 +908,8 @@ quit (void)
   gdb_flush (gdb_stderr);
 
   /* 3.  The system-level buffer.  */
-  SERIAL_DRAIN_OUTPUT (gdb_stdout_serial);
-  SERIAL_UN_FDOPEN (gdb_stdout_serial);
+  serial_drain_output (gdb_stdout_serial);
+  serial_un_fdopen (gdb_stdout_serial);
 
   annotate_error_begin ();
 
@@ -854,46 +923,17 @@ quit (void)
   fprintf_unfiltered (gdb_stderr, "Quit\n");
 #else
   if (job_control
-  /* If there is no terminal switching for this target, then we can't
-     possibly get screwed by the lack of job control.  */
+      /* If there is no terminal switching for this target, then we can't
+         possibly get screwed by the lack of job control.  */
       || current_target.to_terminal_ours == NULL)
     fprintf_unfiltered (gdb_stderr, "Quit\n");
   else
     fprintf_unfiltered (gdb_stderr,
-              "Quit (expect signal SIGINT when the program is resumed)\n");
+                       "Quit (expect signal SIGINT when the program is resumed)\n");
 #endif
-  return_to_top_level (RETURN_QUIT);
-}
-
-
-#if defined(_MSC_VER)          /* should test for wingdb instead? */
-
-/*
- * Windows translates all keyboard and mouse events 
- * into a message which is appended to the message 
- * queue for the process.
- */
-
-void
-notice_quit (void)
-{
-  int k = win32pollquit ();
-  if (k == 1)
-    quit_flag = 1;
-  else if (k == 2)
-    immediate_quit = 1;
-}
-
-#else /* !defined(_MSC_VER) */
-
-void
-notice_quit (void)
-{
-  /* Done by signals */
+  throw_exception (RETURN_QUIT);
 }
 
-#endif /* !defined(_MSC_VER) */
-
 /* Control C comes here */
 void
 request_quit (int signo)
@@ -914,41 +954,33 @@ request_quit (int signo)
 \f
 /* Memory management stuff (malloc friends).  */
 
-/* Make a substitute size_t for non-ANSI compilers. */
-
-#ifndef HAVE_STDDEF_H
-#ifndef size_t
-#define size_t unsigned int
-#endif
-#endif
-
 #if !defined (USE_MMALLOC)
 
-PTR
-mcalloc (PTR md, size_t number, size_t size)
+static void *
+mmalloc (void *md, size_t size)
 {
-  return calloc (number, size);
+  return malloc (size);                /* NOTE: GDB's only call to malloc() */
 }
 
-PTR
-mmalloc (PTR md, size_t size)
+static void *
+mrealloc (void *md, void *ptr, size_t size)
 {
-  return malloc (size);
+  if (ptr == 0)                        /* Guard against old realloc's */
+    return mmalloc (md, size);
+  else
+    return realloc (ptr, size);        /* NOTE: GDB's only call to ralloc() */
 }
 
-PTR
-mrealloc (PTR md, PTR ptr, size_t size)
+static void *
+mcalloc (void *md, size_t number, size_t size)
 {
-  if (ptr == 0)                        /* Guard against old realloc's */
-    return malloc (size);
-  else
-    return realloc (ptr, size);
+  return calloc (number, size);        /* NOTE: GDB's only call to calloc() */
 }
 
-void
-mfree (PTR md, PTR ptr)
+static void
+mfree (void *md, void *ptr)
 {
-  xfree (ptr);
+  free (ptr);                  /* NOTE: GDB's only call to free() */
 }
 
 #endif /* USE_MMALLOC */
@@ -997,9 +1029,10 @@ init_malloc (void *md)
          initialize_all_files(). */
 
       fprintf_unfiltered
-       (gdb_stderr, "warning: failed to install memory consistency checks; ");
-      fprintf_unfiltered
-       (gdb_stderr, "configuration should define NO_MMCHECK or MMCHECK_FORCE\n");
+       (gdb_stderr,
+        "warning: failed to install memory consistency checks; ");
+      fprintf_unfiltered (gdb_stderr,
+                         "configuration should define NO_MMCHECK or MMCHECK_FORCE\n");
     }
 
   mmtrace ();
@@ -1016,42 +1049,47 @@ nomem (long size)
   if (size > 0)
     {
       internal_error (__FILE__, __LINE__,
-                     "virtual memory exhausted: can't allocate %ld bytes.", size);
+                     "virtual memory exhausted: can't allocate %ld bytes.",
+                     size);
     }
   else
     {
-      internal_error (__FILE__, __LINE__,
-                     "virtual memory exhausted.");
+      internal_error (__FILE__, __LINE__, "virtual memory exhausted.");
     }
 }
 
-/* Like mmalloc but get error if no storage available, and protect against
-   the caller wanting to allocate zero bytes.  Whether to return NULL for
-   a zero byte request, or translate the request into a request for one
-   byte of zero'd storage, is a religious issue. */
+/* The xmmalloc() family of memory management routines.
 
-PTR
-xmmalloc (PTR md, long size)
+   These are are like the mmalloc() family except that they implement
+   consistent semantics and guard against typical memory management
+   problems: if a malloc fails, an internal error is thrown; if
+   free(NULL) is called, it is ignored; if *alloc(0) is called, NULL
+   is returned.
+
+   All these routines are implemented using the mmalloc() family. */
+
+void *
+xmmalloc (void *md, size_t size)
 {
-  register PTR val;
+  void *val;
 
   if (size == 0)
     {
       val = NULL;
     }
-  else if ((val = mmalloc (md, size)) == NULL)
+  else
     {
-      nomem (size);
+      val = mmalloc (md, size);
+      if (val == NULL)
+       nomem (size);
     }
   return (val);
 }
 
-/* Like mrealloc but get error if no storage available.  */
-
-PTR
-xmrealloc (PTR md, PTR ptr, long size)
+void *
+xmrealloc (void *md, void *ptr, size_t size)
 {
-  register PTR val;
+  void *val;
 
   if (size == 0)
     {
@@ -1077,49 +1115,61 @@ xmrealloc (PTR md, PTR ptr, long size)
   return (val);
 }
 
-/* Like malloc but get error if no storage available, and protect against
-   the caller wanting to allocate zero bytes.  */
-
-PTR
-xmalloc (size_t size)
-{
-  return (xmmalloc ((PTR) NULL, size));
-}
-
-/* Like calloc but get error if no storage available */
-
-PTR
-xcalloc (size_t number, size_t size)
+void *
+xmcalloc (void *md, size_t number, size_t size)
 {
   void *mem;
-
   if (number == 0 || size == 0)
     mem = NULL;
   else
     {
-      mem = mcalloc (NULL, number, size);
+      mem = mcalloc (md, number, size);
       if (mem == NULL)
        nomem (number * size);
     }
   return mem;
 }
 
-/* Like mrealloc but get error if no storage available.  */
+void
+xmfree (void *md, void *ptr)
+{
+  if (ptr != NULL)
+    mfree (md, ptr);
+}
+
+/* The xmalloc() (libiberty.h) family of memory management routines.
+
+   These are like the ISO-C malloc() family except that they implement
+   consistent semantics and guard against typical memory management
+   problems.  See xmmalloc() above for further information.
+
+   All these routines are wrappers to the xmmalloc() family. */
+
+/* NOTE: These are declared using PTR to ensure consistency with
+   "libiberty.h".  xfree() is GDB local.  */
+
+PTR                            /* OK: PTR */
+xmalloc (size_t size)
+{
+  return xmmalloc (NULL, size);
+}
 
-PTR
-xrealloc (PTR ptr, size_t size)
+PTR                            /* OK: PTR */
+xrealloc (PTR ptr, size_t size)        /* OK: PTR */
 {
-  return (xmrealloc ((PTR) NULL, ptr, size));
+  return xmrealloc (NULL, ptr, size);
 }
 
-/* Free up space allocated by one of xmalloc(), xcalloc(), or
-   xrealloc().  */
+PTR                            /* OK: PTR */
+xcalloc (size_t number, size_t size)
+{
+  return xmcalloc (NULL, number, size);
+}
 
 void
 xfree (void *ptr)
 {
-  if (ptr != NULL)
-    free (ptr); /* NOTE: GDB's only call to free() */
+  xmfree (NULL, ptr);
 }
 \f
 
@@ -1143,14 +1193,12 @@ xvasprintf (char **ret, const char *format, va_list ap)
      badly format string; or something else. */
   if ((*ret) == NULL)
     internal_error (__FILE__, __LINE__,
-                   "vasprintf returned NULL buffer (errno %d)",
-                   errno);
+                   "vasprintf returned NULL buffer (errno %d)", errno);
   /* A negative status with a non-NULL buffer shouldn't never
      happen. But to be sure. */
   if (status < 0)
     internal_error (__FILE__, __LINE__,
-                   "vasprintf call failed (errno %d)",
-                   errno);
+                   "vasprintf call failed (errno %d)", errno);
 }
 
 
@@ -1230,7 +1278,7 @@ gdb_print_host_address (void *addr, struct ui_file *stream)
 
 /* VARARGS */
 int
-query (char *ctlstr,...)
+query (const char *ctlstr, ...)
 {
   va_list args;
   register int answer;
@@ -1247,11 +1295,6 @@ query (char *ctlstr,...)
   /* Automatically answer "yes" if input is not from a terminal.  */
   if (!input_from_terminal_p ())
     return 1;
-#ifdef MPW
-  /* FIXME Automatically answer "yes" if called from MacGDB.  */
-  if (mac_app)
-    return 1;
-#endif /* MPW */
 
   while (1)
     {
@@ -1267,25 +1310,10 @@ query (char *ctlstr,...)
       if (annotation_level > 1)
        printf_filtered ("\n\032\032query\n");
 
-#ifdef MPW
-      /* If not in MacGDB, move to a new line so the entered line doesn't
-         have a prompt on the front of it. */
-      if (!mac_app)
-       fputs_unfiltered ("\n", gdb_stdout);
-#endif /* MPW */
-
       wrap_here ("");
       gdb_flush (gdb_stdout);
 
-#if defined(TUI)
-      if (!tui_version || cmdWin == tuiWinWithFocus ())
-#endif
-       answer = fgetc (stdin);
-#if defined(TUI)
-      else
-       answer = (unsigned char) tuiBufferGetc ();
-
-#endif
+      answer = fgetc (stdin);
       clearerr (stdin);                /* in case of C-d */
       if (answer == EOF)       /* C-d */
        {
@@ -1293,21 +1321,13 @@ query (char *ctlstr,...)
          break;
        }
       /* Eat rest of input line, to EOF or newline */
-      if ((answer != '\n') || (tui_version && answer != '\r'))
+      if (answer != '\n')
        do
          {
-#if defined(TUI)
-           if (!tui_version || cmdWin == tuiWinWithFocus ())
-#endif
-             ans2 = fgetc (stdin);
-#if defined(TUI)
-           else
-             ans2 = (unsigned char) tuiBufferGetc ();
-#endif
+           ans2 = fgetc (stdin);
            clearerr (stdin);
          }
        while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
-      TUIDO (((TuiOpaqueFuncPtr) tui_vStartNewLines, 1));
 
       if (answer >= 'a')
        answer -= 040;
@@ -1330,6 +1350,23 @@ query (char *ctlstr,...)
 }
 \f
 
+/* Print an error message saying that we couldn't make sense of a
+   \^mumble sequence in a string or character constant.  START and END
+   indicate a substring of some larger string that contains the
+   erroneous backslash sequence, missing the initial backslash.  */
+static NORETURN int
+no_control_char_error (const char *start, const char *end)
+{
+  int len = end - start;
+  char *copy = alloca (end - start + 1);
+
+  memcpy (copy, start, len);
+  copy[len] = '\0';
+
+  error ("There is no control character `\\%s' in the `%s' character set.",
+        copy, target_charset ());
+}
+
 /* Parse a C escape sequence.  STRING_PTR points to a variable
    containing a pointer to the string to parse.  That pointer
    should point to the character after the \.  That pointer
@@ -1348,67 +1385,91 @@ query (char *ctlstr,...)
 int
 parse_escape (char **string_ptr)
 {
+  int target_char;
   register int c = *(*string_ptr)++;
-  switch (c)
-    {
-    case 'a':
-      return 007;              /* Bell (alert) char */
-    case 'b':
-      return '\b';
-    case 'e':                  /* Escape character */
-      return 033;
-    case 'f':
-      return '\f';
-    case 'n':
-      return '\n';
-    case 'r':
-      return '\r';
-    case 't':
-      return '\t';
-    case 'v':
-      return '\v';
-    case '\n':
-      return -2;
-    case 0:
-      (*string_ptr)--;
-      return 0;
-    case '^':
-      c = *(*string_ptr)++;
-      if (c == '\\')
-       c = parse_escape (string_ptr);
-      if (c == '?')
-       return 0177;
-      return (c & 0200) | (c & 037);
-
-    case '0':
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
+  if (c_parse_backslash (c, &target_char))
+    return target_char;
+  else
+    switch (c)
       {
-       register int i = c - '0';
-       register int count = 0;
-       while (++count < 3)
-         {
-           if ((c = *(*string_ptr)++) >= '0' && c <= '7')
-             {
-               i *= 8;
-               i += c - '0';
-             }
-           else
-             {
-               (*string_ptr)--;
-               break;
-             }
-         }
-       return i;
+      case '\n':
+       return -2;
+      case 0:
+       (*string_ptr)--;
+       return 0;
+      case '^':
+       {
+         /* Remember where this escape sequence started, for reporting
+            errors.  */
+         char *sequence_start_pos = *string_ptr - 1;
+
+         c = *(*string_ptr)++;
+
+         if (c == '?')
+           {
+             /* XXXCHARSET: What is `delete' in the host character set?  */
+             c = 0177;
+
+             if (!host_char_to_target (c, &target_char))
+               error ("There is no character corresponding to `Delete' "
+                      "in the target character set `%s'.", host_charset ());
+
+             return target_char;
+           }
+         else if (c == '\\')
+           target_char = parse_escape (string_ptr);
+         else
+           {
+             if (!host_char_to_target (c, &target_char))
+               no_control_char_error (sequence_start_pos, *string_ptr);
+           }
+
+         /* Now target_char is something like `c', and we want to find
+            its control-character equivalent.  */
+         if (!target_char_to_control_char (target_char, &target_char))
+           no_control_char_error (sequence_start_pos, *string_ptr);
+
+         return target_char;
+       }
+
+       /* XXXCHARSET: we need to use isdigit and value-of-digit
+          methods of the host character set here.  */
+
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+       {
+         register int i = c - '0';
+         register int count = 0;
+         while (++count < 3)
+           {
+             c = (**string_ptr);
+             if (c >= '0' && c <= '7')
+               {
+                 (*string_ptr)++;
+                 i *= 8;
+                 i += c - '0';
+               }
+             else
+               {
+                 break;
+               }
+           }
+         return i;
+       }
+      default:
+       if (!host_char_to_target (c, &target_char))
+         error
+           ("The escape sequence `\%c' is equivalent to plain `%c', which"
+            " has no equivalent\n" "in the `%s' character set.", c, c,
+            target_charset ());
+       return target_char;
       }
-    default:
-      return c;
-    }
 }
 \f
 /* Print the character C on STREAM as part of the contents of a literal
@@ -1484,15 +1545,16 @@ fputstr_unfiltered (const char *str, int quoter, struct ui_file *stream)
 }
 
 void
-fputstrn_unfiltered (const char *str, int n, int quoter, struct ui_file *stream)
+fputstrn_unfiltered (const char *str, int n, int quoter,
+                    struct ui_file *stream)
 {
   int i;
   for (i = 0; i < n; i++)
     printchar (str[i], fputs_unfiltered, fprintf_unfiltered, stream, quoter);
 }
-
 \f
 
+
 /* Number of lines per page or UINT_MAX if paging is disabled.  */
 static unsigned int lines_per_page;
 /* Number of chars per line or UINT_MAX if line folding is disabled.  */
@@ -1530,12 +1592,7 @@ void
 init_page_info (void)
 {
 #if defined(TUI)
-  if (tui_version && m_winPtrNotNull (cmdWin))
-    {
-      lines_per_page = cmdWin->generic.height;
-      chars_per_line = cmdWin->generic.width;
-    }
-  else
+  if (!tui_get_command_dimension (&chars_per_line, &lines_per_page))
 #endif
     {
       /* These defaults will be used if we are unable to get the correct
@@ -1547,9 +1604,7 @@ init_page_info (void)
       lines_per_page = 24;
       chars_per_line = 80;
 
-#if !defined (MPW) && !defined (_WIN32)
-      /* No termcap under MPW, although might be cool to do something
-         by looking at worksheet or console window sizes. */
+#if !defined (_WIN32)
       /* Initialize the screen height and width from termcap.  */
       {
        char *termtype = getenv ("TERM");
@@ -1585,7 +1640,7 @@ init_page_info (void)
              }
          }
       }
-#endif /* MPW */
+#endif
 
 #if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
 
@@ -1656,7 +1711,7 @@ prompt_for_continue (void)
   /* Call readline, not gdb_readline, because GO32 readline handles control-C
      whereas control-C to gdb_readline will cause the user to get dumped
      out to DOS.  */
-  ignore = readline (cont_prompt);
+  ignore = gdb_readline_wrapper (cont_prompt);
 
   if (annotation_level > 1)
     printf_unfiltered ("\n\032\032post-prompt-for-continue\n");
@@ -1749,22 +1804,67 @@ wrap_here (char *indent)
     }
 }
 
-/* Ensure that whatever gets printed next, using the filtered output
-   commands, starts at the beginning of the line.  I.E. if there is
-   any pending output for the current line, flush it and start a new
-   line.  Otherwise do nothing. */
+/* Print input string to gdb_stdout, filtered, with wrap, 
+   arranging strings in columns of n chars. String can be
+   right or left justified in the column.  Never prints 
+   trailing spaces.  String should never be longer than
+   width.  FIXME: this could be useful for the EXAMINE 
+   command, which currently doesn't tabulate very well */
 
 void
-begin_line (void)
+puts_filtered_tabular (char *string, int width, int right)
 {
-  if (chars_printed > 0)
+  int spaces = 0;
+  int stringlen;
+  char *spacebuf;
+
+  gdb_assert (chars_per_line > 0);
+  if (chars_per_line == UINT_MAX)
     {
-      puts_filtered ("\n");
+      fputs_filtered (string, gdb_stdout);
+      fputs_filtered ("\n", gdb_stdout);
+      return;
     }
-}
 
+  if (((chars_printed - 1) / width + 2) * width >= chars_per_line)
+    fputs_filtered ("\n", gdb_stdout);
 
-/* Like fputs but if FILTER is true, pause after every screenful.
+  if (width >= chars_per_line)
+    width = chars_per_line - 1;
+
+  stringlen = strlen (string);
+
+  if (chars_printed > 0)
+    spaces = width - (chars_printed - 1) % width - 1;
+  if (right)
+    spaces += width - stringlen;
+
+  spacebuf = alloca (spaces + 1);
+  spacebuf[spaces] = '\0';
+  while (spaces--)
+    spacebuf[spaces] = ' ';
+
+  fputs_filtered (spacebuf, gdb_stdout);
+  fputs_filtered (string, gdb_stdout);
+}
+
+
+/* Ensure that whatever gets printed next, using the filtered output
+   commands, starts at the beginning of the line.  I.E. if there is
+   any pending output for the current line, flush it and start a new
+   line.  Otherwise do nothing. */
+
+void
+begin_line (void)
+{
+  if (chars_printed > 0)
+    {
+      puts_filtered ("\n");
+    }
+}
+
+
+/* Like fputs but if FILTER is true, pause after every screenful.
 
    Regardless of FILTER can wrap at points other than the final
    character of a line.
@@ -1802,8 +1902,7 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
   while (*lineptr)
     {
       /* Possible new page.  */
-      if (filter &&
-         (lines_printed >= lines_per_page - 1))
+      if (filter && (lines_printed >= lines_per_page - 1))
        prompt_for_continue ();
 
       while (*lineptr && *lineptr != '\n')
@@ -1851,7 +1950,7 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
              if (wrap_column)
                {
                  fputs_unfiltered (wrap_indent, stream);
-                 *wrap_pointer = '\0';         /* Null-terminate saved stuff */
+                 *wrap_pointer = '\0'; /* Null-terminate saved stuff */
                  fputs_unfiltered (wrap_buffer, stream);       /* and eject it */
                  /* FIXME, this strlen is what prevents wrap_indent from
                     containing tabs.  However, if we recurse to print it
@@ -2065,7 +2164,7 @@ vprintf_unfiltered (const char *format, va_list args)
 }
 
 void
-fprintf_filtered (struct ui_file * stream, const char *format,...)
+fprintf_filtered (struct ui_file *stream, const char *format, ...)
 {
   va_list args;
   va_start (args, format);
@@ -2074,7 +2173,7 @@ fprintf_filtered (struct ui_file * stream, const char *format,...)
 }
 
 void
-fprintf_unfiltered (struct ui_file * stream, const char *format,...)
+fprintf_unfiltered (struct ui_file *stream, const char *format, ...)
 {
   va_list args;
   va_start (args, format);
@@ -2086,7 +2185,8 @@ fprintf_unfiltered (struct ui_file * stream, const char *format,...)
    Called as fprintfi_filtered (spaces, stream, format, ...);  */
 
 void
-fprintfi_filtered (int spaces, struct ui_file * stream, const char *format,...)
+fprintfi_filtered (int spaces, struct ui_file *stream, const char *format,
+                  ...)
 {
   va_list args;
   va_start (args, format);
@@ -2098,7 +2198,7 @@ fprintfi_filtered (int spaces, struct ui_file * stream, const char *format,...)
 
 
 void
-printf_filtered (const char *format,...)
+printf_filtered (const char *format, ...)
 {
   va_list args;
   va_start (args, format);
@@ -2108,7 +2208,7 @@ printf_filtered (const char *format,...)
 
 
 void
-printf_unfiltered (const char *format,...)
+printf_unfiltered (const char *format, ...)
 {
   va_list args;
   va_start (args, format);
@@ -2120,7 +2220,7 @@ printf_unfiltered (const char *format,...)
    Called as printfi_filtered (spaces, format, ...);  */
 
 void
-printfi_filtered (int spaces, const char *format,...)
+printfi_filtered (int spaces, const char *format, ...)
 {
   va_list args;
   va_start (args, format);
@@ -2176,7 +2276,7 @@ print_spaces_filtered (int n, struct ui_file *stream)
   fputs_filtered (n_spaces (n), stream);
 }
 \f
-/* C++ demangler stuff.  */
+/* C++/ObjC demangler stuff.  */
 
 /* fprintf_symbol_filtered attempts to demangle NAME, a symbol in language
    LANG, using demangling args ARG_MODE, and print it filtered to STREAM.
@@ -2184,8 +2284,8 @@ print_spaces_filtered (int n, struct ui_file *stream)
    demangling is off, the name is printed in its "raw" form. */
 
 void
-fprintf_symbol_filtered (struct ui_file *stream, char *name, enum language lang,
-                        int arg_mode)
+fprintf_symbol_filtered (struct ui_file *stream, char *name,
+                        enum language lang, int arg_mode)
 {
   char *demangled;
 
@@ -2198,21 +2298,7 @@ fprintf_symbol_filtered (struct ui_file *stream, char *name, enum language lang,
        }
       else
        {
-         switch (lang)
-           {
-           case language_cplus:
-             demangled = cplus_demangle (name, arg_mode);
-             break;
-           case language_java:
-             demangled = cplus_demangle (name, arg_mode | DMGL_JAVA);
-             break;
-           case language_chill:
-             demangled = chill_demangle (name);
-             break;
-           default:
-             demangled = NULL;
-             break;
-           }
+         demangled = language_demangle (language_def (lang), name, arg_mode);
          fputs_filtered (demangled ? demangled : name, stream);
          if (demangled != NULL)
            {
@@ -2256,6 +2342,94 @@ strcmp_iw (const char *string1, const char *string2)
     }
   return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0');
 }
+
+/* This is like strcmp except that it ignores whitespace and treats
+   '(' as the first non-NULL character in terms of ordering.  Like
+   strcmp (and unlike strcmp_iw), it returns negative if STRING1 <
+   STRING2, 0 if STRING2 = STRING2, and positive if STRING1 > STRING2
+   according to that ordering.
+
+   If a list is sorted according to this function and if you want to
+   find names in the list that match some fixed NAME according to
+   strcmp_iw(LIST_ELT, NAME), then the place to start looking is right
+   where this function would put NAME.
+
+   Here are some examples of why using strcmp to sort is a bad idea:
+
+   Whitespace example:
+
+   Say your partial symtab contains: "foo<char *>", "goo".  Then, if
+   we try to do a search for "foo<char*>", strcmp will locate this
+   after "foo<char *>" and before "goo".  Then lookup_partial_symbol
+   will start looking at strings beginning with "goo", and will never
+   see the correct match of "foo<char *>".
+
+   Parenthesis example:
+
+   In practice, this is less like to be an issue, but I'll give it a
+   shot.  Let's assume that '$' is a legitimate character to occur in
+   symbols.  (Which may well even be the case on some systems.)  Then
+   say that the partial symbol table contains "foo$" and "foo(int)".
+   strcmp will put them in this order, since '$' < '('.  Now, if the
+   user searches for "foo", then strcmp will sort "foo" before "foo$".
+   Then lookup_partial_symbol will notice that strcmp_iw("foo$",
+   "foo") is false, so it won't proceed to the actual match of
+   "foo(int)" with "foo".  */
+
+int
+strcmp_iw_ordered (const char *string1, const char *string2)
+{
+  while ((*string1 != '\0') && (*string2 != '\0'))
+    {
+      while (isspace (*string1))
+       {
+         string1++;
+       }
+      while (isspace (*string2))
+       {
+         string2++;
+       }
+      if (*string1 != *string2)
+       {
+         break;
+       }
+      if (*string1 != '\0')
+       {
+         string1++;
+         string2++;
+       }
+    }
+
+  switch (*string1)
+    {
+      /* Characters are non-equal unless they're both '\0'; we want to
+        make sure we get the comparison right according to our
+        comparison in the cases where one of them is '\0' or '('.  */
+    case '\0':
+      if (*string2 == '\0')
+       return 0;
+      else
+       return -1;
+    case '(':
+      if (*string2 == '\0')
+       return 1;
+      else
+       return -1;
+    default:
+      if (*string2 == '(')
+       return 1;
+      else
+       return *string1 - *string2;
+    }
+}
+
+/* A simple comparison function with opposite semantics to strcmp.  */
+
+int
+streq (const char *lhs, const char *rhs)
+{
+  return !strcmp (lhs, rhs);
+}
 \f
 
 /*
@@ -2268,11 +2442,11 @@ int
 subset_compare (char *string_to_compare, char *template_string)
 {
   int match;
-  if (template_string != (char *) NULL && string_to_compare != (char *) NULL &&
-      strlen (string_to_compare) <= strlen (template_string))
-    match = (strncmp (template_string,
-                     string_to_compare,
-                     strlen (string_to_compare)) == 0);
+  if (template_string != (char *) NULL && string_to_compare != (char *) NULL
+      && strlen (string_to_compare) <= strlen (template_string))
+    match =
+      (strncmp
+       (template_string, string_to_compare, strlen (string_to_compare)) == 0);
   else
     match = 0;
   return match;
@@ -2304,7 +2478,7 @@ initialize_utils (void)
                   "Set number of characters gdb thinks are in a line.",
                   &setlist);
   add_show_from_set (c, &showlist);
-  c->function.sfunc = set_width_command;
+  set_cmd_sfunc (c, set_width_command);
 
   add_show_from_set
     (add_set_cmd ("height", class_support,
@@ -2323,15 +2497,13 @@ initialize_utils (void)
   add_show_from_set
     (add_set_cmd ("demangle", class_support, var_boolean,
                  (char *) &demangle,
-            "Set demangling of encoded C++ names when displaying symbols.",
-                 &setprintlist),
-     &showprintlist);
+                 "Set demangling of encoded C++/ObjC names when displaying symbols.",
+                 &setprintlist), &showprintlist);
 
   add_show_from_set
     (add_set_cmd ("pagination", class_support,
                  var_boolean, (char *) &pagination_enabled,
-                 "Set state of pagination.", &setlist),
-     &showlist);
+                 "Set state of pagination.", &setlist), &showlist);
 
   if (xdb_commands)
     {
@@ -2345,15 +2517,13 @@ initialize_utils (void)
     (add_set_cmd ("sevenbit-strings", class_support, var_boolean,
                  (char *) &sevenbit_strings,
                  "Set printing of 8-bit characters in strings as \\nnn.",
-                 &setprintlist),
-     &showprintlist);
+                 &setprintlist), &showprintlist);
 
   add_show_from_set
     (add_set_cmd ("asm-demangle", class_support, var_boolean,
                  (char *) &asm_demangle,
-                 "Set demangling of C++ names in disassembly listings.",
-                 &setprintlist),
-     &showprintlist);
+                 "Set demangling of C++/ObjC names in disassembly listings.",
+                 &setprintlist), &showprintlist);
 }
 
 /* Machine specific function to handle SIGWINCH signal. */
@@ -2361,514 +2531,7 @@ initialize_utils (void)
 #ifdef  SIGWINCH_HANDLER_BODY
 SIGWINCH_HANDLER_BODY
 #endif
-\f
-/* Support for converting target fp numbers into host DOUBLEST format.  */
-
-/* XXX - This code should really be in libiberty/floatformat.c, however
-   configuration issues with libiberty made this very difficult to do in the
-   available time.  */
-
-#include "floatformat.h"
-#include <math.h>              /* ldexp */
-
-/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
-   going to bother with trying to muck around with whether it is defined in
-   a system header, what we do if not, etc.  */
-#define FLOATFORMAT_CHAR_BIT 8
-
-static unsigned long get_field (unsigned char *,
-                               enum floatformat_byteorders,
-                               unsigned int, unsigned int, unsigned int);
-
-/* Extract a field which starts at START and is LEN bytes long.  DATA and
-   TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
-static unsigned long
-get_field (unsigned char *data, enum floatformat_byteorders order,
-          unsigned int total_len, unsigned int start, unsigned int len)
-{
-  unsigned long result;
-  unsigned int cur_byte;
-  int cur_bitshift;
-
-  /* Start at the least significant part of the field.  */
-  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
-    {
-      /* We start counting from the other end (i.e, from the high bytes
-        rather than the low bytes).  As such, we need to be concerned
-        with what happens if bit 0 doesn't start on a byte boundary. 
-        I.e, we need to properly handle the case where total_len is
-        not evenly divisible by 8.  So we compute ``excess'' which
-        represents the number of bits from the end of our starting
-        byte needed to get to bit 0. */
-      int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);
-      cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) 
-                 - ((start + len + excess) / FLOATFORMAT_CHAR_BIT);
-      cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT) 
-                     - FLOATFORMAT_CHAR_BIT;
-    }
-  else
-    {
-      cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
-      cur_bitshift =
-       ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
-    }
-  if (cur_bitshift > -FLOATFORMAT_CHAR_BIT)
-    result = *(data + cur_byte) >> (-cur_bitshift);
-  else
-    result = 0;
-  cur_bitshift += FLOATFORMAT_CHAR_BIT;
-  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
-    ++cur_byte;
-  else
-    --cur_byte;
-
-  /* Move towards the most significant part of the field.  */
-  while (cur_bitshift < len)
-    {
-      result |= (unsigned long)*(data + cur_byte) << cur_bitshift;
-      cur_bitshift += FLOATFORMAT_CHAR_BIT;
-      if (order == floatformat_little || order == floatformat_littlebyte_bigword)
-       ++cur_byte;
-      else
-       --cur_byte;
-    }
-  if (len < sizeof(result) * FLOATFORMAT_CHAR_BIT)
-    /* Mask out bits which are not part of the field */
-    result &= ((1UL << len) - 1);
-  return result;
-}
-
-/* Convert from FMT to a DOUBLEST.
-   FROM is the address of the extended float.
-   Store the DOUBLEST in *TO.  */
-
-void
-floatformat_to_doublest (const struct floatformat *fmt, char *from,
-                        DOUBLEST *to)
-{
-  unsigned char *ufrom = (unsigned char *) from;
-  DOUBLEST dto;
-  long exponent;
-  unsigned long mant;
-  unsigned int mant_bits, mant_off;
-  int mant_bits_left;
-  int special_exponent;                /* It's a NaN, denorm or zero */
-
-  /* If the mantissa bits are not contiguous from one end of the
-     mantissa to the other, we need to make a private copy of the
-     source bytes that is in the right order since the unpacking
-     algorithm assumes that the bits are contiguous.
-
-     Swap the bytes individually rather than accessing them through
-     "long *" since we have no guarantee that they start on a long
-     alignment, and also sizeof(long) for the host could be different
-     than sizeof(long) for the target.  FIXME: Assumes sizeof(long)
-     for the target is 4. */
-
-  if (fmt->byteorder == floatformat_littlebyte_bigword)
-    {
-      static unsigned char *newfrom;
-      unsigned char *swapin, *swapout;
-      int longswaps;
-
-      longswaps = fmt->totalsize / FLOATFORMAT_CHAR_BIT;
-      longswaps >>= 3;
-
-      if (newfrom == NULL)
-       {
-         newfrom = (unsigned char *) xmalloc (fmt->totalsize);
-       }
-      swapout = newfrom;
-      swapin = ufrom;
-      ufrom = newfrom;
-      while (longswaps-- > 0)
-       {
-         /* This is ugly, but efficient */
-         *swapout++ = swapin[4];
-         *swapout++ = swapin[5];
-         *swapout++ = swapin[6];
-         *swapout++ = swapin[7];
-         *swapout++ = swapin[0];
-         *swapout++ = swapin[1];
-         *swapout++ = swapin[2];
-         *swapout++ = swapin[3];
-         swapin += 8;
-       }
-    }
-
-  exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
-                       fmt->exp_start, fmt->exp_len);
-  /* Note that if exponent indicates a NaN, we can't really do anything useful
-     (not knowing if the host has NaN's, or how to build one).  So it will
-     end up as an infinity or something close; that is OK.  */
-
-  mant_bits_left = fmt->man_len;
-  mant_off = fmt->man_start;
-  dto = 0.0;
-
-  special_exponent = exponent == 0 || exponent == fmt->exp_nan;
-
-/* Don't bias NaNs. Use minimum exponent for denorms. For simplicity,
-   we don't check for zero as the exponent doesn't matter. */
-  if (!special_exponent)
-    exponent -= fmt->exp_bias;
-  else if (exponent == 0)
-    exponent = 1 - fmt->exp_bias;
-
-  /* Build the result algebraically.  Might go infinite, underflow, etc;
-     who cares. */
-
-/* If this format uses a hidden bit, explicitly add it in now.  Otherwise,
-   increment the exponent by one to account for the integer bit.  */
-
-  if (!special_exponent)
-    {
-      if (fmt->intbit == floatformat_intbit_no)
-       dto = ldexp (1.0, exponent);
-      else
-       exponent++;
-    }
-
-  while (mant_bits_left > 0)
-    {
-      mant_bits = min (mant_bits_left, 32);
-
-      mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
-                       mant_off, mant_bits);
-
-      dto += ldexp ((double) mant, exponent - mant_bits);
-      exponent -= mant_bits;
-      mant_off += mant_bits;
-      mant_bits_left -= mant_bits;
-    }
-
-  /* Negate it if negative.  */
-  if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
-    dto = -dto;
-  *to = dto;
-}
-\f
-static void put_field (unsigned char *, enum floatformat_byteorders,
-                      unsigned int,
-                      unsigned int, unsigned int, unsigned long);
-
-/* Set a field which starts at START and is LEN bytes long.  DATA and
-   TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
-static void
-put_field (unsigned char *data, enum floatformat_byteorders order,
-          unsigned int total_len, unsigned int start, unsigned int len,
-          unsigned long stuff_to_put)
-{
-  unsigned int cur_byte;
-  int cur_bitshift;
-
-  /* Start at the least significant part of the field.  */
-  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
-    {
-      int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);
-      cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) 
-                 - ((start + len + excess) / FLOATFORMAT_CHAR_BIT);
-      cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT) 
-                     - FLOATFORMAT_CHAR_BIT;
-    }
-  else
-    {
-      cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
-      cur_bitshift =
-       ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
-    }
-  if (cur_bitshift > -FLOATFORMAT_CHAR_BIT)
-    {
-      *(data + cur_byte) &=
-       ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1)
-         << (-cur_bitshift));
-      *(data + cur_byte) |=
-       (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
-    }
-  cur_bitshift += FLOATFORMAT_CHAR_BIT;
-  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
-    ++cur_byte;
-  else
-    --cur_byte;
-
-  /* Move towards the most significant part of the field.  */
-  while (cur_bitshift < len)
-    {
-      if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
-       {
-         /* This is the last byte.  */
-         *(data + cur_byte) &=
-           ~((1 << (len - cur_bitshift)) - 1);
-         *(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
-       }
-      else
-       *(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
-                             & ((1 << FLOATFORMAT_CHAR_BIT) - 1));
-      cur_bitshift += FLOATFORMAT_CHAR_BIT;
-      if (order == floatformat_little || order == floatformat_littlebyte_bigword)
-       ++cur_byte;
-      else
-       --cur_byte;
-    }
-}
-
-#ifdef HAVE_LONG_DOUBLE
-/* Return the fractional part of VALUE, and put the exponent of VALUE in *EPTR.
-   The range of the returned value is >= 0.5 and < 1.0.  This is equivalent to
-   frexp, but operates on the long double data type.  */
-
-static long double ldfrexp (long double value, int *eptr);
-
-static long double
-ldfrexp (long double value, int *eptr)
-{
-  long double tmp;
-  int exp;
-
-  /* Unfortunately, there are no portable functions for extracting the exponent
-     of a long double, so we have to do it iteratively by multiplying or dividing
-     by two until the fraction is between 0.5 and 1.0.  */
-
-  if (value < 0.0l)
-    value = -value;
-
-  tmp = 1.0l;
-  exp = 0;
-
-  if (value >= tmp)            /* Value >= 1.0 */
-    while (value >= tmp)
-      {
-       tmp *= 2.0l;
-       exp++;
-      }
-  else if (value != 0.0l)      /* Value < 1.0  and > 0.0 */
-    {
-      while (value < tmp)
-       {
-         tmp /= 2.0l;
-         exp--;
-       }
-      tmp *= 2.0l;
-      exp++;
-    }
-
-  *eptr = exp;
-  return value / tmp;
-}
-#endif /* HAVE_LONG_DOUBLE */
-
-
-/* The converse: convert the DOUBLEST *FROM to an extended float
-   and store where TO points.  Neither FROM nor TO have any alignment
-   restrictions.  */
-
-void
-floatformat_from_doublest (CONST struct floatformat *fmt, DOUBLEST *from,
-                          char *to)
-{
-  DOUBLEST dfrom;
-  int exponent;
-  DOUBLEST mant;
-  unsigned int mant_bits, mant_off;
-  int mant_bits_left;
-  unsigned char *uto = (unsigned char *) to;
-
-  memcpy (&dfrom, from, sizeof (dfrom));
-  memset (uto, 0, (fmt->totalsize + FLOATFORMAT_CHAR_BIT - 1) 
-                    / FLOATFORMAT_CHAR_BIT);
-  if (dfrom == 0)
-    return;                    /* Result is zero */
-  if (dfrom != dfrom)          /* Result is NaN */
-    {
-      /* From is NaN */
-      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
-                fmt->exp_len, fmt->exp_nan);
-      /* Be sure it's not infinity, but NaN value is irrel */
-      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
-                32, 1);
-      return;
-    }
-
-  /* If negative, set the sign bit.  */
-  if (dfrom < 0)
-    {
-      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
-      dfrom = -dfrom;
-    }
-
-  if (dfrom + dfrom == dfrom && dfrom != 0.0)  /* Result is Infinity */
-    {
-      /* Infinity exponent is same as NaN's.  */
-      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
-                fmt->exp_len, fmt->exp_nan);
-      /* Infinity mantissa is all zeroes.  */
-      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
-                fmt->man_len, 0);
-      return;
-    }
-
-#ifdef HAVE_LONG_DOUBLE
-  mant = ldfrexp (dfrom, &exponent);
-#else
-  mant = frexp (dfrom, &exponent);
-#endif
-
-  put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, fmt->exp_len,
-            exponent + fmt->exp_bias - 1);
-
-  mant_bits_left = fmt->man_len;
-  mant_off = fmt->man_start;
-  while (mant_bits_left > 0)
-    {
-      unsigned long mant_long;
-      mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
-
-      mant *= 4294967296.0;
-      mant_long = ((unsigned long) mant) & 0xffffffffL;
-      mant -= mant_long;
-
-      /* If the integer bit is implicit, then we need to discard it.
-         If we are discarding a zero, we should be (but are not) creating
-         a denormalized number which means adjusting the exponent
-         (I think).  */
-      if (mant_bits_left == fmt->man_len
-         && fmt->intbit == floatformat_intbit_no)
-       {
-         mant_long <<= 1;
-         mant_long &= 0xffffffffL;
-         mant_bits -= 1;
-       }
-
-      if (mant_bits < 32)
-       {
-         /* The bits we want are in the most significant MANT_BITS bits of
-            mant_long.  Move them to the least significant.  */
-         mant_long >>= 32 - mant_bits;
-       }
-
-      put_field (uto, fmt->byteorder, fmt->totalsize,
-                mant_off, mant_bits, mant_long);
-      mant_off += mant_bits;
-      mant_bits_left -= mant_bits;
-    }
-  if (fmt->byteorder == floatformat_littlebyte_bigword)
-    {
-      int count;
-      unsigned char *swaplow = uto;
-      unsigned char *swaphigh = uto + 4;
-      unsigned char tmp;
-
-      for (count = 0; count < 4; count++)
-       {
-         tmp = *swaplow;
-         *swaplow++ = *swaphigh;
-         *swaphigh++ = tmp;
-       }
-    }
-}
-
-/* Check if VAL (which is assumed to be a floating point number whose
-   format is described by FMT) is negative.  */
-
-int
-floatformat_is_negative (const struct floatformat *fmt, char *val)
-{
-  unsigned char *uval = (unsigned char *) val;
-
-  return get_field (uval, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1);
-}
-
-/* Check if VAL is "not a number" (NaN) for FMT.  */
-
-int
-floatformat_is_nan (const struct floatformat *fmt, char *val)
-{
-  unsigned char *uval = (unsigned char *) val;
-  long exponent;
-  unsigned long mant;
-  unsigned int mant_bits, mant_off;
-  int mant_bits_left;
-
-  if (! fmt->exp_nan)
-    return 0;
-
-  exponent = get_field (uval, fmt->byteorder, fmt->totalsize,
-                       fmt->exp_start, fmt->exp_len);
-
-  if (exponent != fmt->exp_nan)
-    return 0;
-
-  mant_bits_left = fmt->man_len;
-  mant_off = fmt->man_start;
-
-  while (mant_bits_left > 0)
-    {
-      mant_bits = min (mant_bits_left, 32);
-
-      mant = get_field (uval, fmt->byteorder, fmt->totalsize,
-                       mant_off, mant_bits);
-
-      /* If there is an explicit integer bit, mask it off.  */
-      if (mant_off == fmt->man_start
-         && fmt->intbit == floatformat_intbit_yes)
-       mant &= ~(1 << (mant_bits - 1));
-
-      if (mant)
-       return 1;
-
-      mant_off += mant_bits;
-      mant_bits_left -= mant_bits;
-    }
-
-  return 0;
-}
-
-/* Convert the mantissa of VAL (which is assumed to be a floating
-   point number whose format is described by FMT) into a hexadecimal
-   and store it in a static string.  Return a pointer to that string.  */
-
-char *
-floatformat_mantissa (const struct floatformat *fmt, char *val)
-{
-  unsigned char *uval = (unsigned char *) val;
-  unsigned long mant;
-  unsigned int mant_bits, mant_off;
-  int mant_bits_left;
-  static char res[50];
-  char buf[9];
-
-  /* Make sure we have enough room to store the mantissa.  */
-  gdb_assert (sizeof res > ((fmt->man_len + 7) / 8) * 2);
-
-  mant_off = fmt->man_start;
-  mant_bits_left = fmt->man_len;
-  mant_bits = (mant_bits_left % 32) > 0 ? mant_bits_left % 32 : 32;
-
-  mant = get_field (uval, fmt->byteorder, fmt->totalsize,
-                   mant_off, mant_bits);
-
-  sprintf (res, "%lx", mant);
-
-  mant_off += mant_bits;
-  mant_bits_left -= mant_bits;
-  
-  while (mant_bits_left > 0)
-    {
-      mant = get_field (uval, fmt->byteorder, fmt->totalsize,
-                       mant_off, 32);
-
-      sprintf (buf, "%08lx", mant);
-      strcat (res, buf);
-
-      mant_off += 32;
-      mant_bits_left -= 32;
-    }
-
-  return res;
-}
-
 /* print routines to handle variable size regs, etc. */
-
 /* temporary storage using circular buffer */
 #define NUMCELLS 16
 #define CELLSIZE 32
@@ -2917,19 +2580,17 @@ decimal2str (char *paddr_str, char *sign, ULONGEST addr)
   switch (i)
     {
     case 1:
-      sprintf (paddr_str, "%s%lu",
-              sign, temp[0]);
+      sprintf (paddr_str, "%s%lu", sign, temp[0]);
       break;
     case 2:
-      sprintf (paddr_str, "%s%lu%09lu",
-              sign, temp[1], temp[0]);
+      sprintf (paddr_str, "%s%lu%09lu", sign, temp[1], temp[0]);
       break;
     case 3:
-      sprintf (paddr_str, "%s%lu%09lu%09lu",
-              sign, temp[2], temp[1], temp[0]);
+      sprintf (paddr_str, "%s%lu%09lu%09lu", sign, temp[2], temp[1], temp[0]);
       break;
     default:
-      internal_error (__FILE__, __LINE__, "failed internal consistency check");
+      internal_error (__FILE__, __LINE__,
+                     "failed internal consistency check");
     }
 }
 
@@ -2958,22 +2619,25 @@ static int thirty_two = 32;
 char *
 phex (ULONGEST l, int sizeof_l)
 {
-  char *str = get_cell ();
+  char *str;
   switch (sizeof_l)
     {
     case 8:
+      str = get_cell ();
       sprintf (str, "%08lx%08lx",
               (unsigned long) (l >> thirty_two),
               (unsigned long) (l & 0xffffffff));
       break;
     case 4:
+      str = get_cell ();
       sprintf (str, "%08lx", (unsigned long) l);
       break;
     case 2:
+      str = get_cell ();
       sprintf (str, "%04x", (unsigned short) (l & 0xffff));
       break;
     default:
-      phex (l, sizeof (l));
+      str = phex (l, sizeof (l));
       break;
     }
   return str;
@@ -2982,51 +2646,273 @@ phex (ULONGEST l, int sizeof_l)
 char *
 phex_nz (ULONGEST l, int sizeof_l)
 {
-  char *str = get_cell ();
+  char *str;
   switch (sizeof_l)
     {
     case 8:
       {
        unsigned long high = (unsigned long) (l >> thirty_two);
+       str = get_cell ();
        if (high == 0)
          sprintf (str, "%lx", (unsigned long) (l & 0xffffffff));
        else
-         sprintf (str, "%lx%08lx",
-                  high, (unsigned long) (l & 0xffffffff));
+         sprintf (str, "%lx%08lx", high, (unsigned long) (l & 0xffffffff));
        break;
       }
     case 4:
+      str = get_cell ();
       sprintf (str, "%lx", (unsigned long) l);
       break;
     case 2:
+      str = get_cell ();
       sprintf (str, "%x", (unsigned short) (l & 0xffff));
       break;
     default:
-      phex_nz (l, sizeof (l));
+      str = phex_nz (l, sizeof (l));
       break;
     }
   return str;
 }
 
 
-/* Convert to / from the hosts pointer to GDB's internal CORE_ADDR
-   using the target's conversion routines. */
+/* Convert a CORE_ADDR into a string.  */
+const char *
+core_addr_to_string (const CORE_ADDR addr)
+{
+  char *str = get_cell ();
+  strcpy (str, "0x");
+  strcat (str, phex (addr, sizeof (addr)));
+  return str;
+}
+
+const char *
+core_addr_to_string_nz (const CORE_ADDR addr)
+{
+  char *str = get_cell ();
+  strcpy (str, "0x");
+  strcat (str, phex_nz (addr, sizeof (addr)));
+  return str;
+}
+
+/* Convert a string back into a CORE_ADDR.  */
 CORE_ADDR
-host_pointer_to_address (void *ptr)
+string_to_core_addr (const char *my_string)
 {
-  if (sizeof (ptr) != TYPE_LENGTH (builtin_type_ptr))
-    internal_error (__FILE__, __LINE__,
-                   "core_addr_to_void_ptr: bad cast");
-  return POINTER_TO_ADDRESS (builtin_type_ptr, &ptr);
+  CORE_ADDR addr = 0;
+  if (my_string[0] == '0' && tolower (my_string[1]) == 'x')
+    {
+      /* Assume that it is in decimal.  */
+      int i;
+      for (i = 2; my_string[i] != '\0'; i++)
+       {
+         if (isdigit (my_string[i]))
+           addr = (my_string[i] - '0') + (addr * 16);
+         else if (isxdigit (my_string[i]))
+           addr = (tolower (my_string[i]) - 'a' + 0xa) + (addr * 16);
+         else
+           internal_error (__FILE__, __LINE__, "invalid hex");
+       }
+    }
+  else
+    {
+      /* Assume that it is in decimal.  */
+      int i;
+      for (i = 0; my_string[i] != '\0'; i++)
+       {
+         if (isdigit (my_string[i]))
+           addr = (my_string[i] - '0') + (addr * 10);
+         else
+           internal_error (__FILE__, __LINE__, "invalid decimal");
+       }
+    }
+  return addr;
 }
 
-void *
-address_to_host_pointer (CORE_ADDR addr)
+char *
+gdb_realpath (const char *filename)
+{
+  /* Method 1: The system has a compile time upper bound on a filename
+     path.  Use that and realpath() to canonicalize the name.  This is
+     the most common case.  Note that, if there isn't a compile time
+     upper bound, you want to avoid realpath() at all costs.  */
+#if defined(HAVE_REALPATH)
+  {
+# if defined (PATH_MAX)
+    char buf[PATH_MAX];
+#  define USE_REALPATH
+# elif defined (MAXPATHLEN)
+    char buf[MAXPATHLEN];
+#  define USE_REALPATH
+# endif
+# if defined (USE_REALPATH)
+    const char *rp = realpath (filename, buf);
+    if (rp == NULL)
+      rp = filename;
+    return xstrdup (rp);
+# endif
+  }
+#endif /* HAVE_REALPATH */
+
+  /* Method 2: The host system (i.e., GNU) has the function
+     canonicalize_file_name() which malloc's a chunk of memory and
+     returns that, use that.  */
+#if defined(HAVE_CANONICALIZE_FILE_NAME)
+  {
+    char *rp = canonicalize_file_name (filename);
+    if (rp == NULL)
+      return xstrdup (filename);
+    else
+      return rp;
+  }
+#endif
+
+  /* FIXME: cagney/2002-11-13:
+
+     Method 2a: Use realpath() with a NULL buffer.  Some systems, due
+     to the problems described in in method 3, have modified their
+     realpath() implementation so that it will allocate a buffer when
+     NULL is passed in.  Before this can be used, though, some sort of
+     configure time test would need to be added.  Otherwize the code
+     will likely core dump.  */
+
+  /* Method 3: Now we're getting desperate!  The system doesn't have a
+     compile time buffer size and no alternative function.  Query the
+     OS, using pathconf(), for the buffer limit.  Care is needed
+     though, some systems do not limit PATH_MAX (return -1 for
+     pathconf()) making it impossible to pass a correctly sized buffer
+     to realpath() (it could always overflow).  On those systems, we
+     skip this.  */
+#if defined (HAVE_REALPATH) && defined (HAVE_UNISTD_H) && defined(HAVE_ALLOCA)
+  {
+    /* Find out the max path size.  */
+    long path_max = pathconf ("/", _PC_PATH_MAX);
+    if (path_max > 0)
+      {
+       /* PATH_MAX is bounded.  */
+       char *buf = alloca (path_max);
+       char *rp = realpath (filename, buf);
+       return xstrdup (rp ? rp : filename);
+      }
+  }
+#endif
+
+  /* This system is a lost cause, just dup the buffer.  */
+  return xstrdup (filename);
+}
+
+/* Return a copy of FILENAME, with its directory prefix canonicalized
+   by gdb_realpath.  */
+
+char *
+xfullpath (const char *filename)
 {
-  void *ptr;
-  if (sizeof (ptr) != TYPE_LENGTH (builtin_type_ptr))
-    internal_error (__FILE__, __LINE__,
-                   "core_addr_to_void_ptr: bad cast");
-  ADDRESS_TO_POINTER (builtin_type_ptr, &ptr, addr);
-  return ptr;
+  const char *base_name = lbasename (filename);
+  char *dir_name;
+  char *real_path;
+  char *result;
+
+  /* Extract the basename of filename, and return immediately 
+     a copy of filename if it does not contain any directory prefix. */
+  if (base_name == filename)
+    return xstrdup (filename);
+
+  dir_name = alloca ((size_t) (base_name - filename + 2));
+  /* Allocate enough space to store the dir_name + plus one extra
+     character sometimes needed under Windows (see below), and
+     then the closing \000 character */
+  strncpy (dir_name, filename, base_name - filename);
+  dir_name[base_name - filename] = '\000';
+
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  /* We need to be careful when filename is of the form 'd:foo', which
+     is equivalent of d:./foo, which is totally different from d:/foo.  */
+  if (strlen (dir_name) == 2 && isalpha (dir_name[0]) && dir_name[1] == ':')
+    {
+      dir_name[2] = '.';
+      dir_name[3] = '\000';
+    }
+#endif
+
+  /* Canonicalize the directory prefix, and build the resulting
+     filename. If the dirname realpath already contains an ending
+     directory separator, avoid doubling it.  */
+  real_path = gdb_realpath (dir_name);
+  if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1]))
+    result = concat (real_path, base_name, NULL);
+  else
+    result = concat (real_path, SLASH_STRING, base_name, NULL);
+
+  xfree (real_path);
+  return result;
+}
+
+
+/* This is the 32-bit CRC function used by the GNU separate debug
+   facility.  An executable may contain a section named
+   .gnu_debuglink, which holds the name of a separate executable file
+   containing its debug info, and a checksum of that file's contents,
+   computed using this function.  */
+unsigned long
+gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len)
+{
+  static const unsigned long crc32_table[256] = {
+    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+    0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+    0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+    0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+    0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+    0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+    0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+    0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+    0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+    0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+    0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+    0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+    0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+    0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+    0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+    0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+    0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+    0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+    0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+    0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+    0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+    0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+    0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+    0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+    0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+    0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+    0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+    0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+    0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+    0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+    0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+    0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+    0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+    0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+    0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+    0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+    0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+    0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+    0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+    0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+    0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+    0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+    0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+    0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+    0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+    0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+    0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+    0x2d02ef8d
+  };
+  unsigned char *end;
+
+  crc = ~crc & 0xffffffff;
+  for (end = buf + len; buf < end; ++buf)
+    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+  return ~crc & 0xffffffff;;
 }
This page took 0.049231 seconds and 4 git commands to generate.