frame: add frame_id_build_unavailable_stack_special
[deliverable/binutils-gdb.git] / gdb / utils.c
index 6065d8221b3f7dc476acd165e3b925c3cf60bf4b..e062e89801c33533fdf3a0b3cfdb6f46be04d61b 100644 (file)
@@ -1,6 +1,6 @@
 /* General utility routines for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2013 Free Software Foundation, Inc.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -21,7 +21,7 @@
 #include "dyn-string.h"
 #include "gdb_assert.h"
 #include <ctype.h>
-#include "gdb_string.h"
+#include <string.h>
 #include "gdb_wait.h"
 #include "event-top.h"
 #include "exceptions.h"
 #include <pc.h>
 #endif
 
-/* SunOS's curses.h has a '#define reg register' in it.  Thank you Sun.  */
-#ifdef reg
-#undef reg
-#endif
-
 #include <signal.h>
 #include "timeval-utils.h"
 #include "gdbcmd.h"
@@ -66,8 +61,6 @@
 
 #include "inferior.h"          /* for signed_pointer_to_address */
 
-#include <sys/param.h>         /* For MAXPATHLEN */
-
 #include "gdb_curses.h"
 
 #include "readline/readline.h"
@@ -187,14 +180,6 @@ show_sevenbit_strings (struct ui_file *file, int from_tty,
                    value);
 }
 
-/* String to be printed before error messages, if any.  */
-
-char *error_pre_print;
-
-/* String to be printed before quit messages, if any.  */
-
-char *quit_pre_print;
-
 /* String to be printed before warning messages, if any.  */
 
 char *warning_pre_print = "\nwarning: ";
@@ -544,117 +529,6 @@ free_current_contents (void *ptr)
       *location = NULL;
     }
 }
-
-/* 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_cpu_time;
-  struct timeval start_wall_time;
-  long start_space;
-};
-
-/* Set whether to display time statistics to NEW_VALUE (non-zero 
-   means true).  */
-void
-set_display_time (int new_value)
-{
-  display_time = new_value;
-}
-
-/* Set whether to display space statistics to NEW_VALUE (non-zero
-   means true).  */
-void
-set_display_space (int new_value)
-{
-  display_space = new_value;
-}
-
-/* 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_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 (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)
-    {
-#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 (%s%ld during startup)\n")
-                        : _("Space used: %ld (%s%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)
-{
-  static const struct timeval zero_timeval = { 0 };
-  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_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);
-}
 \f
 
 
@@ -824,6 +698,7 @@ internal_vproblem (struct internal_problem *problem,
   int quit_p;
   int dump_core_p;
   char *reason;
+  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
 
   /* Don't allow infinite error/warning recursion.  */
   {
@@ -932,6 +807,7 @@ internal_vproblem (struct internal_problem *problem,
     }
 
   dejavu = 0;
+  do_cleanups (cleanup);
 }
 
 static struct internal_problem internal_error_problem = {
@@ -942,7 +818,7 @@ 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);
+  fatal (_("Command aborted."));
 }
 
 void
@@ -1076,29 +952,66 @@ add_internal_problem_command (struct internal_problem *problem)
   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.  */
