* dwarf2read.c (try_open_dwo_file): Use gdb_bfd_ref and
[deliverable/binutils-gdb.git] / gdb / utils.c
index 11c34bf7bd9e7e82c55d9d3094294437320805ca..d26899980d2ffd61690e2cf676af13ffbd60844b 100644 (file)
@@ -1,8 +1,6 @@
 /* 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,
-   2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1986, 1988-2012 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "dyn-string.h"
 #include "gdb_assert.h"
 #include <ctype.h>
 #include "gdb_string.h"
+#include "gdb_wait.h"
 #include "event-top.h"
 #include "exceptions.h"
 #include "gdbthread.h"
+#include "fnmatch.h"
+#include "gdb_bfd.h"
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
 #endif /* HAVE_SYS_RESOURCE_H */
 #endif
 
 #include <signal.h>
+#include "timeval-utils.h"
 #include "gdbcmd.h"
 #include "serial.h"
 #include "bfd.h"
 #include "target.h"
-#include "demangle.h"
+#include "gdb-demangle.h"
 #include "expression.h"
 #include "language.h"
 #include "charset.h"
@@ -59,6 +62,7 @@
 #include "gdbcore.h"
 #include "top.h"
 #include "main.h"
+#include "solist.h"
 
 #include "inferior.h"          /* for signed_pointer_to_address */
 
@@ -97,8 +101,6 @@ static void vfprintf_maybe_filtered (struct ui_file *, const char *,
 
 static void fputs_maybe_filtered (const char *, struct ui_file *, int);
 
-static void do_my_cleanups (struct cleanup **, struct cleanup *);
-
 static void prompt_for_continue (void);
 
 static void set_screen_size (void);
@@ -108,12 +110,6 @@ static void set_width (void);
 
 static int debug_timestamp = 0;
 
-/* Chain of cleanup actions established with make_cleanup,
-   to be executed if an error happens.  */
-
-static struct cleanup *cleanup_chain;  /* cleaned up after a failed command */
-static struct cleanup *final_cleanup_chain;    /* cleaned up when gdb exits */
-
 /* Nonzero if we have job control.  */
 
 int job_control;
@@ -135,35 +131,6 @@ int quit_flag;
 
 int immediate_quit;
 
-/* Nonzero means that encoded C++/ObjC names should be printed out in their
-   C++/ObjC form rather than raw.  */
-
-int demangle = 1;
-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"),
-                   value);
-}
-
-/* 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;
-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"),
-                   value);
-}
-
 /* Nonzero means that strings with character values >0x7F should be printed
    as octal escapes.  Zero means just print the value (e.g. it's an
    international character, and the terminal or window can cope.)  */
@@ -199,48 +166,40 @@ show_pagination_enabled (struct ui_file *file, int from_tty,
 }
 
 \f
+/* Cleanup utilities.
 
-/* Add a new cleanup to the cleanup_chain,
-   and return the previous chain pointer
-   to be passed later to do_cleanups or discard_cleanups.
-   Args are FUNCTION to clean up with, and ARG to pass to it.  */
-
-struct cleanup *
-make_cleanup (make_cleanup_ftype *function, void *arg)
-{
-  return make_my_cleanup (&cleanup_chain, function, arg);
-}
+   These are not defined in cleanups.c (nor declared in cleanups.h)
+   because while they use the "cleanup API" they are not part of the
+   "cleanup API".  */
 
-struct cleanup *
-make_cleanup_dtor (make_cleanup_ftype *function, void *arg,
-                  void (*dtor) (void *))
+static void
+do_freeargv (void *arg)
 {
-  return make_my_cleanup2 (&cleanup_chain,
-                          function, arg, dtor);
+  freeargv ((char **) arg);
 }
 
 struct cleanup *
-make_final_cleanup (make_cleanup_ftype *function, void *arg)
+make_cleanup_freeargv (char **arg)
 {
-  return make_my_cleanup (&final_cleanup_chain, function, arg);
+  return make_cleanup (do_freeargv, arg);
 }
 
 static void
-do_freeargv (void *arg)
+do_dyn_string_delete (void *arg)
 {
-  freeargv ((char **) arg);
+  dyn_string_delete ((dyn_string_t) arg);
 }
 
 struct cleanup *
-make_cleanup_freeargv (char **arg)
+make_cleanup_dyn_string_delete (dyn_string_t arg)
 {
-  return make_my_cleanup (&cleanup_chain, do_freeargv, arg);
+  return make_cleanup (do_dyn_string_delete, arg);
 }
 
 static void
 do_bfd_close_cleanup (void *arg)
 {
-  bfd_close (arg);
+  gdb_bfd_unref (arg);
 }
 
 struct cleanup *
