2011-03-31 Thiago Jung Bauermann <bauerman@br.ibm.com>
[deliverable/binutils-gdb.git] / gdb / utils.c
index d9953a07cbf51c0eaeffa01e1ecb1aa828e845de..496c9dca29c416aa7eb8c407f3d3a7ffabf5eeed 100644 (file)
@@ -1,8 +1,8 @@
 /* General utility routines for GDB, the GNU debugger.
 
    Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-   Free Software Foundation, Inc.
+   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+   2009, 2010, 2011 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "gdb_string.h"
 #include "event-top.h"
 #include "exceptions.h"
+#include "gdbthread.h"
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif /* HAVE_SYS_RESOURCE_H */
 
 #ifdef TUI
 #include "tui/tui.h"           /* For tui_get_command_dimension.   */
@@ -34,7 +38,7 @@
 #include <pc.h>
 #endif
 
-/* SunOS's curses.h has a '#define reg register' in it.  Thank you Sun. */
+/* SunOS's curses.h has a '#define reg register' in it.  Thank you Sun.  */
 #ifdef reg
 #undef reg
 #endif
@@ -54,6 +58,7 @@
 #include "gdb_obstack.h"
 #include "gdbcore.h"
 #include "top.h"
+#include "main.h"
 
 #include "inferior.h"          /* for signed_pointer_to_address */
 
 #include <sys/time.h>
 #include <time.h>
 
+#include "gdb_usleep.h"
+#include "interps.h"
+#include "gdb_regex.h"
+
 #if !HAVE_DECL_MALLOC
-extern PTR malloc ();          /* OK: PTR */
+extern PTR malloc ();          /* ARI: PTR */
 #endif
 #if !HAVE_DECL_REALLOC
-extern PTR realloc ();         /* OK: PTR */
+extern PTR realloc ();         /* ARI: PTR */
 #endif
 #if !HAVE_DECL_FREE
 extern void free ();
@@ -84,7 +93,7 @@ void (*deprecated_error_begin_hook) (void);
 /* Prototypes for local functions */
 
 static void vfprintf_maybe_filtered (struct ui_file *, const char *,
-                                    va_list, int) ATTR_FORMAT (printf, 2, 0);
+                                    va_list, int) ATTRIBUTE_PRINTF (2, 0);
 
 static void fputs_maybe_filtered (const char *, struct ui_file *, int);
 
@@ -105,14 +114,7 @@ static int debug_timestamp = 0;
 static struct cleanup *cleanup_chain;  /* cleaned up after a failed command */
 static struct cleanup *final_cleanup_chain;    /* cleaned up when gdb exits */
 
-/* Pointer to what is left to do for an execution command after the
-   target stops. Used only in asynchronous mode, by targets that
-   support async execution.  The finish and until commands use it. So
-   does the target extended-remote command. */
-struct continuation *cmd_continuation;
-struct continuation *intermediate_continuation;
-
-/* Nonzero if we have job control. */
+/* Nonzero if we have job control.  */
 
 int job_control;
 
@@ -141,8 +143,9 @@ static void
 show_demangle (struct ui_file *file, int from_tty,
               struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("\
-Demangling of encoded C++/ObjC names when displaying symbols is %s.\n"),
+  fprintf_filtered (file,
+                   _("Demangling of encoded C++/ObjC names "
+                     "when displaying symbols is %s.\n"),
                    value);
 }
 
@@ -155,8 +158,9 @@ static void
 show_asm_demangle (struct ui_file *file, int from_tty,
                   struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("\
-Demangling of C++/ObjC names in disassembly listings is %s.\n"),
+  fprintf_filtered (file,
+                   _("Demangling of C++/ObjC names in "
+                     "disassembly listings is %s.\n"),
                    value);
 }
 
@@ -169,8 +173,8 @@ static void
 show_sevenbit_strings (struct ui_file *file, int from_tty,
                       struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("\
-Printing of 8-bit characters in strings as \\nnn is %s.\n"),
+  fprintf_filtered (file, _("Printing of 8-bit characters "
+                           "in strings as \\nnn is %s.\n"),
                    value);
 }
 
@@ -207,6 +211,14 @@ make_cleanup (make_cleanup_ftype *function, void *arg)
   return make_my_cleanup (&cleanup_chain, function, arg);
 }
 
+struct cleanup *
+make_cleanup_dtor (make_cleanup_ftype *function, void *arg,
+                  void (*dtor) (void *))
+{
+  return make_my_cleanup2 (&cleanup_chain,
+                          function, arg, dtor);
+}
+
 struct cleanup *
 make_final_cleanup (make_cleanup_ftype *function, void *arg)
 {
@@ -241,16 +253,53 @@ static void
 do_close_cleanup (void *arg)
 {
   int *fd = arg;
+
   close (*fd);
-  xfree (fd);
 }
 
 struct cleanup *
 make_cleanup_close (int fd)
 {
   int *saved_fd = xmalloc (sizeof (fd));
+
   *saved_fd = fd;
-  return make_cleanup (do_close_cleanup, saved_fd);
+  return make_cleanup_dtor (do_close_cleanup, saved_fd, xfree);
+}
+
+/* Helper function which does the work for make_cleanup_fclose.  */
+
+static void
+do_fclose_cleanup (void *arg)
+{
+  FILE *file = arg;
+
+  fclose (file);
+}
+
+/* Return a new cleanup that closes FILE.  */
+
+struct cleanup *
+make_cleanup_fclose (FILE *file)
+{
+  return make_cleanup (do_fclose_cleanup, file);
+}
+
+/* Helper function which does the work for make_cleanup_obstack_free.  */
+
+static void
+do_obstack_free (void *arg)
+{
+  struct obstack *ob = arg;
+
+  obstack_free (ob, NULL);
+}
+
+/* Return a new cleanup that frees OBSTACK.  */
+
+struct cleanup *
+make_cleanup_obstack_free (struct obstack *obstack)
+{
+  return make_cleanup (do_obstack_free, obstack);
 }
 
 static void
@@ -265,6 +314,26 @@ make_cleanup_ui_file_delete (struct ui_file *arg)
   return make_my_cleanup (&cleanup_chain, do_ui_file_delete, arg);
 }
 
+/* Helper function for make_cleanup_ui_out_redirect_pop.  */
+
+static void
+do_ui_out_redirect_pop (void *arg)
+{
+  struct ui_out *uiout = arg;
+
+  if (ui_out_redirect (uiout, NULL) < 0)
+    warning (_("Cannot restore redirection of the current output protocol"));
+}
+
+/* Return a new cleanup that pops the last redirection by ui_out_redirect
+   with NULL parameter.  */
+
+struct cleanup *
+make_cleanup_ui_out_redirect_pop (struct ui_out *uiout)
+{
+  return make_my_cleanup (&cleanup_chain, do_ui_out_redirect_pop, uiout);
+}
+
 static void
 do_free_section_addr_info (void *arg)
 {
@@ -277,10 +346,94 @@ make_cleanup_free_section_addr_info (struct section_addr_info *addrs)
   return make_my_cleanup (&cleanup_chain, do_free_section_addr_info, addrs);
 }
 
+struct restore_integer_closure
+{
+  int *variable;
+  int value;
+};
+
+static void
+restore_integer (void *p)
+{
+  struct restore_integer_closure *closure = p;
+
+  *(closure->variable) = closure->value;
+}
+
+/* Remember the current value of *VARIABLE and make it restored when
+   the cleanup is run.  */
 
 struct cleanup *
-make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
-                void *arg)
+make_cleanup_restore_integer (int *variable)
+{
+  struct restore_integer_closure *c =
+    xmalloc (sizeof (struct restore_integer_closure));
+
+  c->variable = variable;
+  c->value = *variable;
+
+  return make_my_cleanup2 (&cleanup_chain, restore_integer, (void *)c,
+                          xfree);
+}
+
+/* Remember the current value of *VARIABLE and make it restored when
+   the cleanup is run.  */
+
+struct cleanup *
+make_cleanup_restore_uinteger (unsigned int *variable)
+{
+  return make_cleanup_restore_integer ((int *) variable);
+}
+
+/* Helper for make_cleanup_unpush_target.  */
+
+static void
+do_unpush_target (void *arg)
+{
+  struct target_ops *ops = arg;
+
+  unpush_target (ops);
+}
+
+/* Return a new cleanup that unpushes OPS.  */
+
+struct cleanup *
+make_cleanup_unpush_target (struct target_ops *ops)
+{
+  return make_my_cleanup (&cleanup_chain, do_unpush_target, ops);
+}
+
+struct restore_ui_file_closure
+{
+  struct ui_file **variable;
+  struct ui_file *value;
+};
+
+static void
+do_restore_ui_file (void *p)
+{
+  struct restore_ui_file_closure *closure = p;
+
+  *(closure->variable) = closure->value;
+}
+
+/* Remember the current value of *VARIABLE and make it restored when
+   the cleanup is run.  */
+
+struct cleanup *
+make_cleanup_restore_ui_file (struct ui_file **variable)
+{
+  struct restore_ui_file_closure *c = XNEW (struct restore_ui_file_closure);
+
+  c->variable = variable;
+  c->value = *variable;
+
+  return make_cleanup_dtor (do_restore_ui_file, (void *) c, xfree);
+}
+
+struct cleanup *
+make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function,
+                 void *arg,  void (*free_arg) (void *))
 {
   struct cleanup *new
     = (struct cleanup *) xmalloc (sizeof (struct cleanup));
@@ -288,12 +441,20 @@ make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
 
   new->next = *pmy_chain;
   new->function = function;
+  new->free_arg = free_arg;
   new->arg = arg;
   *pmy_chain = new;
 
   return old_chain;
 }
 