+/* Return a newly allocated string, containing the PREFIX followed
+   by the system error message for errno (separated by a colon).
 
-void
-perror_with_name (const char *string)
+   The result must be deallocated after use.  */
+
+static char *
+perror_string (const char *prefix)
 {
   char *err;
   char *combined;
 
   err = safe_strerror (errno);
-  combined = (char *) alloca (strlen (err) + strlen (string) + 3);
-  strcpy (combined, string);
+  combined = (char *) xmalloc (strlen (err) + strlen (prefix) + 3);
+  strcpy (combined, prefix);
   strcat (combined, ": ");
   strcat (combined, err);
 
+  return combined;
+}
+
+/* Print the system error message for errno, and also mention STRING
+   as the file name for which the error was encountered.  Use ERRCODE
+   for the thrown exception.  Then return to command level.  */
+
+void
+throw_perror_with_name (enum errors errcode, const char *string)
+{
+  char *combined;
+
+  combined = perror_string (string);
+  make_cleanup (xfree, combined);
+
   /* 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.  */
   bfd_set_error (bfd_error_no_error);
   errno = 0;
 
-  error (_("%s."), combined);
+  throw_error (errcode, _("%s."), combined);
+}
+
+/* See throw_perror_with_name, ERRCODE defaults here to GENERIC_ERROR.  */
+
+void
+perror_with_name (const char *string)
+{
+  throw_perror_with_name (GENERIC_ERROR, string);
+}
+
+/* Same as perror_with_name except that it prints a warning instead
+   of throwing an error.  */
+
+void
+perror_warning_with_name (const char *string)
+{
+  char *combined;
+
+  combined = perror_string (string);
+  warning (_("%s"), combined);
+  xfree (combined);
 }
 
 /* Print the system error message for ERRCODE, and also mention STRING
@@ -1227,6 +1140,29 @@ get_regcomp_error (int code, regex_t *rx)
   return result;
 }
 
+/* Compile a regexp and throw an exception on error.  This returns a
+   cleanup to free the resulting pattern on success.  RX must not be
+   NULL.  */
+
+struct cleanup *
+compile_rx_or_error (regex_t *pattern, const char *rx, const char *message)
+{
+  int code;
+
+  gdb_assert (rx != NULL);
+
+  code = regcomp (pattern, rx, REG_NOSUB);
+  if (code != 0)
+    {
+      char *err = get_regcomp_error (code, pattern);
+
+      make_cleanup (xfree, err);
+      error (("%s: %s"), message, err);
+    }
+
+  return make_regfree_cleanup (pattern);
+}
+
 \f
 
 /* This function supports the query, nquery, and yquery functions.
@@ -1471,7 +1407,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)
     {
@@ -1499,7 +1436,7 @@ host_char_to_target (struct gdbarch *gdbarch, int c, int *target_c)
    after the zeros.  A value of 0 does not mean end of string.  */
 
 int
-parse_escape (struct gdbarch *gdbarch, char **string_ptr)
+parse_escape (struct gdbarch *gdbarch, const char **string_ptr)
 {
   int target_char = -2;        /* Initialize to avoid GCC warnings.  */
   int c = *(*string_ptr)++;
@@ -1747,12 +1684,16 @@ init_page_info (void)
       lines_per_page = rows;
       chars_per_line = cols;
 
-      /* Readline should have fetched the termcap entry for us.  */
-      if (tgetnum ("li") < 0 || getenv ("EMACS"))
+      /* Readline should have fetched the termcap entry for us.
+         Only try to use tgetnum function if rl_get_screen_size
+         did not return a useful value. */
+      if (((rows <= 0) && (tgetnum ("li") < 0))
+       /* Also disable paging if inside EMACS.  */
+         || getenv ("EMACS"))
        {
-         /* The number of lines per page is not mentioned in the
-            terminal description.  This probably means that paging is
-            not useful (e.g. emacs shell window), so disable paging.  */
+         /* The number of lines per page is not mentioned in the terminal
+            description or EMACS evironment variable is set.  This probably
+            means that paging is not useful, so disable paging.  */
          lines_per_page = UINT_MAX;
        }
 
@@ -1923,6 +1864,24 @@ prompt_for_continue (void)
   dont_repeat ();              /* Forget prev cmd -- CR won't repeat it.  */
 }
 
+/* Initalize timer to keep track of how long we waited for the user.  */
+
+void
+reset_prompt_for_continue_wait_time (void)
+{
+  static const struct timeval zero_timeval = { 0 };
+
+  prompt_for_continue_wait_time = zero_timeval;
+}
+
+/* Fetch the cumulative time spent in prompt_for_continue.  */
+
+struct timeval
+get_prompt_for_continue_wait_time (void)
+{
+  return prompt_for_continue_wait_time;
+}
+
 /* Reinitialize filter; ie. tell it to reset to original values.  */
 
 void
@@ -2735,7 +2694,7 @@ initialize_utils (void)
 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."),
+Setting this to \"unlimited\" or zero prevents GDB from wrapping its output."),
                            set_width_command,
                            show_chars_per_line,
                            &setlist, &showlist);
@@ -2745,7 +2704,7 @@ 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."),
+Setting this to \"unlimited\" or zero causes GDB never pause during output."),
                            set_height_command,
                            show_lines_per_page,
                            &setlist, &showlist);
@@ -2758,7 +2717,7 @@ 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\"."),
+Turning pagination off is an alternative to \"set height unlimited\"."),
                           NULL,
                           show_pagination_enabled,
                           &setlist, &showlist);