@@ -311,7 +270,7 @@ do_ui_file_delete (void *arg)
 struct cleanup *
 make_cleanup_ui_file_delete (struct ui_file *arg)
 {
-  return make_my_cleanup (&cleanup_chain, do_ui_file_delete, arg);
+  return make_cleanup (do_ui_file_delete, arg);
 }
 
 /* Helper function for make_cleanup_ui_out_redirect_pop.  */
@@ -331,7 +290,7 @@ do_ui_out_redirect_pop (void *arg)
 struct cleanup *
 make_cleanup_ui_out_redirect_pop (struct ui_out *uiout)
 {
-  return make_my_cleanup (&cleanup_chain, do_ui_out_redirect_pop, uiout);
+  return make_cleanup (do_ui_out_redirect_pop, uiout);
 }
 
 static void
@@ -343,7 +302,7 @@ do_free_section_addr_info (void *arg)
 struct cleanup *
 make_cleanup_free_section_addr_info (struct section_addr_info *addrs)
 {
-  return make_my_cleanup (&cleanup_chain, do_free_section_addr_info, addrs);
+  return make_cleanup (do_free_section_addr_info, addrs);
 }
 
 struct restore_integer_closure
@@ -372,8 +331,7 @@ make_cleanup_restore_integer (int *variable)
   c->variable = variable;
   c->value = *variable;
 
-  return make_my_cleanup2 (&cleanup_chain, restore_integer, (void *)c,
-                          xfree);
+  return make_cleanup_dtor (restore_integer, (void *) c, xfree);
 }
 
 /* Remember the current value of *VARIABLE and make it restored when
@@ -400,7 +358,25 @@ do_unpush_target (void *arg)
 struct cleanup *
 make_cleanup_unpush_target (struct target_ops *ops)
 {
-  return make_my_cleanup (&cleanup_chain, do_unpush_target, ops);
+  return make_cleanup (do_unpush_target, ops);
+}
+
+/* Helper for make_cleanup_htab_delete compile time checking the types.  */
+
+static void
+do_htab_delete_cleanup (void *htab_voidp)
+{
+  htab_t htab = htab_voidp;
+
+  htab_delete (htab);
+}
+
+/* Return a new cleanup that deletes HTAB.  */
+
+struct cleanup *
+make_cleanup_htab_delete (htab_t htab)
+{
+  return make_cleanup (do_htab_delete_cleanup, htab);
 }
 
 struct restore_ui_file_closure
@@ -431,130 +407,55 @@ make_cleanup_restore_ui_file (struct ui_file **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));
-  struct cleanup *old_chain = *pmy_chain;
-
-  new->next = *pmy_chain;
-  new->function = function;
-  new->free_arg = free_arg;
-  new->arg = arg;
-  *pmy_chain = new;
-
-  return old_chain;
-}
+/* Helper for make_cleanup_value_free_to_mark.  */
 
-struct cleanup *
-make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
-                void *arg)
+static void
+do_value_free_to_mark (void *value)
 {
-  return make_my_cleanup2 (pmy_chain, function, arg, NULL);
+  value_free_to_mark ((struct value *) value);
 }
 
-/* Discard cleanups and do the actions they describe
-   until we get back to the point OLD_CHAIN in the cleanup_chain.  */
+/* Free all values allocated since MARK was obtained by value_mark
+   (except for those released) when the cleanup is run.  */
 
-void
-do_cleanups (struct cleanup *old_chain)
+struct cleanup *
+make_cleanup_value_free_to_mark (struct value *mark)
 {
-  do_my_cleanups (&cleanup_chain, old_chain);
+  return make_cleanup (do_value_free_to_mark, mark);
 }
 
-void
-do_final_cleanups (struct cleanup *old_chain)
-{
-  do_my_cleanups (&final_cleanup_chain, old_chain);
-}
+/* Helper for make_cleanup_value_free.  */
 
 static void
-do_my_cleanups (struct cleanup **pmy_chain,
-               struct cleanup *old_chain)
+do_value_free (void *value)
 {
-  struct cleanup *ptr;
-
-  while ((ptr = *pmy_chain) != old_chain)
-    {
-      *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);
-    }
+  value_free (value);
 }
 
-/* Discard cleanups, not doing the actions they describe,
-   until we get back to the point OLD_CHAIN in the cleanup_chain.  */
-
-void
-discard_cleanups (struct cleanup *old_chain)
-{
-  discard_my_cleanups (&cleanup_chain, old_chain);
-}
+/* Free VALUE.  */
 
-void
-discard_final_cleanups (struct cleanup *old_chain)
-{
-  discard_my_cleanups (&final_cleanup_chain, old_chain);
-}
-
-void
-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);
-    }
-}
-
-/* Set the cleanup_chain to 0, and return the old cleanup chain.  */
 struct cleanup *
