2013-03-11 Sebastian Huber <sebastian.huber@embedded-brains.de>
[deliverable/binutils-gdb.git] / gdb / utils.c
index a979cc4e4e1d0ae6817ec2967a622f1ee0426a8c..4c2f08c91b84082f410d39c56113f2125ea60131 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-2013 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 */
 
@@ -85,9 +89,6 @@ extern PTR realloc ();                /* ARI: PTR */
 extern void free ();
 #endif
 
-/* readline defines this.  */
-#undef savestring
-
 void (*deprecated_error_begin_hook) (void);
 
 /* Prototypes for local functions */
@@ -97,30 +98,32 @@ 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);
 static void set_width (void);
 
-/* A flag indicating whether to timestamp debugging messages.  */
+/* Time spent in prompt_for_continue in the currently executing command
+   waiting for user to respond.
+   Initialized in make_command_stats_cleanup.
+   Modified in prompt_for_continue and defaulted_query.
+   Used in report_command_stats.  */
 
-static int debug_timestamp = 0;
+static struct timeval prompt_for_continue_wait_time;
 
-/* Chain of cleanup actions established with make_cleanup,
-   to be executed if an error happens.  */
+/* A flag indicating whether to timestamp debugging messages.  */
 
-static struct cleanup *cleanup_chain;  /* cleaned up after a failed command */
-static struct cleanup *final_cleanup_chain;    /* cleaned up when gdb exits */
+static int debug_timestamp = 0;
 
 /* Nonzero if we have job control.  */
 
 int job_control;
 
+#ifndef HAVE_PYTHON
 /* Nonzero means a quit has been requested.  */
 
 int quit_flag;
+#endif /* HAVE_PYTHON */
 
 /* Nonzero means quit immediately if Control-C is typed now, rather
    than waiting until QUIT is executed.  Be careful in setting this;
@@ -135,35 +138,41 @@ 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.  */
+#ifndef HAVE_PYTHON
 
-int demangle = 1;
-static void
-show_demangle (struct ui_file *file, int from_tty,
-              struct cmd_list_element *c, const char *value)
+/* Clear the quit flag.  */
+
+void
+clear_quit_flag (void)
 {
-  fprintf_filtered (file,
-                   _("Demangling of encoded C++/ObjC names "
-                     "when displaying symbols is %s.\n"),
-                   value);
+  quit_flag = 0;
 }
 
-/* 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.  */
+/* Set the quit flag.  */
 
-int asm_demangle = 0;
-static void
-show_asm_demangle (struct ui_file *file, int from_tty,
-                  struct cmd_list_element *c, const char *value)
+void
+set_quit_flag (void)
 {
-  fprintf_filtered (file,
-                   _("Demangling of C++/ObjC names in "
-                     "disassembly listings is %s.\n"),
-                   value);
+  quit_flag = 1;
+}
+
+/* Return true if the quit flag has been set, false otherwise.  */
+
+int
+check_quit_flag (void)
+{
+  /* This is written in a particular way to avoid races.  */
+  if (quit_flag)
+    {
+      quit_flag = 0;
+      return 1;
+    }
+
+  return 0;
 }
 
+#endif /* HAVE_PYTHON */
+
 /* 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,52 +208,44 @@ 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.  */
+   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 (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 *))
+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 *
-make_cleanup_bfd_close (bfd *abfd)
+make_cleanup_bfd_unref (bfd *abfd)
 {
   return make_cleanup (do_bfd_close_cleanup, abfd);
 }
@@ -311,7 +312,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 +332,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 +344,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 +373,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 +400,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
@@ -445,7 +463,7 @@ do_value_free_to_mark (void *value)
 struct cleanup *
 make_cleanup_value_free_to_mark (struct value *mark)
 {
-  return make_my_cleanup (&cleanup_chain, do_value_free_to_mark, mark);
+  return make_cleanup (do_value_free_to_mark, mark);
 }
 
 /* Helper for make_cleanup_value_free.  */
@@ -461,133 +479,47 @@ do_value_free (void *value)
 struct cleanup *
 make_cleanup_value_free (struct value *value)
 {
-  return make_my_cleanup (&cleanup_chain, do_value_free, value);
-}
-
-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;
-}
-
-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.  */
-
-void
-do_cleanups (struct cleanup *old_chain)
-{
-  do_my_cleanups (&cleanup_chain, old_chain);
+  return make_cleanup (do_value_free, value);
 }
 