@@ -3189,22 +3148,14 @@ gdb_realpath (const char *filename)
      path.  Use that and realpath() to canonicalize the name.  This is
      the most common case.  Note that, if there isn't a compile time
      upper bound, you want to avoid realpath() at all costs.  */
-#if defined(HAVE_REALPATH)
+#if defined (HAVE_REALPATH) && defined (PATH_MAX)
   {
-# if defined (PATH_MAX)
     char buf[PATH_MAX];
-#  define USE_REALPATH
-# elif defined (MAXPATHLEN)
-    char buf[MAXPATHLEN];
-#  define USE_REALPATH
-# endif
-# if defined (USE_REALPATH)
     const char *rp = realpath (filename, buf);
 
     if (rp == NULL)
       rp = filename;
     return xstrdup (rp);
-# endif
   }
 #endif /* HAVE_REALPATH */
 
@@ -3238,7 +3189,7 @@ gdb_realpath (const char *filename)
      pathconf()) making it impossible to pass a correctly sized buffer
      to realpath() (it could always overflow).  On those systems, we
      skip this.  */
-#if defined (HAVE_REALPATH) && defined (HAVE_UNISTD_H) && defined(HAVE_ALLOCA)
+#if defined (HAVE_REALPATH) && defined (_PC_PATH_MAX) && defined(HAVE_ALLOCA)
   {
     /* Find out the max path size.  */
     long path_max = pathconf ("/", _PC_PATH_MAX);
@@ -3277,6 +3228,78 @@ gdb_realpath (const char *filename)
   return xstrdup (filename);
 }
 
+/* Return a copy of FILENAME, with its directory prefix canonicalized
+   by gdb_realpath.  */
+
+char *
+gdb_realpath_keepfile (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';
+
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  /* We need to be careful when filename is of the form 'd:foo', which
+     is equivalent of d:./foo, which is totally different from d:/foo.  */
+  if (strlen (dir_name) == 2 && isalpha (dir_name[0]) && dir_name[1] == ':')
+    {
+      dir_name[2] = '.';
+      dir_name[3] = '\000';
+    }
+#endif
+
+  /* Canonicalize the directory prefix, and build the resulting
+     filename.  If the dirname realpath already contains an ending
+     directory separator, avoid doubling it.  */
+  real_path = gdb_realpath (dir_name);
+  if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1]))
+    result = concat (real_path, base_name, (char *) NULL);
+  else
+    result = concat (real_path, SLASH_STRING, base_name, (char *) NULL);
+
+  xfree (real_path);
+  return result;
+}
+
+/* Return PATH in absolute form, performing tilde-expansion if necessary.
+   PATH cannot be NULL or the empty string.
+   This does not resolve symlinks however, use gdb_realpath for that.
+   Space for the result is allocated with malloc.
+   If the path is already absolute, it is strdup'd.
+   If there is a problem computing the absolute path, the path is returned
+   unchanged (still strdup'd).  */
+
+char *
+gdb_abspath (const char *path)
+{
+  gdb_assert (path != NULL && path[0] != '\0');
+
+  if (path[0] == '~')
+    return tilde_expand (path);
+
+  if (IS_ABSOLUTE_PATH (path))
+    return xstrdup (path);
+
+  /* Beware the // my son, the Emacs barfs, the botch that catch...  */
+  return concat (current_directory,
+           IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
+                ? "" : SLASH_STRING,
+                path, (char *) NULL);
+}
+
 ULONGEST
 align_up (ULONGEST v, int n)
 {
@@ -3293,6 +3316,23 @@ align_down (ULONGEST v, int n)
   return (v & -n);
 }
 
+/* See utils.h.  */
+
+LONGEST
+gdb_sign_extend (LONGEST value, int bit)
+{
+  gdb_assert (bit >= 1 && bit <= 8 * sizeof (LONGEST));
+
+  if (((value >> (bit - 1)) & 1) != 0)
+    {
+      LONGEST signbit = ((LONGEST) 1) << (bit - 1);
+
+      value = (value ^ signbit) - signbit;
+    }
+
+  return value;
+}
+
 /* Allocation function for the libiberty hash table which uses an
    obstack.  The obstack is passed as DATA.  */
 
This page took 0.030713 seconds and 4 git commands to generate.