-save_cleanups (void)
+make_cleanup_value_free (struct value *value)
 {
-  return save_my_cleanups (&cleanup_chain);
+  return make_cleanup (do_value_free, value);
 }
 
-struct cleanup *
-save_final_cleanups (void)
-{
-  return save_my_cleanups (&final_cleanup_chain);
-}
+/* Helper for make_cleanup_free_so.  */
 
-struct cleanup *
-save_my_cleanups (struct cleanup **pmy_chain)
+static void
+do_free_so (void *arg)
 {
-  struct cleanup *old_chain = *pmy_chain;
+  struct so_list *so = arg;
 
-  *pmy_chain = 0;
-  return old_chain;
+  free_so (so);
 }
 
-/* Restore the cleanup chain from a previously saved chain.  */
-void
-restore_cleanups (struct cleanup *chain)
-{
-  restore_my_cleanups (&cleanup_chain, chain);
-}
-
-void
-restore_final_cleanups (struct cleanup *chain)
-{
-  restore_my_cleanups (&final_cleanup_chain, chain);
-}
+/* Make cleanup handler calling free_so for SO.  */
 
-void
-restore_my_cleanups (struct cleanup **pmy_chain, struct cleanup *chain)
+struct cleanup *
+make_cleanup_free_so (struct so_list *so)
 {
-  *pmy_chain = chain;
+  return make_cleanup (do_free_so, so);
 }
 
 /* This function is useful for cleanups.
@@ -580,18 +481,6 @@ free_current_contents (void *ptr)
     }
 }
 
-/* Provide a known function that does nothing, to use as a base for
-   a possibly long chain of cleanups.  This is useful where we
-   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.  */
-
-void
-null_cleanup (void *arg)
-{
-}
-
 /* If nonzero, display time usage both at startup and for each command.  */
 
 static int display_time;
@@ -608,7 +497,8 @@ static int display_space;
 struct cmd_stats 
 {
   int msg_type;
-  long start_time;
+  long start_cpu_time;
+  struct timeval start_wall_time;
   long start_space;
 };
 
@@ -640,12 +530,19 @@ report_command_stats (void *arg)
 
   if (display_time)
     {
-      long cmd_time = get_run_time () - start_stats->start_time;
+      long cmd_time = get_run_time () - start_stats->start_cpu_time;
+      struct timeval now_wall_time, delta_wall_time;
+
+      gettimeofday (&now_wall_time, NULL);
+      timeval_sub (&delta_wall_time,
+                  &now_wall_time, &start_stats->start_wall_time);
 
       printf_unfiltered (msg_type == 0
-                        ? _("Startup time: %ld.%06ld\n")
-                        : _("Command execution time: %ld.%06ld\n"),
-                        cmd_time / 1000000, cmd_time % 1000000);
+                        ? _("Startup time: %ld.%06ld (cpu), %ld.%06ld (wall)\n")
+                        : _("Command execution time: %ld.%06ld (cpu), %ld.%06ld (wall)\n"),
+                        cmd_time / 1000000, cmd_time % 1000000,
+                        (long) delta_wall_time.tv_sec,
+                        (long) delta_wall_time.tv_usec);
     }
 
   if (display_space)
@@ -681,272 +578,11 @@ make_command_stats_cleanup (int msg_type)
 #endif
 
   new_stat->msg_type = msg_type;
-  new_stat->start_time = get_run_time ();
+  new_stat->start_cpu_time = get_run_time ();
+  gettimeofday (&new_stat->start_wall_time, NULL);
 
   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_inferior_continuations (void)
-{
-  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.  */
-
-  as_cleanup = &inf->continuations->base;
-  inf->continuations = NULL;
-
-  /* Work now on the list we have set aside.  */
-  do_my_cleanups (&as_cleanup, NULL);
-}
-
-/* Get rid of all the inferior-wide continuations of INF.  */
-
-void
-discard_all_inferior_continuations (struct inferior *inf)
-{
-  struct cleanup *continuation_ptr = &inf->continuations->base;
-
-  discard_my_cleanups (&continuation_ptr, NULL);
-  inf->continuations = NULL;
-}
-
-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
-do_all_continuations_thread (struct thread_info *thread)
-{
-  do_all_continuations_thread_callback (thread, NULL);
-}
-
-/* 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 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 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_thread (struct thread_info *thread)
-{
-  do_all_intermediate_continuations_thread_callback (thread, NULL);
-}
-
-/* Do all intermediate continuations of all threads.  */
-void
-do_all_intermediate_continuations (void)
-{
-  iterate_over_threads (do_all_intermediate_continuations_thread_callback,
-                       NULL);
-}
-
-/* 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;
-}
-
-/* Get rid of all the intermediate continuations of THREAD.  */
-void
-discard_all_intermediate_continuations_thread (struct thread_info *thread)
-{
-  discard_all_intermediate_continuations_thread_callback (thread, NULL);
-}
-
-/* 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
 
 
@@ -1085,7 +721,7 @@ can_dump_core (const char *reason)
 const char internal_problem_ask[] = "ask";
 const char internal_problem_yes[] = "yes";
 const char internal_problem_no[] = "no";
-static const char *internal_problem_modes[] =
+static const char *const internal_problem_modes[] =
 {
   internal_problem_ask,
   internal_problem_yes,
@@ -1169,7 +805,7 @@ internal_vproblem (struct internal_problem *problem,
       /* Default (yes/batch case) is to quit GDB.  When in batch mode
         this lessens the likelihood of GDB going into an infinite
         loop.  */