-void
-do_final_cleanups (struct cleanup *old_chain)
-{
-  do_my_cleanups (&final_cleanup_chain, old_chain);
-}
+/* Helper for make_cleanup_free_so.  */
 
 static void
-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 in case of recursion.  */
-      (*ptr->function) (ptr->arg);
-      if (ptr->free_arg)
-       (*ptr->free_arg) (ptr->arg);
-      xfree (ptr);
-    }
-}
-
-/* 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)
+do_free_so (void *arg)
 {
-  discard_my_cleanups (&cleanup_chain, old_chain);
-}
+  struct so_list *so = arg;
 
-void
-discard_final_cleanups (struct cleanup *old_chain)
-{
-  discard_my_cleanups (&final_cleanup_chain, old_chain);
+  free_so (so);
 }
 
-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);
-    }
-}
+/* Make cleanup handler calling free_so for SO.  */
 
-/* Set the cleanup_chain to 0, and return the old cleanup chain.  */
 struct cleanup *
-save_cleanups (void)
+make_cleanup_free_so (struct so_list *so)
 {
-  return save_my_cleanups (&cleanup_chain);
+  return make_cleanup (do_free_so, so);
 }
 
-struct cleanup *
-save_final_cleanups (void)
-{
-  return save_my_cleanups (&final_cleanup_chain);
-}
+/* Helper for make_cleanup_restore_current_language.  */
 
-struct cleanup *
-save_my_cleanups (struct cleanup **pmy_chain)
+static void
+do_restore_current_language (void *p)
 {
-  struct cleanup *old_chain = *pmy_chain;
+  enum language saved_lang = (uintptr_t) p;
 
-  *pmy_chain = 0;
-  return old_chain;
+  set_language (saved_lang);
 }
 
-/* Restore the cleanup chain from a previously saved chain.  */
-void
-restore_cleanups (struct cleanup *chain)
-{
-  restore_my_cleanups (&cleanup_chain, chain);
-}
+/* Remember the current value of CURRENT_LANGUAGE and make it restored when
+   the cleanup is run.  */
 
-void
-restore_final_cleanups (struct cleanup *chain)
+struct cleanup *
+make_cleanup_restore_current_language (void)
 {
-  restore_my_cleanups (&final_cleanup_chain, chain);
-}
+  enum language saved_lang = current_language->la_language;
 
-void
-restore_my_cleanups (struct cleanup **pmy_chain, struct cleanup *chain)
-{
-  *pmy_chain = chain;
+  return make_cleanup (do_restore_current_language,
+                      (void *) (uintptr_t) saved_lang);
 }
 
 /* This function is useful for cleanups.
@@ -613,18 +545,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;
@@ -641,7 +561,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;
 };
 
@@ -673,12 +594,23 @@ 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);
+
+      /* Subtract time spend in prompt_for_continue from walltime.  */
+      timeval_sub (&delta_wall_time,
+                   &delta_wall_time, &prompt_for_continue_wait_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)
@@ -706,6 +638,7 @@ report_command_stats (void *arg)
 struct cleanup *
 make_command_stats_cleanup (int msg_type)
 {
+  static const struct timeval zero_timeval = { 0 };
   struct cmd_stats *new_stat = XMALLOC (struct cmd_stats);
   
 #ifdef HAVE_SBRK
@@ -714,7 +647,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);
+
+  /* Initalize timer to keep track of how long we waited for the user.  */
+  prompt_for_continue_wait_time = zero_timeval;
 
   return make_cleanup_dtor (report_command_stats, new_stat, xfree);
 }
@@ -856,7 +793,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,
@@ -940,7 +877,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);
@@ -1246,20 +1183,6 @@ myread (int desc, char *addr, int len)
   return orglen;
 }
 
-/* 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.  */
-
-char *
-savestring (const char *ptr, size_t size)
-{
-  char *p = (char *) xmalloc (size + 1);
-
-  memcpy (p, ptr, size);
-  p[size] = 0;
-  return p;
-}
-
 void
 print_spaces (int n, struct ui_file *file)
 {
@@ -1325,6 +1248,9 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
   int def_value;
   char def_answer, not_def_answer;
   char *y_string, *n_string, *question;
+  /* Used to add duration we waited for user to respond to
+     prompt_for_continue_wait_time.  */
+  struct timeval prompt_started, prompt_ended, prompt_delta;
 
   /* Set up according to which answer is the default.  */
   if (defchar == '\0')
@@ -1354,7 +1280,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
@@ -1382,6 +1308,9 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
   /* Format the question outside of the loop, to avoid reusing args.  */
   question = xstrvprintf (ctlstr, args);
 
+  /* Used for calculating time spend waiting for user.  */
+  gettimeofday (&prompt_started, NULL);
+
   while (1)
     {
       wrap_here ("");          /* Flush any buffered output.  */
@@ -1459,6 +1388,12 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
                       y_string, n_string);
     }
 