+struct cleanup *
+make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
+                void *arg)
+{
+  return make_my_cleanup2 (pmy_chain, function, arg, NULL);
+}
+
 /* Discard cleanups and do the actions they describe
    until we get back to the point OLD_CHAIN in the cleanup_chain.  */
 
@@ -314,10 +475,13 @@ do_my_cleanups (struct cleanup **pmy_chain,
                struct cleanup *old_chain)
 {
   struct cleanup *ptr;
+
   while ((ptr = *pmy_chain) != old_chain)
     {
-      *pmy_chain = ptr->next;  /* Do this first incase recursion */
+      *pmy_chain = ptr->next;  /* Do this first in case of recursion.  */
       (*ptr->function) (ptr->arg);
+      if (ptr->free_arg)
+       (*ptr->free_arg) (ptr->arg);
       xfree (ptr);
     }
 }
@@ -342,9 +506,12 @@ discard_my_cleanups (struct cleanup **pmy_chain,
                     struct cleanup *old_chain)
 {
   struct cleanup *ptr;
+
   while ((ptr = *pmy_chain) != old_chain)
     {
       *pmy_chain = ptr->next;
+      if (ptr->free_arg)
+       (*ptr->free_arg) (ptr->arg);
       xfree (ptr);
     }
 }
@@ -402,6 +569,7 @@ void
 free_current_contents (void *ptr)
 {
   void **location = ptr;
+
   if (location == NULL)
     internal_error (__FILE__, __LINE__,
                    _("free_current_contents: NULL pointer"));
@@ -417,137 +585,367 @@ free_current_contents (void *ptr)
    use the cleanup chain for handling normal cleanups as well as dealing
    with cleanups that need to be done as a result of a call to error().
    In such cases, we may not be certain where the first cleanup is, unless
-   we have a do-nothing one to always use as the base. */
+   we have a do-nothing one to always use as the base.  */
 
 void
 null_cleanup (void *arg)
 {
 }
 
-/* Add a continuation to the continuation list, the global list
-   cmd_continuation. The new continuation will be added at the front.*/
+/* If nonzero, display time usage both at startup and for each command.  */
+
+static int display_time;
+
+/* If nonzero, display space usage both at startup and for each command.  */
+
+static int display_space;
+
+/* Records a run time and space usage to be used as a base for
+   reporting elapsed time or change in space.  In addition,
+   the msg_type field indicates whether the saved time is from the
+   beginning of GDB execution (0) or the beginning of an individual 
+   command execution (1).  */
+struct cmd_stats 
+{
+  int msg_type;
+  long start_time;
+  long start_space;
+};
+
+/* Set whether to display time statistics to NEW_VALUE (non-zero 
+   means true).  */
 void
-add_continuation (void (*continuation_hook) (struct continuation_arg *, int),
-                 struct continuation_arg *arg_list)
+set_display_time (int new_value)
 {
-  struct continuation *continuation_ptr;
+  display_time = new_value;
+}
 
-  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;
-  cmd_continuation = continuation_ptr;
+/* Set whether to display space statistics to NEW_VALUE (non-zero
+   means true).  */
+void
+set_display_space (int new_value)
+{
+  display_space = new_value;
 }
 
-/* Walk down the cmd_continuation list, and execute all the
-   continuations. There is a problem though. In some cases new
-   continuations may be added while we are in the middle of this
-   loop. If this happens they will be added in the front, and done
-   before we have a chance of exhausting those that were already
-   there. We need to then save the beginning of the list in a pointer
-   and do the continuations from there on, instead of using the
-   global beginning of list as our iteration pointer.  */
+/* As indicated by display_time and display_space, report GDB's elapsed time
+   and space usage from the base time and space provided in ARG, which
+   must be a pointer to a struct cmd_stat.  This function is intended
+   to be called as a cleanup.  */
+static void
+report_command_stats (void *arg)
+{
+  struct cmd_stats *start_stats = (struct cmd_stats *) arg;
+  int msg_type = start_stats->msg_type;
+
+  if (display_time)
+    {
+      long cmd_time = get_run_time () - start_stats->start_time;
+
+      printf_unfiltered (msg_type == 0
+                        ? _("Startup time: %ld.%06ld\n")
+                        : _("Command execution time: %ld.%06ld\n"),
+                        cmd_time / 1000000, cmd_time % 1000000);
+    }
+
+  if (display_space)
+    {
+#ifdef HAVE_SBRK
+      char *lim = (char *) sbrk (0);
+
+      long space_now = lim - lim_at_start;
+      long space_diff = space_now - start_stats->start_space;
+
+      printf_unfiltered (msg_type == 0
+                        ? _("Space used: %ld (%c%ld during startup)\n")
+                        : _("Space used: %ld (%c%ld for this command)\n"),
+                        space_now,
+                        (space_diff >= 0 ? '+' : '-'),
+                        space_diff);
+#endif
+    }
+}
+
+/* Create a cleanup that reports time and space used since its
+   creation.  Precise messages depend on MSG_TYPE:
+      0:  Initial time/space
+      1:  Individual command time/space.  */
+struct cleanup *
+make_command_stats_cleanup (int msg_type)
+{
+  struct cmd_stats *new_stat = XMALLOC (struct cmd_stats);
+  
+#ifdef HAVE_SBRK
+  char *lim = (char *) sbrk (0);
+  new_stat->start_space = lim - lim_at_start;
+#endif
+
+  new_stat->msg_type = msg_type;
+  new_stat->start_time = get_run_time ();
+
+  return make_cleanup_dtor (report_command_stats, new_stat, xfree);
+}
+
+/* Continuations are implemented as cleanups internally.  Inherit from
+   cleanups.  */
+struct continuation
+{
+  struct cleanup base;
+};
+
+/* Add a continuation to the continuation list of THREAD.  The new
+   continuation will be added at the front.  */
+void
+add_continuation (struct thread_info *thread,
+                 void (*continuation_hook) (void *), void *args,
+                 void (*continuation_free_args) (void *))
+{
+  struct cleanup *as_cleanup = &thread->continuations->base;
+  make_cleanup_ftype *continuation_hook_fn = continuation_hook;
+
+  make_my_cleanup2 (&as_cleanup,
+                   continuation_hook_fn,
+                   args,
+                   continuation_free_args);
+
+  thread->continuations = (struct continuation *) as_cleanup;
+}
+
+/* Add a continuation to the continuation list of INFERIOR.  The new
+   continuation will be added at the front.  */
+
+void
+add_inferior_continuation (void (*continuation_hook) (void *), void *args,
+                          void (*continuation_free_args) (void *))
+{
+  struct inferior *inf = current_inferior ();
+  struct cleanup *as_cleanup = &inf->continuations->base;
+  make_cleanup_ftype *continuation_hook_fn = continuation_hook;
+
+  make_my_cleanup2 (&as_cleanup,
+                   continuation_hook_fn,
+                   args,
+                   continuation_free_args);
+
+  inf->continuations = (struct continuation *) as_cleanup;
+}
+
+/* Do all continuations of the current inferior.  */
+
 void
-do_all_continuations (int error)
+do_all_inferior_continuations (void)
 {
-  struct continuation *continuation_ptr;
-  struct continuation *saved_continuation;
+  struct cleanup *as_cleanup;
+  struct inferior *inf = current_inferior ();
+
+  if (inf->continuations == NULL)
+    return;
 
   /* Copy the list header into another pointer, and set the global
      list header to null, so that the global list can change as a side
-     effect of invoking the continuations and the processing of
-     the preexisting continuations will not be affected. */
-  continuation_ptr = cmd_continuation;
-  cmd_continuation = NULL;
+     effect of invoking the continuations and the processing of the
+     preexisting continuations will not be affected.  */
+
+  as_cleanup = &inf->continuations->base;
+  inf->continuations = NULL;
 
   /* Work now on the list we have set aside.  */
-  while (continuation_ptr)
-    {
-      (continuation_ptr->continuation_hook) (continuation_ptr->arg_list, error);
-      saved_continuation = continuation_ptr;
-      continuation_ptr = continuation_ptr->next;
-      xfree (saved_continuation);
-    }
+  do_my_cleanups (&as_cleanup, NULL);
 }
 
-/* Walk down the cmd_continuation list, and get rid of all the
-   continuations. */
+/* Get rid of all the inferior-wide continuations of INF.  */
+
 void
-discard_all_continuations (void)
+discard_all_inferior_continuations (struct inferior *inf)
 {
-  struct continuation *continuation_ptr;
+  struct cleanup *continuation_ptr = &inf->continuations->base;
 
-  while (cmd_continuation)
-    {
-      continuation_ptr = cmd_continuation;
-      cmd_continuation = continuation_ptr->next;
-      xfree (continuation_ptr);
-    }
+  discard_my_cleanups (&continuation_ptr, NULL);
+  inf->continuations = NULL;
 }
 
-/* Add a continuation to the continuation list, the global list
-   intermediate_continuation.  The new continuation will be added at
-   the front.  */
+static void
+restore_thread_cleanup (void *arg)
+{
+  ptid_t *ptid_p = arg;
+
+  switch_to_thread (*ptid_p);
+}
+
+/* Walk down the continuation list of PTID, and execute all the
+   continuations.  There is a problem though.  In some cases new
+   continuations may be added while we are in the middle of this loop.
+   If this happens they will be added in the front, and done before we
+   have a chance of exhausting those that were already there.  We need
+   to then save the beginning of the list in a pointer and do the
+   continuations from there on, instead of using the global beginning
+   of list as our iteration pointer.  */
+static void
+do_all_continuations_ptid (ptid_t ptid,
+                          struct continuation **continuations_p)
+{
+  struct cleanup *old_chain;
+  ptid_t current_thread;
+  struct cleanup *as_cleanup;
+
+  if (*continuations_p == NULL)
+    return;
+
+  current_thread = inferior_ptid;
+
+  /* Restore selected thread on exit.  Don't try to restore the frame
+     as well, because:
+
+    - When running continuations, the selected frame is always #0.
+
+    - The continuations may trigger symbol file loads, which may
+      change the frame layout (frame ids change), which would trigger
+      a warning if we used make_cleanup_restore_current_thread.  */
+
+  old_chain = make_cleanup (restore_thread_cleanup, &current_thread);
+
+  /* Let the continuation see this thread as selected.  */
+  switch_to_thread (ptid);
+
+  /* Copy the list header into another pointer, and set the global
+     list header to null, so that the global list can change as a side
+     effect of invoking the continuations and the processing of the
+     preexisting continuations will not be affected.  */
+
+  as_cleanup = &(*continuations_p)->base;
+  *continuations_p = NULL;
+
+  /* Work now on the list we have set aside.  */
+  do_my_cleanups (&as_cleanup, NULL);
+
+  do_cleanups (old_chain);
+}
+
+/* Callback for iterate over threads.  */
+static int
+do_all_continuations_thread_callback (struct thread_info *thread, void *data)
+{
+  do_all_continuations_ptid (thread->ptid, &thread->continuations);
+  return 0;
+}
+
+/* Do all continuations of thread THREAD.  */
 void
-add_intermediate_continuation (void (*continuation_hook)
-                              (struct continuation_arg *, int),
-                              struct continuation_arg *arg_list)
+do_all_continuations_thread (struct thread_info *thread)
 {
-  struct continuation *continuation_ptr;
+  do_all_continuations_thread_callback (thread, NULL);
+}
 
-  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;
-  intermediate_continuation = continuation_ptr;
+/* Do all continuations of all threads.  */
+void
+do_all_continuations (void)
+{
+  iterate_over_threads (do_all_continuations_thread_callback, NULL);
+}
+
+/* Callback for iterate over threads.  */
+static int
+discard_all_continuations_thread_callback (struct thread_info *thread,
+                                          void *data)
+{
+  struct cleanup *continuation_ptr = &thread->continuations->base;
+
+  discard_my_cleanups (&continuation_ptr, NULL);
+  thread->continuations = NULL;
+  return 0;
+}
+
+/* Get rid of all the continuations of THREAD.  */
+void
+discard_all_continuations_thread (struct thread_info *thread)
+{
+  discard_all_continuations_thread_callback (thread, NULL);
+}
+
+/* Get rid of all the continuations of all threads.  */
+void
+discard_all_continuations (void)
+{
+  iterate_over_threads (discard_all_continuations_thread_callback, NULL);
+}
+
+
+/* Add a continuation to the intermediate continuation list of THREAD.
+   The new continuation will be added at the front.  */
+void
+add_intermediate_continuation (struct thread_info *thread,
+                              void (*continuation_hook)
+                              (void *), void *args,
+                              void (*continuation_free_args) (void *))
+{
+  struct cleanup *as_cleanup = &thread->intermediate_continuations->base;
+  make_cleanup_ftype *continuation_hook_fn = continuation_hook;
+
+  make_my_cleanup2 (&as_cleanup,
+                   continuation_hook_fn,
+                   args,
+                   continuation_free_args);
+
+  thread->intermediate_continuations = (struct continuation *) as_cleanup;
 }
 
 /* Walk down the cmd_continuation list, and execute all the
-   continuations. There is a problem though. In some cases new
+   continuations.  There is a problem though.  In some cases new
    continuations may be added while we are in the middle of this
-   loop. If this happens they will be added in the front, and done
+   loop.  If this happens they will be added in the front, and done
    before we have a chance of exhausting those that were already
-   there. We need to then save the beginning of the list in a pointer
+   there.  We need to then save the beginning of the list in a pointer
    and do the continuations from there on, instead of using the
-   global beginning of list as our iteration pointer.*/
+   global beginning of list as our iteration pointer.  */
+static int
+do_all_intermediate_continuations_thread_callback (struct thread_info *thread,
+                                                  void *data)
+{
+  do_all_continuations_ptid (thread->ptid,
+                            &thread->intermediate_continuations);
+  return 0;
+}
+
+/* Do all intermediate continuations of thread THREAD.  */
 void
-do_all_intermediate_continuations (int error)
+do_all_intermediate_continuations_thread (struct thread_info *thread)
 {
-  struct continuation *continuation_ptr;
-  struct continuation *saved_continuation;
+  do_all_intermediate_continuations_thread_callback (thread, NULL);
+}
 
-  /* Copy the list header into another pointer, and set the global
-     list header to null, so that the global list can change as a side
-     effect of invoking the continuations and the processing of
-     the preexisting continuations will not be affected. */
-  continuation_ptr = intermediate_continuation;
-  intermediate_continuation = NULL;
+/* Do all intermediate continuations of all threads.  */
+void
+do_all_intermediate_continuations (void)
+{
+  iterate_over_threads (do_all_intermediate_continuations_thread_callback,
+                       NULL);
+}
 
-  /* Work now on the list we have set aside.  */
-  while (continuation_ptr)
-    {
-      (continuation_ptr->continuation_hook) (continuation_ptr->arg_list, error);
-      saved_continuation = continuation_ptr;
-      continuation_ptr = continuation_ptr->next;
-      xfree (saved_continuation);
-    }
+/* Callback for iterate over threads.  */
+static int
+discard_all_intermediate_continuations_thread_callback (struct thread_info *thread,
+                                                       void *data)
+{
+  struct cleanup *continuation_ptr = &thread->intermediate_continuations->base;
+
+  discard_my_cleanups (&continuation_ptr, NULL);
+  thread->intermediate_continuations = NULL;
+  return 0;
 }
 
-/* Walk down the cmd_continuation list, and get rid of all the
-   continuations. */
+/* Get rid of all the intermediate continuations of THREAD.  */
 void
-discard_all_intermediate_continuations (void)
+discard_all_intermediate_continuations_thread (struct thread_info *thread)
 {
-  struct continuation *continuation_ptr;
+  discard_all_intermediate_continuations_thread_callback (thread, NULL);
+}
 
-  while (intermediate_continuation)
-    {
-      continuation_ptr = intermediate_continuation;
-      intermediate_continuation = continuation_ptr->next;
-      xfree (continuation_ptr);
-    }
+/* Get rid of all the intermediate continuations of all threads.  */
+void
+discard_all_intermediate_continuations (void)
+{
+  iterate_over_threads (discard_all_intermediate_continuations_thread_callback,
+                       NULL);
 }
 \f
 
@@ -566,7 +964,7 @@ vwarning (const char *string, va_list args)
   else
     {
       target_terminal_ours ();
-      wrap_here ("");          /* Force out any buffered output */
+      wrap_here ("");          /* Force out any buffered output */
       gdb_flush (gdb_stdout);
       if (warning_pre_print)
        fputs_unfiltered (warning_pre_print, gdb_stderr);
@@ -586,6 +984,7 @@ void
 warning (const char *string, ...)
 {
   va_list args;
+
   va_start (args, string);
   vwarning (string, args);
   va_end (args);
@@ -595,16 +994,17 @@ warning (const char *string, ...)
    The first argument STRING is the error message, used as a fprintf string,
    and the remaining args are passed as arguments to it.  */
 
-NORETURN void
+void
 verror (const char *string, va_list args)
 {
   throw_verror (GENERIC_ERROR, string, args);
 }
 
-NORETURN void
+void
 error (const char *string, ...)
 {
   va_list args;
+
   va_start (args, string);
   throw_verror (GENERIC_ERROR, string, args);
   va_end (args);
@@ -614,48 +1014,101 @@ error (const char *string, ...)
    The first argument STRING is the error message, used as a fprintf string,
    and the remaining args are passed as arguments to it.  */
 
-NORETURN void
+void
 vfatal (const char *string, va_list args)
 {
   throw_vfatal (string, args);
 }
 
-NORETURN void
+void
 fatal (const char *string, ...)
 {
   va_list args;
+
   va_start (args, string);
   throw_vfatal (string, args);
   va_end (args);
 }
 
-NORETURN void
+void
 error_stream (struct ui_file *stream)
 {
-  long len;
-  char *message = ui_file_xstrdup (stream, &len);
+  char *message = ui_file_xstrdup (stream, NULL);
+
   make_cleanup (xfree, message);
   error (("%s"), message);
 }
 
-/* Print a message reporting an internal error/warning. Ask the user
+/* Dump core trying to increase the core soft limit to hard limit first.  */
+
+static void
+dump_core (void)
+{
+#ifdef HAVE_SETRLIMIT
+  struct rlimit rlim = { RLIM_INFINITY, RLIM_INFINITY };
+
+  setrlimit (RLIMIT_CORE, &rlim);
+#endif /* HAVE_SETRLIMIT */
+
+  abort ();            /* NOTE: GDB has only three calls to abort().  */
+}
+
+/* Check whether GDB will be able to dump core using the dump_core
+   function.  */
+
+static int
+can_dump_core (const char *reason)
+{
+#ifdef HAVE_GETRLIMIT
+  struct rlimit rlim;
+
+  /* Be quiet and assume we can dump if an error is returned.  */
+  if (getrlimit (RLIMIT_CORE, &rlim) != 0)
+    return 1;
+
+  if (rlim.rlim_max == 0)
+    {
+      fprintf_unfiltered (gdb_stderr,
+                         _("%s\nUnable to dump core, use `ulimit -c"
+                           " unlimited' before executing GDB next time.\n"),
+                         reason);
+      return 0;
+    }
+#endif /* HAVE_GETRLIMIT */
+
+  return 1;
+}
+
+/* Allow the user to configure the debugger behavior with respect to
+   what to do when an internal problem is detected.  */
+
+const char internal_problem_ask[] = "ask";
+const char internal_problem_yes[] = "yes";
+const char internal_problem_no[] = "no";
+static const char *internal_problem_modes[] =
+{
+  internal_problem_ask,
+  internal_problem_yes,
+  internal_problem_no,
+  NULL
+};
+
+/* 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.  */
 
 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;
+  const char *should_quit;
+  const char *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 ATTR_FORMAT (printf, 4, 0)
+static void ATTRIBUTE_PRINTF (4, 0)
 internal_vproblem (struct internal_problem *problem,
                   const char *file, int line, const char *fmt, va_list ap)
 {
@@ -667,6 +1120,7 @@ internal_vproblem (struct internal_problem *problem,
   /* Don't allow infinite error/warning recursion.  */
   {
     static char msg[] = "Recursive internal problem.\n";
+
     switch (dejavu)
       {
       case 0:
@@ -678,7 +1132,13 @@ internal_vproblem (struct internal_problem *problem,
        abort ();       /* NOTE: GDB has only three calls to abort().  */
       default:
        dejavu = 3;
-       write (STDERR_FILENO, msg, sizeof (msg));
+        /* Newer GLIBC versions put the warn_unused_result attribute
+           on write, but this is one of those rare cases where
+           ignoring the return value is correct.  Casting to (void)
+           does not fix this problem.  This is the solution suggested
+           at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509.  */
+       if (write (STDERR_FILENO, msg, sizeof (msg)) != sizeof (msg))
+          abort (); /* NOTE: GDB has only three calls to abort().  */
        exit (1);
       }
   }
@@ -694,56 +1154,61 @@ internal_vproblem (struct internal_problem *problem,
      so that the user knows that they are living on the edge.  */
   {
     char *msg;
+
     msg = xstrvprintf (fmt, ap);
-    reason = xstrprintf ("\
-%s:%d: %s: %s\n\
-A problem internal to GDB has been detected,\n\
-further debugging may prove unreliable.", file, line, problem->name, msg);
+    reason = xstrprintf ("%s:%d: %s: %s\n"
+                        "A problem internal to GDB has been detected,\n"
+                        "further debugging may prove unreliable.",
+                        file, line, problem->name, msg);
     xfree (msg);
     make_cleanup (xfree, reason);
   }
 
-  switch (problem->should_quit)
+  if (problem->should_quit == internal_problem_ask)
     {
-    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 (_("%s\nQuit this debugging session? "), reason);
-      break;
-    case AUTO_BOOLEAN_TRUE:
-      quit_p = 1;
-      break;
-    case AUTO_BOOLEAN_FALSE:
-      quit_p = 0;
-      break;
-    default:
-      internal_error (__FILE__, __LINE__, _("bad switch"));
+        this lessens the likelihood of GDB going into an infinite
+        loop.  */
+      if (caution == 0)
+        {
+          /* Emit the message and quit.  */
+          fputs_unfiltered (reason, gdb_stderr);
+          fputs_unfiltered ("\n", gdb_stderr);
+          quit_p = 1;
+        }
+      else
+        quit_p = query (_("%s\nQuit this debugging session? "), reason);
     }
+  else if (problem->should_quit == internal_problem_yes)
+    quit_p = 1;
+  else if (problem->should_quit == internal_problem_no)
+    quit_p = 0;
+  else
+    internal_error (__FILE__, __LINE__, _("bad switch"));
 
-  switch (problem->should_dump_core)
+  if (problem->should_dump_core == internal_problem_ask)
     {
-    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 (_("%s\nCreate a core file of GDB? "), reason);
-      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"));
+      if (!can_dump_core (reason))
+       dump_core_p = 0;
+      else
+       {
+         /* 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 (_("%s\nCreate a core file of GDB? "), reason);
+       }
     }
+  else if (problem->should_dump_core == internal_problem_yes)
+    dump_core_p = can_dump_core (reason);
+  else if (problem->should_dump_core == internal_problem_no)
+    dump_core_p = 0;
+  else
+    internal_error (__FILE__, __LINE__, _("bad switch"));
 
   if (quit_p)
     {
       if (dump_core_p)
-       abort ();               /* NOTE: GDB has only three calls to abort().  */
+       dump_core ();
       else
        exit (1);
     }
@@ -753,7 +1218,7 @@ further debugging may prove unreliable.", file, line, problem->name, msg);
        {
 #ifdef HAVE_WORKING_FORK
          if (fork () == 0)
-           abort ();           /* NOTE: GDB has only three calls to abort().  */
+           dump_core ();
 #endif
        }
     }
@@ -762,27 +1227,28 @@ further debugging may prove unreliable.", file, line, problem->name, msg);
 }
 
 static struct internal_problem internal_error_problem = {
-  "internal-error", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
+  "internal-error", internal_problem_ask, internal_problem_ask
 };
 
-NORETURN void
+void
 internal_verror (const char *file, int line, const char *fmt, va_list ap)
 {
   internal_vproblem (&internal_error_problem, file, line, fmt, ap);
   deprecated_throw_reason (RETURN_ERROR);
 }
 
-NORETURN void
+void
 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-warning", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
+  "internal-warning", internal_problem_ask, internal_problem_ask
 };
 
 void
@@ -795,16 +1261,118 @@ 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);
 }
 
+/* Dummy functions to keep add_prefix_cmd happy.  */
+
+static void
+set_internal_problem_cmd (char *args, int from_tty)
+{
+}
+
+static void
+show_internal_problem_cmd (char *args, int from_tty)
+{
+}
+
+/* When GDB reports an internal problem (error or warning) it gives
+   the user the opportunity to quit GDB and/or create a core file of
+   the current debug session.  This function registers a few commands
+   that make it possible to specify that GDB should always or never
+   quit or create a core file, without asking.  The commands look
+   like:
+
+   maint set PROBLEM-NAME quit ask|yes|no
+   maint show PROBLEM-NAME quit
+   maint set PROBLEM-NAME corefile ask|yes|no
+   maint show PROBLEM-NAME corefile
+
+   Where PROBLEM-NAME is currently "internal-error" or
+   "internal-warning".  */
+
+static void
+add_internal_problem_command (struct internal_problem *problem)
+{
+  struct cmd_list_element **set_cmd_list;
+  struct cmd_list_element **show_cmd_list;
+  char *set_doc;
+  char *show_doc;
+
+  set_cmd_list = xmalloc (sizeof (*set_cmd_list));
+  show_cmd_list = xmalloc (sizeof (*set_cmd_list));
+  *set_cmd_list = NULL;
+  *show_cmd_list = NULL;
+
+  set_doc = xstrprintf (_("Configure what GDB does when %s is detected."),
+                       problem->name);
+
+  show_doc = xstrprintf (_("Show what GDB does when %s is detected."),
+                        problem->name);
+
+  add_prefix_cmd ((char*) problem->name,
+                 class_maintenance, set_internal_problem_cmd, set_doc,
+                 set_cmd_list,
+                 concat ("maintenance set ", problem->name, " ",
+                         (char *) NULL),
+                 0/*allow-unknown*/, &maintenance_set_cmdlist);
+
+  add_prefix_cmd ((char*) problem->name,
+                 class_maintenance, show_internal_problem_cmd, show_doc,
+                 show_cmd_list,
+                 concat ("maintenance show ", problem->name, " ",
+                         (char *) NULL),
+                 0/*allow-unknown*/, &maintenance_show_cmdlist);
+
+  set_doc = xstrprintf (_("Set whether GDB should quit "
+                         "when an %s is detected"),
+                       problem->name);
+  show_doc = xstrprintf (_("Show whether GDB will quit "
+                          "when an %s is detected"),
+                        problem->name);
+  add_setshow_enum_cmd ("quit", class_maintenance,
+                       internal_problem_modes,
+                       &problem->should_quit,
+                       set_doc,
+                       show_doc,
+                       NULL, /* help_doc */
+                       NULL, /* setfunc */
+                       NULL, /* showfunc */
+                       set_cmd_list,
+                       show_cmd_list);
+
+  xfree (set_doc);
+  xfree (show_doc);
+
+  set_doc = xstrprintf (_("Set whether GDB should create a core "
+                         "file of GDB when %s is detected"),
+                       problem->name);
+  show_doc = xstrprintf (_("Show whether GDB will create a core "
+                          "file of GDB when %s is detected"),
+                        problem->name);
+  add_setshow_enum_cmd ("corefile", class_maintenance,
+                       internal_problem_modes,
+                       &problem->should_dump_core,
+                       set_doc,
+                       show_doc,
+                       NULL, /* help_doc */
+                       NULL, /* setfunc */
+                       NULL, /* showfunc */
+                       set_cmd_list,
+                       show_cmd_list);
+
+  xfree (set_doc);
+  xfree (show_doc);
+}
+
 /* Print the system error message for errno, and also mention STRING
    as the file name for which the error was encountered.
    Then return to command level.  */
 
-NORETURN void
+void
 perror_with_name (const char *string)
 {
   char *err;
@@ -818,7 +1386,7 @@ perror_with_name (const char *string)
 
   /* I understand setting these is a matter of taste.  Still, some people
      may clear errno but not know about bfd_error.  Doing this here is not
-     unreasonable. */
+     unreasonable.  */
   bfd_set_error (bfd_error_no_error);
   errno = 0;
 
@@ -868,9 +1436,9 @@ quit (void)
 
 \f
 /* Called when a memory allocation fails, with the number of bytes of
-   memory requested in SIZE. */
+   memory requested in SIZE.  */
 
-NORETURN void
+void
 nomem (long size)
 {
   if (size > 0)
@@ -894,7 +1462,7 @@ nomem (long size)
 /* NOTE: These are declared using PTR to ensure consistency with
    "libiberty.h".  xfree() is GDB local.  */
 
-PTR                            /* OK: PTR */
+PTR                            /* ARI: PTR */
 xmalloc (size_t size)
 {
   void *val;
@@ -904,7 +1472,7 @@ xmalloc (size_t size)
   if (size == 0)
     size = 1;
 
-  val = malloc (size);         /* OK: malloc */
+  val = malloc (size);         /* ARI: malloc */
   if (val == NULL)
     nomem (size);
 
@@ -917,8 +1485,8 @@ xzalloc (size_t size)
   return xcalloc (1, size);
 }
 
-PTR                            /* OK: PTR */
-xrealloc (PTR ptr, size_t size)        /* OK: PTR */
+PTR                            /* ARI: PTR */
+xrealloc (PTR ptr, size_t size)        /* ARI: PTR */
 {
   void *val;
 
@@ -928,16 +1496,16 @@ xrealloc (PTR ptr, size_t size)  /* OK: PTR */
     size = 1;
 
   if (ptr != NULL)
-    val = realloc (ptr, size); /* OK: realloc */
+    val = realloc (ptr, size); /* ARI: realloc */
   else
-    val = malloc (size);               /* OK: malloc */
+    val = malloc (size);               /* ARI: malloc */
   if (val == NULL)
     nomem (size);
 
   return (val);
 }
 
-PTR                            /* OK: PTR */
+PTR                            /* ARI: PTR */
 xcalloc (size_t number, size_t size)
 {
   void *mem;
@@ -950,7 +1518,7 @@ xcalloc (size_t number, size_t size)
       size = 1;
     }
 
-  mem = calloc (number, size);         /* OK: xcalloc */
+  mem = calloc (number, size);         /* ARI: xcalloc */
   if (mem == NULL)
     nomem (number * size);
 
@@ -961,18 +1529,19 @@ void
 xfree (void *ptr)
 {
   if (ptr != NULL)
-    free (ptr);                /* OK: free */
+    free (ptr);                /* ARI: free */
 }
 \f
 
 /* Like asprintf/vasprintf but get an internal_error if the call
-   fails. */
+   fails.  */
 
 char *
 xstrprintf (const char *format, ...)
 {
   char *ret;
   va_list args;
+
   va_start (args, format);
   ret = xstrvprintf (format, args);
   va_end (args);
@@ -983,6 +1552,7 @@ void
 xasprintf (char **ret, const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   (*ret) = xstrvprintf (format, args);
   va_end (args);
@@ -999,6 +1569,7 @@ xstrvprintf (const char *format, va_list ap)
 {
   char *ret = NULL;
   int status = vasprintf (&ret, format, ap);
+
   /* NULL is returned when there was a memory allocation problem, or
      any other error (for instance, a bad format string).  A negative
      status (the printed length) with a non-NULL buffer should never
@@ -1052,6 +1623,7 @@ char *
 savestring (const char *ptr, size_t size)
 {
   char *p = (char *) xmalloc (size + 1);
+
   memcpy (p, ptr, size);
   p[size] = 0;
   return p;
@@ -1068,13 +1640,39 @@ print_spaces (int n, struct ui_file *file)
 void
 gdb_print_host_address (const void *addr, struct ui_file *stream)
 {
+  fprintf_filtered (stream, "%s", host_address_to_string (addr));
+}
+\f
 
-  /* We could use the %p conversion specifier to fprintf if we had any
-     way of knowing whether this host supports it.  But the following
-     should work on the Alpha and on 32 bit machines.  */
+/* A cleanup function that calls regfree.  */
 
-  fprintf_filtered (stream, "0x%lx", (unsigned long) addr);
+static void
+do_regfree_cleanup (void *r)
+{
+  regfree (r);
 }
+
+/* Create a new cleanup that frees the compiled regular expression R.  */
+
+struct cleanup *
+make_regfree_cleanup (regex_t *r)
+{
+  return make_cleanup (do_regfree_cleanup, r);
+}
+
+/* Return an xmalloc'd error message resulting from a regular
+   expression compilation failure.  */
+
+char *
+get_regcomp_error (int code, regex_t *rx)
+{
+  size_t length = regerror (code, rx, NULL, 0);
+  char *result = xmalloc (length);
+
+  regerror (code, rx, result, length);
+  return result;
+}
+
 \f
 
 /* This function supports the query, nquery, and yquery functions.
@@ -1087,7 +1685,7 @@ gdb_print_host_address (const void *addr, struct ui_file *stream)
    ARGS are the arguments passed along with the CTLSTR argument to
    printf.  */
 
-static int ATTR_FORMAT (printf, 1, 0)
+static int ATTRIBUTE_PRINTF (1, 0)
 defaulted_query (const char *ctlstr, const char defchar, va_list args)
 {
   int answer;
@@ -1124,12 +1722,12 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
     }
 
   /* Automatically answer the default value if the user did not want
-     prompts.  */
-  if (! caution)
+     prompts or the command was issued with the server prefix.  */
+  if (! caution || server_command)
     return def_value;
 
   /* If input isn't coming from the user directly, just say what
-     question we're asking, and then answer "yes" automatically.  This
+     question we're asking, and then answer the default automatically.  This
      way, important error messages don't get lost when talking to GDB
      over a pipe.  */
   if (! input_from_terminal_p ())
@@ -1137,18 +1735,14 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
       wrap_here ("");
       vfprintf_filtered (gdb_stdout, ctlstr, args);
 
-      printf_filtered (_("(%s or %s) [answered %c; input not from terminal]\n"),
+      printf_filtered (_("(%s or %s) [answered %c; "
+                        "input not from terminal]\n"),
                       y_string, n_string, def_answer);
       gdb_flush (gdb_stdout);
 
       return def_value;
     }
 
-  /* Automatically answer the default value if input is not from the user
-     directly, or if the user did not want prompts.  */
-  if (!input_from_terminal_p () || !caution)
-    return def_value;
-
   if (deprecated_query_hook)
     {
       return deprecated_query_hook (ctlstr, args);
@@ -1159,7 +1753,7 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
 
   while (1)
     {
-      wrap_here ("");          /* Flush any buffered output */
+      wrap_here ("");          /* Flush any buffered output */
       gdb_flush (gdb_stdout);
 
       if (annotation_level > 1)
@@ -1175,6 +1769,25 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
       gdb_flush (gdb_stdout);
 
       answer = fgetc (stdin);
+
+      /* We expect fgetc to block until a character is read.  But
+         this may not be the case if the terminal was opened with
+         the NONBLOCK flag.  In that case, if there is nothing to
+         read on stdin, fgetc returns EOF, but also sets the error
+         condition flag on stdin and errno to EAGAIN.  With a true
+         EOF, stdin's error condition flag is not set.
+
+         A situation where this behavior was observed is a pseudo
+         terminal on AIX.  */
+      while (answer == EOF && ferror (stdin) && errno == EAGAIN)
+        {
+          /* Not a real EOF.  Wait a little while and try again until
+             we read something.  */
+          clearerr (stdin);
+          gdb_usleep (10000);
+          answer = fgetc (stdin);
+        }
+
       clearerr (stdin);                /* in case of C-d */
       if (answer == EOF)       /* C-d */
        {
@@ -1182,7 +1795,7 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
          retval = def_value;
          break;
        }
-      /* Eat rest of input line, to EOF or newline */
+      /* Eat rest of input line, to EOF or newline */
       if (answer != '\n')
        do
          {
@@ -1232,10 +1845,12 @@ int
 nquery (const char *ctlstr, ...)
 {
   va_list args;
+  int ret;
 
   va_start (args, ctlstr);
-  return defaulted_query (ctlstr, 'n', args);
+  ret = defaulted_query (ctlstr, 'n', args);
   va_end (args);
+  return ret;
 }
 
 /* Ask user a y-or-n question and return 0 if answer is no, 1 if
@@ -1248,10 +1863,12 @@ int
 yquery (const char *ctlstr, ...)
 {
   va_list args;
+  int ret;
 
   va_start (args, ctlstr);
-  return defaulted_query (ctlstr, 'y', args);
+  ret = defaulted_query (ctlstr, 'y', args);
   va_end (args);
+  return ret;
 }
 
 /* Ask user a y-or-n question and return 1 iff answer is yes.
@@ -1263,27 +1880,41 @@ int
 query (const char *ctlstr, ...)
 {
   va_list args;
+  int ret;
 
   va_start (args, ctlstr);
-  return defaulted_query (ctlstr, '\0', args);
+  ret = defaulted_query (ctlstr, '\0', args);
   va_end (args);
+  return ret;
 }
 
-/* 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)
+/* A helper for parse_escape that converts a host character to a
+   target character.  C is the host character.  If conversion is
+   possible, then the target character is stored in *TARGET_C and the
+   function returns 1.  Otherwise, the function returns 0.  */
+
+static int
+host_char_to_target (struct gdbarch *gdbarch, int c, int *target_c)
 {
-  int len = end - start;
-  char *copy = alloca (end - start + 1);
+  struct obstack host_data;
+  char the_char = c;
+  struct cleanup *cleanups;
+  int result = 0;
+
+  obstack_init (&host_data);
+  cleanups = make_cleanup_obstack_free (&host_data);
 
-  memcpy (copy, start, len);
-  copy[len] = '\0';
+  convert_between_encodings (target_charset (gdbarch), host_charset (),
+                            &the_char, 1, 1, &host_data, translit_none);
 
-  error (_("There is no control character `\\%s' in the `%s' character set."),
-        copy, target_charset ());
+  if (obstack_object_size (&host_data) == 1)
+    {
+      result = 1;
+      *target_c = *(char *) obstack_base (&host_data);
+    }
+
+  do_cleanups (cleanups);
+  return result;
 }
 
 /* Parse a C escape sequence.  STRING_PTR points to a variable
@@ -1302,57 +1933,18 @@ no_control_char_error (const char *start, const char *end)
    after the zeros.  A value of 0 does not mean end of string.  */
 
 int
-parse_escape (char **string_ptr)
+parse_escape (struct gdbarch *gdbarch, char **string_ptr)
 {
-  int target_char;
+  int target_char = -2;        /* Initialize to avoid GCC warnings.  */
   int c = *(*string_ptr)++;
-  if (c_parse_backslash (c, &target_char))
-    return target_char;
-  else
-    switch (c)
-      {
+
+  switch (c)
+    {
       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':
@@ -1363,16 +1955,16 @@ parse_escape (char **string_ptr)
       case '6':
       case '7':
        {
-         int i = c - '0';
+         int i = host_hex_value (c);
          int count = 0;
          while (++count < 3)
            {
              c = (**string_ptr);
-             if (c >= '0' && c <= '7')
+             if (isdigit (c) && c != '8' && c != '9')
                {
                  (*string_ptr)++;
                  i *= 8;
-                 i += c - '0';
+                 i += host_hex_value (c);
                }
              else
                {
@@ -1381,27 +1973,50 @@ parse_escape (char **string_ptr)
            }
          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;
-      }
+
+    case 'a':
+      c = '\a';
+      break;
+    case 'b':
+      c = '\b';
+      break;
+    case 'f':
+      c = '\f';
+      break;
+    case 'n':
+      c = '\n';
+      break;
+    case 'r':
+      c = '\r';
+      break;
+    case 't':
+      c = '\t';
+      break;
+    case 'v':
+      c = '\v';
+      break;
+
+    default:
+      break;
+    }
+
+  if (!host_char_to_target (gdbarch, c, &target_char))
+    error (_("The escape sequence `\\%c' is equivalent to plain `%c',"
+            " which has no equivalent\nin the `%s' character set."),
+          c, c, target_charset (gdbarch));
+  return target_char;
 }
 \f
 /* Print the character C on STREAM as part of the contents of a literal
    string whose delimiter is QUOTER.  Note that this routine should only
    be call for printing things which are independent of the language
-   of the program being debugged. */
+   of the program being debugged.  */
 
 static void
 printchar (int c, void (*do_fputs) (const char *, struct ui_file *),
           void (*do_fprintf) (struct ui_file *, const char *, ...)
           ATTRIBUTE_FPTR_PRINTF_2, struct ui_file *stream, int quoter)
 {
-
   c &= 0xFF;                   /* Avoid sign bit follies */
 
   if (c < 0x20 ||              /* Low control chars */
@@ -1447,7 +2062,7 @@ printchar (int c, void (*do_fputs) (const char *, struct ui_file *),
 /* Print the character C on STREAM as part of the contents of a
    literal string whose delimiter is QUOTER.  Note that these routines
    should only be call for printing things which are independent of
-   the language of the program being debugged. */
+   the language of the program being debugged.  */
 
 void
 fputstr_filtered (const char *str, int quoter, struct ui_file *stream)
@@ -1468,6 +2083,7 @@ fputstrn_filtered (const char *str, int n, int quoter,
                   struct ui_file *stream)
 {
   int i;
+
   for (i = 0; i < n; i++)
     printchar (str[i], fputs_filtered, fprintf_filtered, stream, quoter);
 }
@@ -1477,6 +2093,7 @@ 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);
 }
@@ -1488,8 +2105,8 @@ static void
 show_lines_per_page (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("\
-Number of lines gdb thinks are in a page is %s.\n"),
+  fprintf_filtered (file,
+                   _("Number of lines gdb thinks are in a page is %s.\n"),
                    value);
 }
 
@@ -1499,8 +2116,9 @@ static void
 show_chars_per_line (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("\
-Number of characters gdb thinks are in a line is %s.\n"),
+  fprintf_filtered (file,
+                   _("Number of characters gdb thinks "
+                     "are in a line is %s.\n"),
                    value);
 }
 
@@ -1537,6 +2155,12 @@ static int wrap_column;
 void
 init_page_info (void)
 {
+  if (batch_flag)
+    {
+      lines_per_page = UINT_MAX;
+      chars_per_line = UINT_MAX;
+    }
+  else
 #if defined(TUI)
   if (!tui_get_command_dimension (&chars_per_line, &lines_per_page))
 #endif
@@ -1581,6 +2205,44 @@ init_page_info (void)
   set_width ();
 }
 
+/* Helper for make_cleanup_restore_page_info.  */
+
+static void
+do_restore_page_info_cleanup (void *arg)
+{
+  set_screen_size ();
+  set_width ();
+}
+
+/* Provide cleanup for restoring the terminal size.  */
+
+struct cleanup *
+make_cleanup_restore_page_info (void)
+{
+  struct cleanup *back_to;
+
+  back_to = make_cleanup (do_restore_page_info_cleanup, NULL);
+  make_cleanup_restore_uinteger (&lines_per_page);
+  make_cleanup_restore_uinteger (&chars_per_line);
+
+  return back_to;
+}
+
+/* Temporarily set BATCH_FLAG and the associated unlimited terminal size.
+   Provide cleanup for restoring the original state.  */
+
+struct cleanup *
+set_batch_flag_and_make_cleanup_restore_page_info (void)
+{
+  struct cleanup *back_to = make_cleanup_restore_page_info ();
+  
+  make_cleanup_restore_integer (&batch_flag);
+  batch_flag = 1;
+  init_page_info ();
+
+  return back_to;
+}
+
 /* Set the screen size based on LINES_PER_PAGE and CHARS_PER_LINE.  */
 
 static void
@@ -1672,6 +2334,7 @@ prompt_for_continue (void)
   if (ignore)
     {
       char *p = ignore;
+
       while (*p == ' ' || *p == '\t')
        ++p;
       if (p[0] == 'q')
@@ -1684,7 +2347,7 @@ prompt_for_continue (void)
      need to save the ---Type <return>--- line at the top of the screen.  */
   reinitialize_more_filter ();
 
-  dont_repeat ();              /* Forget prev cmd -- CR won't repeat it. */
+  dont_repeat ();              /* Forget prev cmd -- CR won't repeat it.  */
 }
 
 /* Reinitialize filter; ie. tell it to reset to original values.  */
@@ -1697,7 +2360,7 @@ reinitialize_more_filter (void)
 }
 
 /* Indicate that if the next sequence of characters overflows the line,
-   a newline should be inserted here rather than when it hits the end. 
+   a newline should be inserted here rather than when it hits the end.
    If INDENT is non-null, it is a string to be printed to indent the
    wrapped part on the next line.  INDENT must remain accessible until
    the next call to wrap_here() or until a newline is printed through
@@ -1720,9 +2383,10 @@ reinitialize_more_filter (void)
 void
 wrap_here (char *indent)
 {
-  /* This should have been allocated, but be paranoid anyway. */
+  /* This should have been allocated, but be paranoid anyway.  */
   if (!wrap_buffer)
-    internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
+    internal_error (__FILE__, __LINE__,
+                   _("failed internal consistency check"));
 
   if (wrap_buffer[0])
     {
@@ -1731,7 +2395,7 @@ wrap_here (char *indent)
     }
   wrap_pointer = wrap_buffer;
   wrap_buffer[0] = '\0';
-  if (chars_per_line == UINT_MAX)      /* No line overflow checking */
+  if (chars_per_line == UINT_MAX)      /* No line overflow checking */
     {
       wrap_column = 0;
     }
@@ -1753,11 +2417,11 @@ wrap_here (char *indent)
 }
 
 /* Print input string to gdb_stdout, filtered, with wrap, 
-   arranging strings in columns of n chars. String can be
+   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 */
+   command, which currently doesn't tabulate very well */
 
 void
 puts_filtered_tabular (char *string, int width, int right)
@@ -1798,9 +2462,9 @@ puts_filtered_tabular (char *string, int width, int right)
 
 
 /* Ensure that whatever gets printed next, using the filtered output
-   commands, starts at the beginning of the line.  I.E. if there is
+   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. */
+   line.  Otherwise do nothing.  */
 
 void
 begin_line (void)
@@ -1835,8 +2499,12 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
     return;
 
   /* Don't do any filtering if it is disabled.  */
-  if ((stream != gdb_stdout) || !pagination_enabled
-      || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX))
+  if (stream != gdb_stdout
+      || ! pagination_enabled
+      || ! input_from_terminal_p ()
+      || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX)
+      || top_level_interpreter () == NULL
+      || ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())))
     {
       fputs_unfiltered (linebuffer, stream);
       return;
@@ -1894,16 +2562,16 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
              if (lines_printed >= lines_per_page - 1)
                prompt_for_continue ();
 
-             /* Now output indentation and wrapped string */
+             /* Now output indentation and wrapped string */
              if (wrap_column)
                {
                  fputs_unfiltered (wrap_indent, stream);
-                 *wrap_pointer = '\0'; /* Null-terminate saved stuff */
-                 fputs_unfiltered (wrap_buffer, stream);       /* and eject it */
+                 *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
                     and count its chars, we risk trouble if wrap_indent is
-                    longer than (the user settable) chars_per_line. 
+                    longer than (the user settable) chars_per_line.
                     Note also that this can set chars_printed > chars_per_line
                     if we are printing a long string.  */
                  chars_printed = strlen (wrap_indent)
@@ -1918,7 +2586,8 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
       if (*lineptr == '\n')
        {
          chars_printed = 0;
-         wrap_here ((char *) 0);       /* Spit out chars, cancel further wraps */
+         wrap_here ((char *) 0);       /* Spit out chars, cancel
+                                          further wraps.  */
          lines_printed++;
          fputc_unfiltered ('\n', stream);
          lineptr++;
@@ -1936,6 +2605,7 @@ int
 putchar_unfiltered (int c)
 {
   char buf = c;
+
   ui_file_write (gdb_stdout, &buf, 1);
   return c;
 }
@@ -1953,6 +2623,7 @@ int
 fputc_unfiltered (int c, struct ui_file *stream)
 {
   char buf = c;
+
   ui_file_write (stream, &buf, 1);
   return c;
 }
@@ -2099,13 +2770,22 @@ vfprintf_unfiltered (struct ui_file *stream, const char *format, va_list args)
     {
       struct timeval tm;
       char *timestamp;
+      int len, need_nl;
 
       gettimeofday (&tm, NULL);
-      timestamp = xstrprintf ("%ld:%ld ", (long) tm.tv_sec, (long) tm.tv_usec);
+
+      len = strlen (linebuffer);
+      need_nl = (len > 0 && linebuffer[len - 1] != '\n');
+
+      timestamp = xstrprintf ("%ld:%ld %s%s",
+                             (long) tm.tv_sec, (long) tm.tv_usec,
+                             linebuffer,
+                             need_nl ? "\n": "");
       make_cleanup (xfree, timestamp);
       fputs_unfiltered (timestamp, stream);
     }
-  fputs_unfiltered (linebuffer, stream);
+  else
+    fputs_unfiltered (linebuffer, stream);
   do_cleanups (old_cleanups);
 }
 
@@ -2125,6 +2805,7 @@ void
 fprintf_filtered (struct ui_file *stream, const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   vfprintf_filtered (stream, format, args);
   va_end (args);
@@ -2134,6 +2815,7 @@ void
 fprintf_unfiltered (struct ui_file *stream, const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   vfprintf_unfiltered (stream, format, args);
   va_end (args);
@@ -2147,6 +2829,7 @@ fprintfi_filtered (int spaces, struct ui_file *stream, const char *format,
                   ...)
 {
   va_list args;
+
   va_start (args, format);
   print_spaces_filtered (spaces, stream);
 
@@ -2159,6 +2842,7 @@ void
 printf_filtered (const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   vfprintf_filtered (gdb_stdout, format, args);
   va_end (args);
@@ -2169,6 +2853,7 @@ void
 printf_unfiltered (const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   vfprintf_unfiltered (gdb_stdout, format, args);
   va_end (args);
@@ -2181,6 +2866,7 @@ void
 printfi_filtered (int spaces, const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   print_spaces_filtered (spaces, gdb_stdout);
   vfprintf_filtered (gdb_stdout, format, args);
@@ -2239,7 +2925,7 @@ print_spaces_filtered (int n, struct ui_file *stream)
 /* fprintf_symbol_filtered attempts to demangle NAME, a symbol in language
    LANG, using demangling args ARG_MODE, and print it filtered to STREAM.
    If the name is not mangled, or the language for the name is unknown, or
-   demangling is off, the name is printed in its "raw" form. */
+   demangling is off, the name is printed in its "raw" form.  */
 
 void
 fprintf_symbol_filtered (struct ui_file *stream, char *name,
@@ -2273,7 +2959,7 @@ fprintf_symbol_filtered (struct ui_file *stream, char *name,
    As an extra hack, string1=="FOO(ARGS)" matches string2=="FOO".
    This "feature" is useful when searching for matching C++ function names
    (such as if the user types 'break FOO', where FOO is a mangled C++
-   function). */
+   function).  */
 
 int
 strcmp_iw (const char *string1, const char *string2)
@@ -2400,6 +3086,7 @@ 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 =
@@ -2426,15 +3113,14 @@ static void
 show_debug_timestamp (struct ui_file *file, int from_tty,
                      struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Timestamping debugging messages is %s.\n"), value);
+  fprintf_filtered (file, _("Timestamping debugging messages is %s.\n"),
+                   value);
 }
 \f
 
 void
 initialize_utils (void)
 {
-  struct cmd_list_element *c;
-
   add_setshow_uinteger_cmd ("width", class_support, &chars_per_line, _("\
 Set number of characters gdb thinks are in a line."), _("\
 Show number of characters gdb thinks are in a line."), NULL,
@@ -2499,13 +3185,13 @@ When set, debugging messages will be marked with seconds and microseconds."),
                           &setdebuglist, &showdebuglist);
 }
 
-/* Machine specific function to handle SIGWINCH signal. */
+/* Machine specific function to handle SIGWINCH signal.  */
 
 #ifdef  SIGWINCH_HANDLER_BODY
 SIGWINCH_HANDLER_BODY
 #endif
-/* print routines to handle variable size regs, etc. */
-/* temporary storage using circular buffer */
+/* Print routines to handle variable size regs, etc.  */
+/* Temporary storage using circular buffer.  */
 #define NUMCELLS 16
 #define CELLSIZE 50
 static char *
@@ -2513,57 +3199,59 @@ get_cell (void)
 {
   static char buf[NUMCELLS][CELLSIZE];
   static int cell = 0;
+
   if (++cell >= NUMCELLS)
     cell = 0;
   return buf[cell];
 }
 
-int
-strlen_paddr (void)
-{
-  return (gdbarch_addr_bit (current_gdbarch) / 8 * 2);
-}
-
-char *
-paddr (CORE_ADDR addr)
-{
-  return phex (addr, gdbarch_addr_bit (current_gdbarch) / 8);
-}
-
-char *
-paddr_nz (CORE_ADDR addr)
-{
-  return phex_nz (addr, gdbarch_addr_bit (current_gdbarch) / 8);
-}
-
 const char *
-paddress (CORE_ADDR addr)
+paddress (struct gdbarch *gdbarch, CORE_ADDR addr)
 {
   /* Truncate address to the size of a target address, avoiding shifts
      larger or equal than the width of a CORE_ADDR.  The local
      variable ADDR_BIT stops the compiler reporting a shift overflow
-     when it won't occur. */
+     when it won't occur.  */
   /* NOTE: This assumes that the significant address information is
      kept in the least significant bits of ADDR - the upper bits were
      either zero or sign extended.  Should gdbarch_address_to_pointer or
      some ADDRESS_TO_PRINTABLE() be used to do the conversion?  */
 
-  int addr_bit = gdbarch_addr_bit (current_gdbarch);
+  int addr_bit = gdbarch_addr_bit (gdbarch);
 
   if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
     addr &= ((CORE_ADDR) 1 << addr_bit) - 1;
   return hex_string (addr);
 }
 
+/* This function is described in "defs.h".  */
+
+const char *
+print_core_address (struct gdbarch *gdbarch, CORE_ADDR address)
+{
+  int addr_bit = gdbarch_addr_bit (gdbarch);
+
+  if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
+    address &= ((CORE_ADDR) 1 << addr_bit) - 1;
+
+  /* FIXME: cagney/2002-05-03: Need local_address_string() function
+     that returns the language localized string formatted to a width
+     based on gdbarch_addr_bit.  */
+  if (addr_bit <= 32)
+    return hex_string_custom (address, 8);
+  else
+    return hex_string_custom (address, 16);
+}
+
 static char *
 decimal2str (char *sign, ULONGEST addr, int width)
 {
   /* Steal code from valprint.c:print_decimal().  Should this worry
-     about the real size of addr as the above does? */
+     about the real size of addr as the above does?  */
   unsigned long temp[3];
   char *str = get_cell ();
-
   int i = 0;
+
   do
     {
       temp[i] = addr % (1000 * 1000 * 1000);
@@ -2603,8 +3291,8 @@ octal2str (ULONGEST addr, int width)
 {
   unsigned long temp[3];
   char *str = get_cell ();
-
   int i = 0;
+
   do
     {
       temp[i] = addr % (0100000 * 0100000);
@@ -2642,18 +3330,18 @@ octal2str (ULONGEST addr, int width)
 }
 
 char *
-paddr_u (CORE_ADDR addr)
+pulongest (ULONGEST u)
 {
-  return decimal2str ("", addr, 0);
+  return decimal2str ("", u, 0);
 }
 
 char *
-paddr_d (LONGEST addr)
+plongest (LONGEST l)
 {
-  if (addr < 0)
-    return decimal2str ("-", -addr, 0);
+  if (l < 0)
+    return decimal2str ("-", -l, 0);
   else
-    return decimal2str ("", addr, 0);
+    return decimal2str ("", l, 0);
 }
 
 /* Eliminate warning from compiler on 32-bit systems.  */
@@ -2698,6 +3386,7 @@ phex_nz (ULONGEST l, int sizeof_l)
     case 8:
       {
        unsigned long high = (unsigned long) (l >> thirty_two);
+
        str = get_cell ();
        if (high == 0)
          xsnprintf (str, CELLSIZE, "%lx",
@@ -2729,6 +3418,7 @@ char *
 hex_string (LONGEST num)
 {
   char *result = get_cell ();
+
   xsnprintf (result, CELLSIZE, "0x%s", phex_nz (num, sizeof (num)));
   return result;
 }
@@ -2748,8 +3438,8 @@ hex_string_custom (LONGEST num, int width)
   if (hex_len > width)
     width = hex_len;
   if (width + 2 >= CELLSIZE)
-    internal_error (__FILE__, __LINE__,
-                   _("hex_string_custom: insufficient space to store result"));
+    internal_error (__FILE__, __LINE__, _("\
+hex_string_custom: insufficient space to store result"));
 
   strcpy (result_end - width - 2, "0x");
   memset (result_end - width, '0', width);
@@ -2762,7 +3452,7 @@ hex_string_custom (LONGEST num, int width)
  * otherwise VAL is interpreted as unsigned.  If WIDTH is supplied, 
  * it is the minimum width (0-padded if needed).  USE_C_FORMAT means
  * to use C format in all cases.  If it is false, then 'x' 
- * and 'o' formats do not include a prefix (0x or leading 0). */
+ * and 'o' formats do not include a prefix (0x or leading 0).  */
 
 char *
 int_string (LONGEST val, int radix, int is_signed, int width, 
@@ -2773,6 +3463,7 @@ int_string (LONGEST val, int radix, int is_signed, int width,
     case 16:
       {
        char *result;
+
        if (width == 0)
          result = hex_string (val);
        else
@@ -2791,6 +3482,7 @@ int_string (LONGEST val, int radix, int is_signed, int width,
     case 8:
       {
        char *result = octal2str (val, width);
+
        if (use_c_format || val == 0)
          return result;
        else
@@ -2807,6 +3499,7 @@ 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;
@@ -2816,6 +3509,7 @@ 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;
@@ -2825,13 +3519,13 @@ core_addr_to_string_nz (const CORE_ADDR addr)
 CORE_ADDR
 string_to_core_addr (const char *my_string)
 {
-  int addr_bit = gdbarch_addr_bit (current_gdbarch);
   CORE_ADDR addr = 0;
 
   if (my_string[0] == '0' && tolower (my_string[1]) == 'x')
     {
       /* Assume that it is in hex.  */
       int i;
+
       for (i = 2; my_string[i] != '\0'; i++)
        {
          if (isdigit (my_string[i]))
@@ -2841,22 +3535,12 @@ string_to_core_addr (const char *my_string)
          else
            error (_("invalid hex \"%s\""), my_string);
        }
-
-      /* Not very modular, but if the executable format expects
-         addresses to be sign-extended, then do so if the address was
-         specified with only 32 significant bits.  Really this should
-         be determined by the target architecture, not by the object
-         file.  */
-      if (i - 2 == addr_bit / 4
-         && exec_bfd
-         && bfd_get_sign_extend_vma (exec_bfd))
-       addr = (addr ^ ((CORE_ADDR) 1 << (addr_bit - 1)))
-              - ((CORE_ADDR) 1 << (addr_bit - 1));
     }
   else
     {
       /* Assume that it is in decimal.  */
       int i;
+
       for (i = 0; my_string[i] != '\0'; i++)
        {
          if (isdigit (my_string[i]))
@@ -2869,6 +3553,15 @@ string_to_core_addr (const char *my_string)
   return addr;
 }
 
+const char *
+host_address_to_string (const void *addr)
+{
+  char *str = get_cell ();
+
+  xsnprintf (str, CELLSIZE, "0x%s", phex_nz ((uintptr_t) addr, sizeof (addr)));
+  return str;
+}
+
 char *
 gdb_realpath (const char *filename)
 {
@@ -2887,6 +3580,7 @@ gdb_realpath (const char *filename)
 # endif
 # if defined (USE_REALPATH)
     const char *rp = realpath (filename, buf);
+
     if (rp == NULL)
       rp = filename;
     return xstrdup (rp);
@@ -2900,6 +3594,7 @@ gdb_realpath (const char *filename)
 #if defined(HAVE_CANONICALIZE_FILE_NAME)
   {
     char *rp = canonicalize_file_name (filename);
+
     if (rp == NULL)
       return xstrdup (filename);
     else
@@ -2927,11 +3622,13 @@ gdb_realpath (const char *filename)
   {
     /* 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);
       }
   }
@@ -2953,14 +3650,14 @@ xfullpath (const char *filename)
   char *result;
 
   /* Extract the basename of filename, and return immediately 
-     a copy of filename if it does not contain any directory prefix. */
+     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 */
+     then the closing \000 character */
   strncpy (dir_name, filename, base_name - filename);
   dir_name[base_name - filename] = '\000';
 
@@ -2975,13 +3672,13 @@ xfullpath (const char *filename)
 #endif
 
   /* Canonicalize the directory prefix, and build the resulting
-     filename. If the dirname realpath already contains an ending
+     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, (char *)NULL);
+    result = concat (real_path, base_name, (char *) NULL);
   else
-    result = concat (real_path, SLASH_STRING, base_name, (char *)NULL);
+    result = concat (real_path, SLASH_STRING, base_name, (char *) NULL);
 
   xfree (real_path);
   return result;
@@ -2996,7 +3693,7 @@ xfullpath (const char *filename)
 unsigned long
 gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len)
 {
-  static const unsigned long crc32_table[256] = {
+  static const unsigned int crc32_table[256] = {
     0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
     0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
     0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
@@ -3055,7 +3752,7 @@ gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len)
   crc = ~crc & 0xffffffff;
   for (end = buf + len; buf < end; ++buf)
     crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
-  return ~crc & 0xffffffff;;
+  return ~crc & 0xffffffff;
 }
 
 ULONGEST
@@ -3082,6 +3779,7 @@ hashtab_obstack_allocate (void *data, size_t size, size_t count)
 {
   unsigned int total = size * count;
   void *ptr = obstack_alloc ((struct obstack *) data, total);
+
   memset (ptr, 0, total);
   return ptr;
 }
@@ -3223,3 +3921,97 @@ ldirname (const char *filename)
   dirname[base - filename] = '\0';
   return dirname;
 }
+
+/* Call libiberty's buildargv, and return the result.
+   If buildargv fails due to out-of-memory, call nomem.
+   Therefore, the returned value is guaranteed to be non-NULL,
+   unless the parameter itself is NULL.  */
+
+char **
+gdb_buildargv (const char *s)
+{
+  char **argv = buildargv (s);
+
+  if (s != NULL && argv == NULL)
+    nomem (0);
+  return argv;
+}
+
+int
+compare_positive_ints (const void *ap, const void *bp)
+{
+  /* Because we know we're comparing two ints which are positive,
+     there's no danger of overflow here.  */
+  return * (int *) ap - * (int *) bp;
+}
+
+#define AMBIGUOUS_MESS1        ".\nMatching formats:"
+#define AMBIGUOUS_MESS2        \
+  ".\nUse \"set gnutarget format-name\" to specify the format."
+
+const char *
+gdb_bfd_errmsg (bfd_error_type error_tag, char **matching)
+{
+  char *ret, *retp;
+  int ret_len;
+  char **p;
+
+  /* Check if errmsg just need simple return.  */
+  if (error_tag != bfd_error_file_ambiguously_recognized || matching == NULL)
+    return bfd_errmsg (error_tag);
+
+  ret_len = strlen (bfd_errmsg (error_tag)) + strlen (AMBIGUOUS_MESS1)
+            + strlen (AMBIGUOUS_MESS2);
+  for (p = matching; *p; p++)
+    ret_len += strlen (*p) + 1;
+  ret = xmalloc (ret_len + 1);
+  retp = ret;
+  make_cleanup (xfree, ret);
+
+  strcpy (retp, bfd_errmsg (error_tag));
+  retp += strlen (retp);
+
+  strcpy (retp, AMBIGUOUS_MESS1);
+  retp += strlen (retp);
+
+  for (p = matching; *p; p++)
+    {
+      sprintf (retp, " %s", *p);
+      retp += strlen (retp);
+    }
+  xfree (matching);
+
+  strcpy (retp, AMBIGUOUS_MESS2);
+
+  return ret;
+}
+
+/* Return ARGS parsed as a valid pid, or throw an error.  */
+
+int
+parse_pid_to_attach (char *args)
+{
+  unsigned long pid;
+  char *dummy;
+
+  if (!args)
+    error_no_arg (_("process-id to attach"));
+
+  dummy = args;
+  pid = strtoul (args, &dummy, 0);
+  /* Some targets don't set errno on errors, grrr!  */
+  if ((pid == 0 && dummy == args) || dummy != &args[strlen (args)])
+    error (_("Illegal process-id: %s."), args);
+
+  return pid;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_utils;
+
+void
+_initialize_utils (void)
+{
+  add_internal_problem_command (&internal_error_problem);
+  add_internal_problem_command (&internal_warning_problem);
+}
This page took 0.053802 seconds and 4 git commands to generate.