Return X86_TDESC_MMX in x86_get_ipa_tdesc_idx
[deliverable/binutils-gdb.git] / gdb / utils.c
index 3a88e2a97162bc3c14fe88ee6617d6cbc4253b46..af50cf09d6a07f3b415f7dbbb556a1d141623642 100644 (file)
@@ -1,6 +1,6 @@
 /* General utility routines for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2016 Free Software Foundation, Inc.
+   Copyright (C) 1986-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -65,6 +65,8 @@
 #include "gdb_usleep.h"
 #include "interps.h"
 #include "gdb_regex.h"
+#include "job-control.h"
+#include "common/selftest.h"
 
 #if !HAVE_DECL_MALLOC
 extern PTR malloc ();          /* ARI: PTR */
@@ -102,10 +104,6 @@ static std::chrono::steady_clock::duration prompt_for_continue_wait_time;
 
 static int debug_timestamp = 0;
 
-/* Nonzero if we have job control.  */
-
-int job_control;
-
 /* 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.)  */
@@ -122,7 +120,7 @@ show_sevenbit_strings (struct ui_file *file, int from_tty,
 
 /* String to be printed before warning messages, if any.  */
 
-char *warning_pre_print = "\nwarning: ";
+const char *warning_pre_print = "\nwarning: ";
 
 int pagination_enabled = 1;
 static void
@@ -139,78 +137,6 @@ show_pagination_enabled (struct ui_file *file, int from_tty,
    because while they use the "cleanup API" they are not part of the
    "cleanup API".  */
 
-static void
-do_freeargv (void *arg)
-{
-  freeargv ((char **) arg);
-}
-
-struct cleanup *
-make_cleanup_freeargv (char **arg)
-{
-  return make_cleanup (do_freeargv, arg);
-}
-
-static void
-do_bfd_close_cleanup (void *arg)
-{
-  gdb_bfd_unref ((bfd *) arg);
-}
-
-struct cleanup *
-make_cleanup_bfd_unref (bfd *abfd)
-{
-  return make_cleanup (do_bfd_close_cleanup, abfd);
-}
-
-/* Helper function which does the work for make_cleanup_fclose.  */
-
-static void
-do_fclose_cleanup (void *arg)
-{
-  FILE *file = (FILE *) arg;
-
-  fclose (file);
-}
-
-/* Return a new cleanup that closes FILE.  */
-
-struct cleanup *
-make_cleanup_fclose (FILE *file)
-{
-  return make_cleanup (do_fclose_cleanup, file);
-}
-
-/* Helper function which does the work for make_cleanup_obstack_free.  */
-
-static void
-do_obstack_free (void *arg)
-{
-  struct obstack *ob = (struct obstack *) arg;
-
-  obstack_free (ob, NULL);
-}
-
-/* Return a new cleanup that frees OBSTACK.  */
-
-struct cleanup *
-make_cleanup_obstack_free (struct obstack *obstack)
-{
-  return make_cleanup (do_obstack_free, obstack);
-}
-
-static void
-do_ui_file_delete (void *arg)
-{
-  ui_file_delete ((struct ui_file *) arg);
-}
-
-struct cleanup *
-make_cleanup_ui_file_delete (struct ui_file *arg)
-{
-  return make_cleanup (do_ui_file_delete, arg);
-}
-
 /* Helper function for make_cleanup_ui_out_redirect_pop.  */
 
 static void
@@ -218,8 +144,7 @@ do_ui_out_redirect_pop (void *arg)
 {
   struct ui_out *uiout = (struct ui_out *) arg;
 
-  if (ui_out_redirect (uiout, NULL) < 0)
-    warning (_("Cannot restore redirection of the current output protocol"));
+  uiout->redirect (NULL);
 }
 
 /* Return a new cleanup that pops the last redirection by ui_out_redirect
@@ -299,24 +224,6 @@ make_cleanup_unpush_target (struct target_ops *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_t) 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);
-}
-
 /* Helper for make_cleanup_value_free_to_mark.  */
 
 static void
@@ -350,46 +257,6 @@ make_cleanup_value_free (struct value *value)
   return make_cleanup (do_value_free, value);
 }
 
-/* Helper for make_cleanup_free_so.  */
-
-static void
-do_free_so (void *arg)
-{
-  struct so_list *so = (struct so_list *) arg;
-
-  free_so (so);
-}
-
-/* Make cleanup handler calling free_so for SO.  */
-
-struct cleanup *
-make_cleanup_free_so (struct so_list *so)
-{
-  return make_cleanup (do_free_so, so);
-}
-
-/* Helper for make_cleanup_restore_current_language.  */
-
-static void
-do_restore_current_language (void *p)
-{
-  enum language saved_lang = (enum language) (uintptr_t) p;
-
-  set_language (saved_lang);
-}
-
-/* Remember the current value of CURRENT_LANGUAGE and make it restored when
-   the cleanup is run.  */
-
-struct cleanup *
-make_cleanup_restore_current_language (void)
-{
-  enum language saved_lang = current_language->la_language;
-
-  return make_cleanup (do_restore_current_language,
-                      (void *) (uintptr_t) saved_lang);
-}
-
 /* Helper function for make_cleanup_clear_parser_state.  */
 
 static void
@@ -476,11 +343,9 @@ verror (const char *string, va_list args)
 }
 
 void