-      if (caution == 0)
+      if (!confirm)
         {
           /* Emit the message and quit.  */
           fputs_unfiltered (reason, gdb_stderr);
@@ -1439,7 +1075,7 @@ quit (void)
    memory requested in SIZE.  */
 
 void
-nomem (long size)
+malloc_failure (long size)
 {
   if (size > 0)
     {
@@ -1453,146 +1089,6 @@ nomem (long size)
     }
 }
 
-/* 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.  */
-
-/* NOTE: These are declared using PTR to ensure consistency with
-   "libiberty.h".  xfree() is GDB local.  */
-
-PTR                            /* ARI: PTR */
-xmalloc (size_t size)
-{
-  void *val;
-
-  /* See libiberty/xmalloc.c.  This function need's to match that's
-     semantics.  It never returns NULL.  */
-  if (size == 0)
-    size = 1;
-
-  val = malloc (size);         /* ARI: malloc */
-  if (val == NULL)
-    nomem (size);
-
-  return (val);
-}
-
-void *
-xzalloc (size_t size)
-{
-  return xcalloc (1, size);
-}
-
-PTR                            /* ARI: PTR */
-xrealloc (PTR ptr, size_t size)        /* ARI: PTR */
-{
-  void *val;
-
-  /* See libiberty/xmalloc.c.  This function need's to match that's
-     semantics.  It never returns NULL.  */
-  if (size == 0)
-    size = 1;
-
-  if (ptr != NULL)
-    val = realloc (ptr, size); /* ARI: realloc */
-  else
-    val = malloc (size);               /* ARI: malloc */
-  if (val == NULL)
-    nomem (size);
-
-  return (val);
-}
-
-PTR                            /* ARI: PTR */
-xcalloc (size_t number, size_t size)
-{
-  void *mem;
-
-  /* See libiberty/xmalloc.c.  This function need's to match that's
-     semantics.  It never returns NULL.  */
-  if (number == 0 || size == 0)
-    {
-      number = 1;
-      size = 1;
-    }
-
-  mem = calloc (number, size);         /* ARI: xcalloc */
-  if (mem == NULL)
-    nomem (number * size);
-
-  return mem;
-}
-
-void
-xfree (void *ptr)
-{
-  if (ptr != NULL)
-    free (ptr);                /* ARI: free */
-}
-\f
-
-/* Like asprintf/vasprintf but get an internal_error if the call
-   fails.  */
-
-char *
-xstrprintf (const char *format, ...)
-{
-  char *ret;
-  va_list args;
-
-  va_start (args, format);
-  ret = xstrvprintf (format, args);
-  va_end (args);
-  return ret;
-}
-
-void
-xasprintf (char **ret, const char *format, ...)
-{
-  va_list args;
-
-  va_start (args, format);
-  (*ret) = xstrvprintf (format, args);
-  va_end (args);
-}
-
-void
-xvasprintf (char **ret, const char *format, va_list ap)
-{
-  (*ret) = xstrvprintf (format, ap);
-}
-
-char *
-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
-     happen, but just to be sure.  */
-  if (ret == NULL || status < 0)
-    internal_error (__FILE__, __LINE__, _("vasprintf call failed"));
-  return ret;
-}
-
-int
-xsnprintf (char *str, size_t size, const char *format, ...)
-{
-  va_list args;
-  int ret;
-
-  va_start (args, format);
-  ret = vsnprintf (str, size, format, args);
-  gdb_assert (ret < size);
-  va_end (args);
-
-  return ret;
-}
-
 /* My replacement for the read system call.
    Used like `read' but keeps going if `read' returns too soon.  */
 
@@ -1614,7 +1110,7 @@ myread (int desc, char *addr, int len)
     }
   return orglen;
 }