+  /* Add time spend in this routine to prompt_for_continue_wait_time.  */
+  gettimeofday (&prompt_ended, NULL);
+  timeval_sub (&prompt_delta, &prompt_ended, &prompt_started);
+  timeval_add (&prompt_for_continue_wait_time,
+               &prompt_for_continue_wait_time, &prompt_delta);
+
   xfree (question);
   if (annotation_level > 1)
     printf_filtered (("\n\032\032post-query\n"));
@@ -1536,7 +1471,8 @@ host_char_to_target (struct gdbarch *gdbarch, int c, int *target_c)
   cleanups = make_cleanup_obstack_free (&host_data);
 
   convert_between_encodings (target_charset (gdbarch), host_charset (),
-                            &the_char, 1, 1, &host_data, translit_none);
+                            (gdb_byte *) &the_char, 1, 1,
+                            &host_data, translit_none);
 
   if (obstack_object_size (&host_data) == 1)
     {
@@ -1821,11 +1757,6 @@ init_page_info (void)
          lines_per_page = UINT_MAX;
        }
 
-      /* FIXME: Get rid of this junk.  */
-#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
-      SIGWINCH_HANDLER (SIGWINCH);
-#endif
-
       /* If the output is not a terminal, don't paginate it.  */
       if (!ui_file_isatty (gdb_stdout))
        lines_per_page = UINT_MAX;
@@ -1932,6 +1863,11 @@ prompt_for_continue (void)
 {
   char *ignore;
   char cont_prompt[120];
+  /* Used to add duration we waited for user to respond to
+     prompt_for_continue_wait_time.  */
+  struct timeval prompt_started, prompt_ended, prompt_delta;
+
+  gettimeofday (&prompt_started, NULL);
 
   if (annotation_level > 1)
     printf_unfiltered (("\n\032\032pre-prompt-for-continue\n"));
@@ -1947,6 +1883,7 @@ prompt_for_continue (void)
   reinitialize_more_filter ();
 
   immediate_quit++;
+  QUIT;
   /* On a real operating system, the user can quit with SIGINT.
      But not on GO32.
 
@@ -1959,6 +1896,12 @@ prompt_for_continue (void)
      out to DOS.  */
   ignore = gdb_readline_wrapper (cont_prompt);
 
+  /* Add time spend in this routine to prompt_for_continue_wait_time.  */
+  gettimeofday (&prompt_ended, NULL);
+  timeval_sub (&prompt_delta, &prompt_ended, &prompt_started);
+  timeval_add (&prompt_for_continue_wait_time,
+               &prompt_for_continue_wait_time, &prompt_delta);
+
   if (annotation_level > 1)
     printf_unfiltered (("\n\032\032post-prompt-for-continue\n"));
 
@@ -1969,7 +1912,7 @@ prompt_for_continue (void)
       while (*p == ' ' || *p == '\t')
        ++p;
       if (p[0] == 'q')
-       async_request_quit (0);
+       quit ();
       xfree (ignore);
     }
   immediate_quit--;
@@ -2559,7 +2502,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;
@@ -2790,32 +2733,33 @@ void
 initialize_utils (void)
 {
   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,
+Set number of characters where GDB should wrap lines of its output."), _("\
+Show number of characters where GDB should wrap lines of its output."), _("\
+This affects where GDB wraps its output to fit the screen width.\n\
+Setting this to zero prevents GDB from wrapping its output."),
                            set_width_command,
                            show_chars_per_line,
                            &setlist, &showlist);
 
   add_setshow_uinteger_cmd ("height", class_support, &lines_per_page, _("\
-Set number of lines gdb thinks are in a page."), _("\
-Show number of lines gdb thinks are in a page."), NULL,
+Set number of lines in a page for GDB output pagination."), _("\
+Show number of lines in a page for GDB output pagination."), _("\
+This affects the number of lines after which GDB will pause\n\
+its output and ask you whether to continue.\n\
+Setting this to zero causes GDB never pause during output."),
                            set_height_command,
                            show_lines_per_page,
                            &setlist, &showlist);
 
   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."), _("\