-error_stream (struct ui_file *stream)
+error_stream (const string_file &stream)
 {
-  std::string message = ui_file_as_string (stream);
-
-  error (("%s"), message.c_str ());
+  error (("%s"), stream.c_str ());
 }
 
 /* Emit a message and abort.  */
@@ -886,23 +751,15 @@ add_internal_problem_command (struct internal_problem *problem)
 }
 
 /* Return a newly allocated string, containing the PREFIX followed
-   by the system error message for errno (separated by a colon).
+   by the system error message for errno (separated by a colon).  */
 
-   The result must be deallocated after use.  */
-
-static char *
+static std::string
 perror_string (const char *prefix)
 {
   char *err;
-  char *combined;
 
   err = safe_strerror (errno);
-  combined = (char *) xmalloc (strlen (err) + strlen (prefix) + 3);
-  strcpy (combined, prefix);
-  strcat (combined, ": ");
-  strcat (combined, err);
-
-  return combined;
+  return std::string (prefix) + ": " + err;
 }
 
 /* Print the system error message for errno, and also mention STRING
@@ -912,10 +769,7 @@ perror_string (const char *prefix)
 void
 throw_perror_with_name (enum errors errcode, const char *string)
 {
-  char *combined;
-
-  combined = perror_string (string);
-  make_cleanup (xfree, combined);
+  std::string combined = perror_string (string);
 
   /* I understand setting these is a matter of taste.  Still, some people
      may clear errno but not know about bfd_error.  Doing this here is not
@@ -923,7 +777,7 @@ throw_perror_with_name (enum errors errcode, const char *string)
   bfd_set_error (bfd_error_no_error);
   errno = 0;
 
-  throw_error (errcode, _("%s."), combined);
+  throw_error (errcode, _("%s."), combined.c_str ());
 }
 
 /* See throw_perror_with_name, ERRCODE defaults here to GENERIC_ERROR.  */
@@ -940,11 +794,8 @@ perror_with_name (const char *string)
 void
 perror_warning_with_name (const char *string)
 {
-  char *combined;
-
-  combined = perror_string (string);
-  warning (_("%s"), combined);
-  xfree (combined);
+  std::string combined = perror_string (string);
+  warning (_("%s"), combined.c_str ());
 }
 
 /* Print the system error message for ERRCODE, and also mention STRING
@@ -1083,58 +934,6 @@ make_hex_string (const gdb_byte *data, size_t length)
 
 \f
 
-/* A cleanup function that calls regfree.  */
-
-static void
-do_regfree_cleanup (void *r)
-{
-  regfree ((regex_t *) r);
-}
-
-/* Create a new cleanup that frees the compiled regular expression R.  */
-
-struct cleanup *
-make_regfree_cleanup (regex_t *r)
-{
-  return make_cleanup (do_regfree_cleanup, r);
-}
-
-/* Return an xmalloc'd error message resulting from a regular
-   expression compilation failure.  */
-
-char *
-get_regcomp_error (int code, regex_t *rx)
-{
-  size_t length = regerror (code, rx, NULL, 0);
-  char *result = (char *) xmalloc (length);
-
-  regerror (code, rx, result, length);
-  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);
-}
-
 /* A cleanup that simply calls ui_unregister_input_event_handler.  */
 
 static void