-\f
+
 /* Make a copy of the string at PTR with SIZE characters
    (and add a null character at the end in the copy).
    Uses malloc to get the space.  Returns the address of the copy.  */
@@ -1723,7 +1219,7 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
 
   /* Automatically answer the default value if the user did not want
      prompts or the command was issued with the server prefix.  */
-  if (! caution || server_command)
+  if (!confirm || server_command)
     return def_value;
 
   /* If input isn't coming from the user directly, just say what
@@ -2500,8 +1996,8 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
 
   /* Don't do any filtering if it is disabled.  */
   if (stream != gdb_stdout
-      || ! pagination_enabled
-      || ! input_from_terminal_p ()
+      || !pagination_enabled
+      || batch_flag
       || (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 ())))
@@ -2928,7 +2424,7 @@ 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,
+fprintf_symbol_filtered (struct ui_file *stream, const char *name,
                         enum language lang, int arg_mode)
 {
   char *demangled;
@@ -2974,10 +2470,12 @@ strcmp_iw (const char *string1, const char *string2)
        {
          string2++;
        }
-      if (*string1 != *string2)
-       {
-         break;
-       }
+      if (case_sensitivity == case_sensitive_on && *string1 != *string2)
+       break;
+      if (case_sensitivity == case_sensitive_off
+         && (tolower ((unsigned char) *string1)
+             != tolower ((unsigned char) *string2)))
+       break;
       if (*string1 != '\0')
        {
          string1++;
@@ -2998,6 +2496,10 @@ strcmp_iw (const char *string1, const char *string2)
    strcmp_iw(LIST_ELT, NAME), then the place to start looking is right
    where this function would put NAME.
 
+   This function must be neutral to the CASE_SENSITIVITY setting as the user
+   may choose it during later lookup.  Therefore this function always sorts
+   primarily case-insensitively and secondarily case-sensitively.
+
    Here are some examples of why using strcmp to sort is a bad idea:
 
    Whitespace example:
@@ -3023,47 +2525,78 @@ strcmp_iw (const char *string1, const char *string2)
 int
 strcmp_iw_ordered (const char *string1, const char *string2)
 {
-  while ((*string1 != '\0') && (*string2 != '\0'))
+  const char *saved_string1 = string1, *saved_string2 = string2;
+  enum case_sensitivity case_pass = case_sensitive_off;
+
+  for (;;)
     {
-      while (isspace (*string1))
-       {
-         string1++;
-       }
-      while (isspace (*string2))
-       {
-         string2++;
-       }
-      if (*string1 != *string2)
+      /* C1 and C2 are valid only if *string1 != '\0' && *string2 != '\0'.
+        Provide stub characters if we are already at the end of one of the
+        strings.  */
+      char c1 = 'X', c2 = 'X';
+
+      while (*string1 != '\0' && *string2 != '\0')
        {
-         break;
+         while (isspace (*string1))
+           string1++;
+         while (isspace (*string2))
+           string2++;
+
+         switch (case_pass)
+         {
+           case case_sensitive_off:
+             c1 = tolower ((unsigned char) *string1);
+             c2 = tolower ((unsigned char) *string2);
+             break;
+           case case_sensitive_on:
+             c1 = *string1;
+             c2 = *string2;
+             break;
+         }
+         if (c1 != c2)
+           break;
+
+         if (*string1 != '\0')
+           {
+             string1++;
+             string2++;
+           }
        }
-      if (*string1 != '\0')
+
+      switch (*string1)
        {
-         string1++;
-         string2++;
+         /* 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')
+           break;
+         else
+           return -1;
+       case '(':
+         if (*string2 == '\0')
+           return 1;
+         else
+           return -1;
+       default:
+         if (*string2 == '\0' || *string2 == '(')
+           return 1;
+         else if (c1 > c2)
+           return 1;
+         else if (c1 < c2)
+           return -1;
+         /* PASSTHRU */
        }
-    }
 
-  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')
+      if (case_pass == case_sensitive_on)
        return 0;
-      else
-       return -1;
-    case '(':
-      if (*string2 == '\0')
-       return 1;
-      else
-       return -1;
-    default:
-      if (*string2 == '(')
-       return 1;
-      else
-       return *string1 - *string2;
+      
+      /* Otherwise the strings were equal in case insensitive way, make
+        a more fine grained comparison in a case sensitive way.  */
+
+      case_pass = case_sensitive_on;
+      string1 = saved_string1;
+      string2 = saved_string2;
     }
 }
 
@@ -3137,13 +2670,6 @@ Show number of lines gdb thinks are in a page."), NULL,
 
   init_page_info ();
 
-  add_setshow_boolean_cmd ("demangle", class_support, &demangle, _("\
-Set demangling of encoded C++/ObjC names when displaying symbols."), _("\
-Show demangling of encoded C++/ObjC names when displaying symbols."), NULL,
-                          NULL,
-                          show_demangle,
-                          &setprintlist, &showprintlist);
-
   add_setshow_boolean_cmd ("pagination", class_support,
                           &pagination_enabled, _("\
 Set state of pagination."), _("\
@@ -3168,13 +2694,6 @@ Show printing of 8-bit characters in strings as \\nnn."), NULL,
                           show_sevenbit_strings,
                           &setprintlist, &showprintlist);
 
-  add_setshow_boolean_cmd ("asm-demangle", class_support, &asm_demangle, _("\
-Set demangling of C++/ObjC names in disassembly listings."), _("\
-Show demangling of C++/ObjC names in disassembly listings."), NULL,
-                          NULL,
-                          show_asm_demangle,
-                          &setprintlist, &showprintlist);
-
   add_setshow_boolean_cmd ("timestamp", class_maintenance,
                            &debug_timestamp, _("\
 Set timestamping of debugging messages."), _("\
@@ -3243,6 +2762,27 @@ print_core_address (struct gdbarch *gdbarch, CORE_ADDR address)
     return hex_string_custom (address, 16);
 }
 
+/* Callback hash_f for htab_create_alloc or htab_create_alloc_ex.  */
+
+hashval_t
+core_addr_hash (const void *ap)
+{
+  const CORE_ADDR *addrp = ap;
+
+  return *addrp;
+}
+
+/* Callback eq_f for htab_create_alloc or htab_create_alloc_ex.  */
+
+int
+core_addr_eq (const void *ap, const void *bp)
+{
+  const CORE_ADDR *addr_ap = ap;
+  const CORE_ADDR *addr_bp = bp;
+
+  return *addr_ap == *addr_bp;
+}
+
 static char *
 decimal2str (char *sign, ULONGEST addr, int width)
 {
@@ -3634,6 +3174,25 @@ gdb_realpath (const char *filename)
   }
 #endif
 
+  /* The MS Windows method.  If we don't have realpath, we assume we
+     don't have symlinks and just canonicalize to a Windows absolute
+     path.  GetFullPath converts ../ and ./ in relative paths to
+     absolute paths, filling in current drive if one is not given
+     or using the current directory of a specified drive (eg, "E:foo").
+     It also converts all forward slashes to back slashes.  */
+  /* The file system is case-insensitive but case-preserving.
+     So we do not lowercase the path.  Otherwise, we might not
+     be able to display the original casing in a given path.  */
+#if defined (_WIN32)
+  {
+    char buf[MAX_PATH];
+    DWORD len = GetFullPathName (filename, MAX_PATH, buf, NULL);
+
+    if (len > 0 && len < MAX_PATH)
+      return xstrdup (buf);
+  }
+#endif
+
   /* This system is a lost cause, just dup the buffer.  */
   return xstrdup (filename);
 }
@@ -3933,7 +3492,7 @@ gdb_buildargv (const char *s)
   char **argv = buildargv (s);
 
   if (s != NULL && argv == NULL)
-    nomem (0);
+    malloc_failure (0);
   return argv;
 }
 