-Show state of pagination."), NULL,
+Set state of GDB output pagination."), _("\
+Show state of GDB output pagination."), _("\
+When pagination is ON, GDB pauses at end of each screenful of\n\
+its output and asks you whether to continue.\n\
+Turning pagination off is an alternative to \"set height 0\"."),
                           NULL,
                           show_pagination_enabled,
                           &setlist, &showlist);
@@ -2836,13 +2780,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."), _("\
@@ -2853,11 +2790,6 @@ When set, debugging messages will be marked with seconds and microseconds."),
                           &setdebuglist, &showdebuglist);
 }
 
-/* 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.  */
 #define NUMCELLS 16
@@ -2911,6 +2843,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)
 {
@@ -3302,125 +3255,27 @@ gdb_realpath (const char *filename)
   }
 #endif
 
-  /* This system is a lost cause, just dup the buffer.  */
-  return xstrdup (filename);
-}
-
-/* Return a copy of FILENAME, with its directory prefix canonicalized
-   by gdb_realpath.  */
-
-char *
-xfullpath (const char *filename)
-{
-  const char *base_name = lbasename (filename);
-  char *dir_name;
-  char *real_path;
-  char *result;
-
-  /* Extract the basename of filename, and return immediately 
-     a copy of filename if it does not contain any directory prefix.  */
-  if (base_name == filename)
-    return xstrdup (filename);
-
-  dir_name = alloca ((size_t) (base_name - filename + 2));
-  /* Allocate enough space to store the dir_name + plus one extra
-     character sometimes needed under Windows (see below), and
-     then the closing \000 character.  */
-  strncpy (dir_name, filename, base_name - filename);
-  dir_name[base_name - filename] = '\000';
+  /* 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);
 
-#ifdef HAVE_DOS_BASED_FILE_SYSTEM
-  /* We need to be careful when filename is of the form 'd:foo', which
-     is equivalent of d:./foo, which is totally different from d:/foo.  */
-  if (strlen (dir_name) == 2 && isalpha (dir_name[0]) && dir_name[1] == ':')
-    {
-      dir_name[2] = '.';
-      dir_name[3] = '\000';
-    }
+    if (len > 0 && len < MAX_PATH)
+      return xstrdup (buf);
+  }
 #endif
 
-  /* Canonicalize the directory prefix, and build the resulting
-     filename.  If the dirname realpath already contains an ending
-     directory separator, avoid doubling it.  */
-  real_path = gdb_realpath (dir_name);
-  if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1]))
-    result = concat (real_path, base_name, (char *) NULL);
-  else
-    result = concat (real_path, SLASH_STRING, base_name, (char *) NULL);
-
-  xfree (real_path);
-  return result;
-}
-
-
-/* This is the 32-bit CRC function used by the GNU separate debug
-   facility.  An executable may contain a section named
-   .gnu_debuglink, which holds the name of a separate executable file
-   containing its debug info, and a checksum of that file's contents,
-   computed using this function.  */
-unsigned long
-gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len)
-{
-  static const unsigned int crc32_table[256] = {
-    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
-    0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
-    0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
-    0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-    0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
-    0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
-    0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
-    0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-    0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
-    0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
-    0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
-    0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
-    0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
-    0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
-    0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-    0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
-    0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
-    0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
-    0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-    0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
-    0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
-    0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
-    0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
-    0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
-    0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
-    0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-    0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
-    0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
-    0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
-    0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-    0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
-    0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
-    0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
-    0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
-    0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
-    0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
-    0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-    0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
-    0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
-    0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
-    0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-    0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
-    0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
-    0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
-    0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
-    0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
-    0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
-    0x2d02ef8d
-  };
-  unsigned char *end;
-
-  crc = ~crc & 0xffffffff;
-  for (end = buf + len; buf < end; ++buf)
-    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
-  return ~crc & 0xffffffff;
+  /* This system is a lost cause, just dup the buffer.  */
+  return xstrdup (filename);
 }
 
 ULONGEST
@@ -3613,6 +3468,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."
@@ -3691,6 +3557,232 @@ 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;
+}
+
+/* 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);
+}
+
+/* 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.043912 seconds and 4 git commands to generate.