@@ -1181,7 +980,8 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
   int retval;
   int def_value;
   char def_answer, not_def_answer;
-  char *y_string, *n_string, *question, *prompt;
+  const char *y_string, *n_string;
+  char *question, *prompt;
   struct cleanup *old_chain;
 
   /* Set up according to which answer is the default.  */
@@ -1220,7 +1020,9 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
      way, important error messages don't get lost when talking to GDB
      over a pipe.  */
   if (current_ui->instream != current_ui->stdin_stream
-      || !input_interactive_p (current_ui))
+      || !input_interactive_p (current_ui)
+      /* Restrict queries to the main UI.  */
+      || current_ui != main_ui)
     {
       old_chain = make_cleanup_restore_target_terminal ();
 
@@ -1374,13 +1176,10 @@ query (const char *ctlstr, ...)
 static int
 host_char_to_target (struct gdbarch *gdbarch, int c, int *target_c)
 {
-  struct obstack host_data;
   char the_char = c;
-  struct cleanup *cleanups;
   int result = 0;
 
-  obstack_init (&host_data);
-  cleanups = make_cleanup_obstack_free (&host_data);
+  auto_obstack host_data;
 
   convert_between_encodings (target_charset (gdbarch), host_charset (),
                             (gdb_byte *) &the_char, 1, 1,
@@ -1392,7 +1191,6 @@ host_char_to_target (struct gdbarch *gdbarch, int c, int *target_c)
       *target_c = *(char *) obstack_base (&host_data);
     }
 
-  do_cleanups (cleanups);
   return result;
 }
 
@@ -1669,7 +1467,7 @@ init_page_info (void)
       /* 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))
+      if (((rows <= 0) && (tgetnum ((char *) "li") < 0))
        /* Also disable paging if inside Emacs.  $EMACS was used
           before Emacs v25.1, $INSIDE_EMACS is used since then.  */
          || getenv ("EMACS") || getenv ("INSIDE_EMACS"))
@@ -2034,7 +1832,7 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
       || 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 ())))
+      || interp_ui_out (top_level_interpreter ())->is_mi_like_p ())
     {
       fputs_unfiltered (linebuffer, stream);
       return;
@@ -2180,8 +1978,8 @@ puts_debug (char *prefix, char *string, char *suffix)
   /* Print prefix and suffix after each line.  */
   static int new_line = 1;
   static int return_p = 0;
-  static char *prev_prefix = "";
-  static char *prev_suffix = "";
+  static const char *prev_prefix = "";
+  static const char *prev_suffix = "";
 
   if (*string == '\n')
     return_p = 0;
@@ -2482,41 +2280,72 @@ fprintf_symbol_filtered (struct ui_file *stream, const char *name,
     }
 }
 
-/* Do a strcmp() type operation on STRING1 and STRING2, ignoring any
-   differences in whitespace.  Returns 0 if they match, non-zero if they
-   don't (slightly different than strcmp()'s range of return values).
+/* Modes of operation for strncmp_iw_with_mode.  */
+
+enum class strncmp_iw_mode
+{
+  /* Work like strncmp, while ignoring whitespace.  */
+  NORMAL,
 
-   As an extra hack, string1=="FOO(ARGS)" matches string2=="FOO".
-   This "feature" is useful when searching for matching C++ function names
-   (such as if the user types 'break FOO', where FOO is a mangled C++
-   function).  */
+  /* Like NORMAL, but also apply the strcmp_iw hack.  I.e.,
+     string1=="FOO(PARAMS)" matches string2=="FOO".  */
+  MATCH_PARAMS,
+};
 