@@ -3945,6 +3504,17 @@ compare_positive_ints (const void *ap, const void *bp)
   return * (int *) ap - * (int *) bp;
 }
 
+/* String compare function for qsort.  */
+
+int
+compare_strings (const void *arg1, const void *arg2)
+{
+  const char **s1 = (const char **) arg1;
+  const char **s2 = (const char **) arg2;
+
+  return strcmp (*s1, *s2);
+}
+
 #define AMBIGUOUS_MESS1        ".\nMatching formats:"
 #define AMBIGUOUS_MESS2        \
   ".\nUse \"set gnutarget format-name\" to specify the format."
@@ -4006,6 +3576,315 @@ parse_pid_to_attach (char *args)
   return pid;
 }
 
+/* Helper for make_bpstat_clear_actions_cleanup.  */
+
+static void
+do_bpstat_clear_actions_cleanup (void *unused)
+{
+  bpstat_clear_actions ();
+}
+
+/* Call bpstat_clear_actions for the case an exception is throw.  You should
+   discard_cleanups if no exception is caught.  */
+
+struct cleanup *
+make_bpstat_clear_actions_cleanup (void)
+{
+  return make_cleanup (do_bpstat_clear_actions_cleanup, NULL);
+}
+
+/* Check for GCC >= 4.x according to the symtab->producer string.  Return minor
+   version (x) of 4.x in such case.  If it is not GCC or it is GCC older than
+   4.x return -1.  If it is GCC 5.x or higher return INT_MAX.  */
+
+int
+producer_is_gcc_ge_4 (const char *producer)
+{
+  const char *cs;
+  int major, minor;
+
+  if (producer == NULL)
+    {
+      /* For unknown compilers expect their behavior is not compliant.  For GCC
+        this case can also happen for -gdwarf-4 type units supported since
+        gcc-4.5.  */
+
+      return -1;
+    }
+
+  /* Skip any identifier after "GNU " - such as "C++" or "Java".  */
+
+  if (strncmp (producer, "GNU ", strlen ("GNU ")) != 0)
+    {
+      /* For non-GCC compilers expect their behavior is not compliant.  */
+
+      return -1;
+    }
+  cs = &producer[strlen ("GNU ")];
+  while (*cs && !isdigit (*cs))
+    cs++;
+  if (sscanf (cs, "%d.%d", &major, &minor) != 2)
+    {
+      /* Not recognized as GCC.  */
+
+      return -1;
+    }
+
+  if (major < 4)
+    return -1;
+  if (major > 4)
+    return INT_MAX;
+  return minor;
+}
+
+/* Call xfree for each element of CHAR_PTR_VEC and final VEC_free for
+   CHAR_PTR_VEC itself.
+
+   You must not modify CHAR_PTR_VEC after it got registered with this function
+   by make_cleanup as the CHAR_PTR_VEC base address may change on its updates.
+   Contrary to VEC_free this function does not (cannot) clear the pointer.  */
+
+void
+free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec)
+{
+  int ix;
+  char *name;
+
+  for (ix = 0; VEC_iterate (char_ptr, char_ptr_vec, ix, name); ++ix)
+    xfree (name);
+  VEC_free (char_ptr, char_ptr_vec);
+}
+
+/* Helper for make_cleanup_free_char_ptr_vec.  */
+
+static void
+do_free_char_ptr_vec (void *arg)
+{
+  VEC (char_ptr) *char_ptr_vec = arg;
+
+  free_char_ptr_vec (char_ptr_vec);
+}
+
+/* Make cleanup handler calling xfree for each element of CHAR_PTR_VEC and
+   final VEC_free for CHAR_PTR_VEC itself.
+
+   You must not modify CHAR_PTR_VEC after this cleanup registration as the
+   CHAR_PTR_VEC base address may change on its updates.  Contrary to VEC_free
+   this function does not (cannot) clear the pointer.  */
+
+struct cleanup *
+make_cleanup_free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec)
+{
+  return make_cleanup (do_free_char_ptr_vec, char_ptr_vec);
+}
+
+/* Extended version of dirnames_to_char_ptr_vec - additionally if *VECP is
+   non-NULL the new list elements from DIRNAMES are appended to the existing
+   *VECP list of entries.  *VECP address will be updated by this call.  */
+
+void
+dirnames_to_char_ptr_vec_append (VEC (char_ptr) **vecp, const char *dirnames)
+{
+  do
+    {
+      size_t this_len;
+      char *next_dir, *this_dir;
+
+      next_dir = strchr (dirnames, DIRNAME_SEPARATOR);
+      if (next_dir == NULL)
+       this_len = strlen (dirnames);
+      else
+       {
+         this_len = next_dir - dirnames;
+         next_dir++;
+       }
+
+      this_dir = xmalloc (this_len + 1);
+      memcpy (this_dir, dirnames, this_len);
+      this_dir[this_len] = '\0';
+      VEC_safe_push (char_ptr, *vecp, this_dir);
+
+      dirnames = next_dir;
+    }
+  while (dirnames != NULL);
+}
+
+/* Split DIRNAMES by DIRNAME_SEPARATOR delimiter and return a list of all the
+   elements in their original order.  For empty string ("") DIRNAMES return
+   list of one empty string ("") element.
+   
+   You may modify the returned strings.
+   Read free_char_ptr_vec for its cleanup.  */
+
+VEC (char_ptr) *
+dirnames_to_char_ptr_vec (const char *dirnames)
+{
+  VEC (char_ptr) *retval = NULL;
+  
+  dirnames_to_char_ptr_vec_append (&retval, dirnames);
+
+  return retval;
+}
+
+/* Substitute all occurences of string FROM by string TO in *STRINGP.  *STRINGP
+   must come from xrealloc-compatible allocator and it may be updated.  FROM
+   needs to be delimited by IS_DIR_SEPARATOR or DIRNAME_SEPARATOR (or be
+   located at the start or end of *STRINGP.  */
+
+void
+substitute_path_component (char **stringp, const char *from, const char *to)
+{
+  char *string = *stringp, *s;
+  const size_t from_len = strlen (from);
+  const size_t to_len = strlen (to);
+
+  for (s = string;;)
+    {
+      s = strstr (s, from);
+      if (s == NULL)
+       break;
+
+      if ((s == string || IS_DIR_SEPARATOR (s[-1])
+          || s[-1] == DIRNAME_SEPARATOR)
+          && (s[from_len] == '\0' || IS_DIR_SEPARATOR (s[from_len])
+             || s[from_len] == DIRNAME_SEPARATOR))
+       {
+         char *string_new;
+
+         string_new = xrealloc (string, (strlen (string) + to_len + 1));
+
+         /* Relocate the current S pointer.  */
+         s = s - string + string_new;
+         string = string_new;
+
+         /* Replace from by to.  */
+         memmove (&s[to_len], &s[from_len], strlen (&s[from_len]) + 1);
+         memcpy (s, to, to_len);
+
+         s += to_len;
+       }
+      else
+       s++;
+    }
+
+  *stringp = string;
+}
+
+#ifdef HAVE_WAITPID
+
+#ifdef SIGALRM
+
+/* SIGALRM handler for waitpid_with_timeout.  */
+
+static void
+sigalrm_handler (int signo)
+{
+  /* Nothing to do.  */
+}
+
+#endif
+
+/* Wrapper to wait for child PID to die with TIMEOUT.
+   TIMEOUT is the time to stop waiting in seconds.
+   If TIMEOUT is zero, pass WNOHANG to waitpid.
+   Returns PID if it was successfully waited for, otherwise -1.
+
+   Timeouts are currently implemented with alarm and SIGALRM.
+   If the host does not support them, this waits "forever".
+   It would be odd though for a host to have waitpid and not SIGALRM.  */
+
+pid_t
+wait_to_die_with_timeout (pid_t pid, int *status, int timeout)
+{
+  pid_t waitpid_result;
+
+  gdb_assert (pid > 0);
+  gdb_assert (timeout >= 0);
+
+  if (timeout > 0)
+    {
+#ifdef SIGALRM
+#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
+      struct sigaction sa, old_sa;
+
+      sa.sa_handler = sigalrm_handler;
+      sigemptyset (&sa.sa_mask);
+      sa.sa_flags = 0;
+      sigaction (SIGALRM, &sa, &old_sa);
+#else
+      void (*ofunc) ();
+
+      ofunc = (void (*)()) signal (SIGALRM, sigalrm_handler);
+#endif
+
+      alarm (timeout);
+#endif
+
+      waitpid_result = waitpid (pid, status, 0);
+
+#ifdef SIGALRM
+      alarm (0);
+#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
+      sigaction (SIGALRM, &old_sa, NULL);
+#else
+      signal (SIGALRM, ofunc);
+#endif
+#endif
+    }
+  else
+    waitpid_result = waitpid (pid, status, WNOHANG);
+
+  if (waitpid_result == pid)
+    return pid;
+  else
+    return -1;
+}
+
+#endif /* HAVE_WAITPID */
+
+/* Provide fnmatch compatible function for FNM_FILE_NAME matching of host files.
+   Both FNM_FILE_NAME and FNM_NOESCAPE must be set in FLAGS.
+
+   It handles correctly HAVE_DOS_BASED_FILE_SYSTEM and
+   HAVE_CASE_INSENSITIVE_FILE_SYSTEM.  */
+
+int
+gdb_filename_fnmatch (const char *pattern, const char *string, int flags)
+{
+  gdb_assert ((flags & FNM_FILE_NAME) != 0);
+
+  /* It is unclear how '\' escaping vs. directory separator should coexist.  */
+  gdb_assert ((flags & FNM_NOESCAPE) != 0);
+
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  {
+    char *pattern_slash, *string_slash;
+
+    /* Replace '\' by '/' in both strings.  */
+
+    pattern_slash = alloca (strlen (pattern) + 1);
+    strcpy (pattern_slash, pattern);
+    pattern = pattern_slash;
+    for (; *pattern_slash != 0; pattern_slash++)
+      if (IS_DIR_SEPARATOR (*pattern_slash))
+       *pattern_slash = '/';
+
+    string_slash = alloca (strlen (string) + 1);
+    strcpy (string_slash, string);
+    string = string_slash;
+    for (; *string_slash != 0; string_slash++)
+      if (IS_DIR_SEPARATOR (*string_slash))
+       *string_slash = '/';
+  }
+#endif /* HAVE_DOS_BASED_FILE_SYSTEM */
+
+#ifdef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
+  flags |= FNM_CASEFOLD;
+#endif /* HAVE_CASE_INSENSITIVE_FILE_SYSTEM */
+
+  return fnmatch (pattern, string, flags);
+}
+
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 extern initialize_file_ftype _initialize_utils;
 
This page took 0.042199 seconds and 4 git commands to generate.