-int
-strcmp_iw (const char *string1, const char *string2)
+/* Helper for strncmp_iw and strcmp_iw.  */
+
+static int
+strncmp_iw_with_mode (const char *string1, const char *string2,
+                     size_t string2_len, strncmp_iw_mode mode)
 {
-  while ((*string1 != '\0') && (*string2 != '\0'))
+  const char *end_str2 = string2 + string2_len;
+
+  while (1)
     {
       while (isspace (*string1))
-       {
-         string1++;
-       }
-      while (isspace (*string2))
-       {
-         string2++;
-       }
+       string1++;
+      while (string2 < end_str2 && isspace (*string2))
+       string2++;
+      if (*string1 == '\0' || string2 == end_str2)
+       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++;
-         string2++;
-       }
+
+      string1++;
+      string2++;
     }
-  return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0');
+
+  if (string2 == end_str2)
+    {
+      if (mode == strncmp_iw_mode::NORMAL)
+       return 0;
+      else
+       return (*string1 != '\0' && *string1 != '(');
+    }
+  else
+    return 1;
+}
+
+/* See utils.h.  */
+
+int
+strncmp_iw (const char *string1, const char *string2, size_t string2_len)
+{
+  return strncmp_iw_with_mode (string1, string2, string2_len,
+                              strncmp_iw_mode::NORMAL);
+}
+
+/* See utils.h.  */
+
+int
+strcmp_iw (const char *string1, const char *string2)
+{
+  return strncmp_iw_with_mode (string1, string2, strlen (string2),
+                              strncmp_iw_mode::MATCH_PARAMS);
 }
 
 /* This is like strcmp except that it ignores whitespace and treats
@@ -2650,7 +2479,7 @@ streq (const char *lhs, const char *rhs)
    **    at index 0.
  */
 int
-subset_compare (char *string_to_compare, char *template_string)
+subset_compare (const char *string_to_compare, const char *template_string)
 {
   int match;
 
@@ -2820,7 +2649,7 @@ string_to_core_addr (const char *my_string)
   return addr;
 }
 
-char *
+gdb::unique_xmalloc_ptr<char>
 gdb_realpath (const char *filename)
 {
 /* On most hosts, we rely on canonicalize_file_name to compute
@@ -2856,36 +2685,71 @@ gdb_realpath (const char *filename)
        we might not be able to display the original casing in a given
        path.  */
     if (len > 0 && len < MAX_PATH)
-      return xstrdup (buf);
+      return gdb::unique_xmalloc_ptr<char> (xstrdup (buf));
   }
 #else
   {
     char *rp = canonicalize_file_name (filename);
 
     if (rp != NULL)
-      return rp;
+      return gdb::unique_xmalloc_ptr<char> (rp);
   }
 #endif
 
   /* This system is a lost cause, just dup the buffer.  */
-  return xstrdup (filename);
+  return gdb::unique_xmalloc_ptr<char> (xstrdup (filename));
+}
+
+#if GDB_SELF_TEST
+
+static void
+gdb_realpath_check_trailer (const char *input, const char *trailer)
+{
+  gdb::unique_xmalloc_ptr<char> result = gdb_realpath (input);
+
+  size_t len = strlen (result.get ());
+  size_t trail_len = strlen (trailer);
+
+  SELF_CHECK (len >= trail_len
+             && strcmp (result.get () + len - trail_len, trailer) == 0);
 }
 
+static void
+gdb_realpath_tests ()
+{
+  /* A file which contains a directory prefix.  */
+  gdb_realpath_check_trailer ("./xfullpath.exp", "/xfullpath.exp");
+  /* A file which contains a directory prefix.  */
+  gdb_realpath_check_trailer ("../../defs.h", "/defs.h");
+  /* A one-character filename.  */
+  gdb_realpath_check_trailer ("./a", "/a");
+  /* A file in the root directory.  */
+  gdb_realpath_check_trailer ("/root_file_which_should_exist",
+                             "/root_file_which_should_exist");
+  /* A file which does not have a directory prefix.  */
+  gdb_realpath_check_trailer ("xfullpath.exp", "xfullpath.exp");
+  /* A one-char filename without any directory prefix.  */
+  gdb_realpath_check_trailer ("a", "a");
+  /* An empty filename.  */
+  gdb_realpath_check_trailer ("", "");
+}
+
+#endif /* GDB_SELF_TEST */
+
 /* Return a copy of FILENAME, with its directory prefix canonicalized
    by gdb_realpath.  */
 
-char *
+gdb::unique_xmalloc_ptr<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);
+    return gdb::unique_xmalloc_ptr<char> (xstrdup (filename));
 
   dir_name = (char *) alloca ((size_t) (base_name - filename + 2));
   /* Allocate enough space to store the dir_name + plus one extra
@@ -2907,40 +2771,37 @@ gdb_realpath_keepfile (const char *filename)
   /* 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);
+  gdb::unique_xmalloc_ptr<char> path_storage = gdb_realpath (dir_name);
+  const char *real_path = path_storage.get ();
   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 gdb::unique_xmalloc_ptr<char> (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).  */
+   This does not resolve symlinks however, use gdb_realpath for that.  */
 
-char *
+gdb::unique_xmalloc_ptr<char>
 gdb_abspath (const char *path)
 {
   gdb_assert (path != NULL && path[0] != '\0');
 
   if (path[0] == '~')
-    return tilde_expand (path);
+    return gdb::unique_xmalloc_ptr<char> (tilde_expand (path));
 
   if (IS_ABSOLUTE_PATH (path))
-    return xstrdup (path);
+    return gdb::unique_xmalloc_ptr<char> (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);
+  return gdb::unique_xmalloc_ptr<char>
+    (concat (current_directory,
+            IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
+            ? "" : SLASH_STRING,
+            path, (char *) NULL));
 }
 
 ULONGEST
@@ -2986,20 +2847,19 @@ dummy_obstack_deallocate (void *object, void *data)
 /* Simple, portable version of dirname that does not modify its
    argument.  */
 
-char *
+std::string
 ldirname (const char *filename)
 {
+  std::string dirname;
   const char *base = lbasename (filename);
-  char *dirname;
 
   while (base > filename && IS_DIR_SEPARATOR (base[-1]))
     --base;
 
   if (base == filename)
-    return NULL;
+    return dirname;
 
-  dirname = (char *) xmalloc (base - filename + 2);
-  memcpy (dirname, filename, base - filename);
+  dirname = std::string (filename, base - filename);
 
   /* On DOS based file systems, convert "d:foo" to "d:.", so that we
      create "d:./bar" later instead of the (different) "d:/bar".  */
@@ -3007,23 +2867,21 @@ ldirname (const char *filename)
       && !IS_DIR_SEPARATOR (filename[0]))
     dirname[base++ - filename] = '.';
 
-  dirname[base - filename] = '\0';
   return dirname;
 }
 
-/* Call libiberty's buildargv, and return the result.
-   If buildargv fails due to out-of-memory, call nomem.
-   Therefore, the returned value is guaranteed to be non-NULL,
-   unless the parameter itself is NULL.  */
+/* See utils.h.  */
 
-char **
-gdb_buildargv (const char *s)
+void
+gdb_argv::reset (const char *s)
 {
   char **argv = buildargv (s);
 
   if (s != NULL && argv == NULL)
     malloc_failure (0);
-  return argv;
+
+  freeargv (m_argv);
+  m_argv = argv;
 }
 
 int
@@ -3447,4 +3305,8 @@ _initialize_utils (void)
   add_internal_problem_command (&internal_error_problem);
   add_internal_problem_command (&internal_warning_problem);
   add_internal_problem_command (&demangler_warning_problem);
+
+#if GDB_SELF_TEST
+  selftests::register_test (gdb_realpath_tests);
+#endif
 }
This page took 0.032277 seconds and 4 git commands to generate.