Change boolean options to bool instead of int
[deliverable/binutils-gdb.git] / gdb / utils.c
index a2e933bc8dc41348a7a689c3186a71e67100712f..b2535ebefd3805c27ebcc41b94d2a0cdc0eaeab1 100644 (file)
@@ -1,6 +1,6 @@
 /* General utility routines for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2018 Free Software Foundation, Inc.
+   Copyright (C) 1986-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -19,7 +19,7 @@
 
 #include "defs.h"
 #include <ctype.h>
-#include "gdb_wait.h"
+#include "gdbsupport/gdb_wait.h"
 #include "event-top.h"
 #include "gdbthread.h"
 #include "fnmatch.h"
 #include "gdb_usleep.h"
 #include "interps.h"
 #include "gdb_regex.h"
-#include "job-control.h"
-#include "common/selftest.h"
-#include "common/gdb_optional.h"
+#include "gdbsupport/job-control.h"
+#include "gdbsupport/selftest.h"
+#include "gdbsupport/gdb_optional.h"
 #include "cp-support.h"
 #include <algorithm>
-#include "common/pathstuff.h"
-
-#if !HAVE_DECL_MALLOC
-extern PTR malloc ();          /* ARI: PTR */
-#endif
-#if !HAVE_DECL_REALLOC
-extern PTR realloc ();         /* ARI: PTR */
-#endif
-#if !HAVE_DECL_FREE
-extern void free ();
-#endif
+#include "gdbsupport/pathstuff.h"
+#include "cli/cli-style.h"
+#include "gdbsupport/scope-exit.h"
+#include "gdbarch.h"
 
 void (*deprecated_error_begin_hook) (void);
 
@@ -106,13 +99,13 @@ static std::chrono::steady_clock::duration prompt_for_continue_wait_time;
 
 /* A flag indicating whether to timestamp debugging messages.  */
 
-static int debug_timestamp = 0;
+static bool debug_timestamp = false;
 
-/* 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
+/* True means that strings with character values >0x7F should be printed
+   as octal escapes.  False means just print the value (e.g. it's an
    international character, and the terminal or window can cope.)  */
 
-int sevenbit_strings = 0;
+bool sevenbit_strings = false;
 static void
 show_sevenbit_strings (struct ui_file *file, int from_tty,
                       struct cmd_list_element *c, const char *value)
@@ -126,7 +119,7 @@ show_sevenbit_strings (struct ui_file *file, int from_tty,
 
 const char *warning_pre_print = "\nwarning: ";
 
-int pagination_enabled = 1;
+bool pagination_enabled = true;
 static void
 show_pagination_enabled (struct ui_file *file, int from_tty,
                         struct cmd_list_element *c, const char *value)
@@ -135,52 +128,6 @@ show_pagination_enabled (struct ui_file *file, int from_tty,
 }
 
 \f
-/* Cleanup utilities.
-
-   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".  */
-
-/* Helper for make_cleanup_value_free_to_mark.  */
-
-static void
-do_value_free_to_mark (void *value)
-{
-  value_free_to_mark ((struct value *) value);
-}
-
-/* Free all values allocated since MARK was obtained by value_mark
-   (except for those released) when the cleanup is run.  */
-
-struct cleanup *
-make_cleanup_value_free_to_mark (struct value *mark)
-{
-  return make_cleanup (do_value_free_to_mark, mark);
-}
-
-/* This function is useful for cleanups.
-   Do
-
-   foo = xmalloc (...);
-   old_chain = make_cleanup (free_current_contents, &foo);
-
-   to arrange to free the object thus allocated.  */
-
-void
-free_current_contents (void *ptr)
-{
-  void **location = (void **) ptr;
-
-  if (location == NULL)
-    internal_error (__FILE__, __LINE__,
-                   _("free_current_contents: NULL pointer"));
-  if (*location != NULL)
-    {
-      xfree (*location);
-      *location = NULL;
-    }
-}
-\f
 
 
 /* Print a warning message.  The first argument STRING is the warning
@@ -247,7 +194,7 @@ void
 dump_core (void)
 {
 #ifdef HAVE_SETRLIMIT
-  struct rlimit rlim = { RLIM_INFINITY, RLIM_INFINITY };
+  struct rlimit rlim = { (rlim_t) RLIM_INFINITY, (rlim_t) RLIM_INFINITY };
 
   setrlimit (RLIMIT_CORE, &rlim);
 #endif /* HAVE_SETRLIMIT */
@@ -354,7 +301,7 @@ internal_vproblem (struct internal_problem *problem,
 
   /* Don't allow infinite error/warning recursion.  */
   {
-    static char msg[] = "Recursive internal problem.\n";
+    static const char msg[] = "Recursive internal problem.\n";
 
     switch (dejavu)
       {
@@ -584,10 +531,10 @@ add_internal_problem_command (struct internal_problem *problem)
   if (problem->user_settable_should_quit)
     {
       set_doc = xstrprintf (_("Set whether GDB should quit "
-                             "when an %s is detected"),
+                             "when an %s is detected."),
                            problem->name);
       show_doc = xstrprintf (_("Show whether GDB will quit "
-                              "when an %s is detected"),
+                              "when an %s is detected."),
                             problem->name);
       add_setshow_enum_cmd ("quit", class_maintenance,
                            internal_problem_modes,
@@ -607,10 +554,10 @@ add_internal_problem_command (struct internal_problem *problem)
   if (problem->user_settable_should_dump_core)
     {
       set_doc = xstrprintf (_("Set whether GDB should create a core "
-                             "file of GDB when %s is detected"),
+                             "file of GDB when %s is detected."),
                            problem->name);
       show_doc = xstrprintf (_("Show whether GDB will create a core "
-                              "file of GDB when %s is detected"),
+                              "file of GDB when %s is detected."),
                             problem->name);
       add_setshow_enum_cmd ("corefile", class_maintenance,
                            internal_problem_modes,
@@ -732,9 +679,6 @@ maybe_quit (void)
     quit ();
 
   quit_handler ();
-
-  if (deprecated_interactive_hook)
-    deprecated_interactive_hook ();
 }
 
 \f
@@ -915,7 +859,6 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
       printf_filtered (_("(%s or %s) [answered %c; "
                         "input not from terminal]\n"),
                       y_string, n_string, def_answer);
-      gdb_flush (gdb_stdout);
 
       return def_value;
     }
@@ -1283,6 +1226,10 @@ show_chars_per_line (struct ui_file *file, int from_tty,
 /* Current count of lines printed on this page, chars on this line.  */
 static unsigned int lines_printed, chars_printed;
 
+/* True if pagination is disabled for just one command.  */
+
+static bool pagination_disabled_for_command;
+
 /* Buffer and start column of buffered text, for doing smarter word-
    wrapping.  When someone calls wrap_here(), we start buffering output
    that comes through fputs_filtered().  If we see a newline, we just
@@ -1291,13 +1238,11 @@ static unsigned int lines_printed, chars_printed;
    the end of the line, we spit out a newline, the indent, and then
    the buffered output.  */
 
-/* Malloc'd buffer with chars_per_line+2 bytes.  Contains characters which
-   are waiting to be output (they have already been counted in chars_printed).
-   When wrap_buffer[0] is null, the buffer is empty.  */
-static char *wrap_buffer;
+static bool filter_initialized = false;
 
-/* Pointer in wrap_buffer to the next character to fill.  */
-static char *wrap_pointer;
+/* Contains characters which are waiting to be output (they have
+   already been counted in chars_printed).  */
+static std::string wrap_buffer;
 
 /* String to indent by if the wrap occurs.  Must not be NULL if wrap_column
    is non-zero.  */
@@ -1306,6 +1251,9 @@ static const char *wrap_indent;
 /* Column number on the screen where wrap_buffer begins, or 0 if wrapping
    is not in effect.  */
 static int wrap_column;
+
+/* The style applied at the time that wrap_here was called.  */
+static ui_file_style wrap_style;
 \f
 
 /* Initialize the number of lines per page and chars per line.  */
@@ -1370,7 +1318,7 @@ init_page_info (void)
 int
 filtered_printing_initialized (void)
 {
-  return wrap_buffer != NULL;
+  return filter_initialized;
 }
 
 set_batch_flag_and_restore_page_info::set_batch_flag_and_restore_page_info ()
@@ -1400,18 +1348,36 @@ set_screen_size (void)
   int rows = lines_per_page;
   int cols = chars_per_line;
 
-  if (rows <= 0)
-    rows = INT_MAX;
+  /* If we get 0 or negative ROWS or COLS, treat as "infinite" size.
+     A negative number can be seen here with the "set width/height"
+     commands and either:
+
+     - the user specified "unlimited", which maps to UINT_MAX, or
+     - the user spedified some number between INT_MAX and UINT_MAX.
+
+     Cap "infinity" to approximately sqrt(INT_MAX) so that we don't
+     overflow in rl_set_screen_size, which multiplies rows and columns
+     to compute the number of characters on the screen.  */
+
+  const int sqrt_int_max = INT_MAX >> (sizeof (int) * 8 / 2);
+
+  if (rows <= 0 || rows > sqrt_int_max)
+    {
+      rows = sqrt_int_max;
+      lines_per_page = UINT_MAX;
+    }
 
-  if (cols <= 0)
-    cols = INT_MAX;
+  if (cols <= 0 || cols > sqrt_int_max)
+    {
+      cols = sqrt_int_max;
+      chars_per_line = UINT_MAX;
+    }
 
   /* Update Readline's idea of the terminal size.  */
   rl_set_screen_size (rows, cols);
 }
 
-/* Reinitialize WRAP_BUFFER according to the current value of
-   CHARS_PER_LINE.  */
+/* Reinitialize WRAP_BUFFER.  */
 
 static void
 set_width (void)
@@ -1419,14 +1385,8 @@ set_width (void)
   if (chars_per_line == 0)
     init_page_info ();
 
-  if (!wrap_buffer)
-    {
-      wrap_buffer = (char *) xmalloc (chars_per_line + 2);
-      wrap_buffer[0] = '\0';
-    }
-  else
-    wrap_buffer = (char *) xrealloc (wrap_buffer, chars_per_line + 2);
-  wrap_pointer = wrap_buffer;  /* Start it at the beginning.  */
+  wrap_buffer.clear ();
+  filter_initialized = true;
 }
 
 static void
@@ -1454,6 +1414,55 @@ set_screen_width_and_height (int width, int height)
   set_width ();
 }
 
+/* The currently applied style.  */
+
+static ui_file_style applied_style;
+
+/* Emit an ANSI style escape for STYLE.  If STREAM is nullptr, emit to
+   the wrap buffer; otherwise emit to STREAM.  */
+
+static void
+emit_style_escape (const ui_file_style &style,
+                  struct ui_file *stream = nullptr)
+{
+  applied_style = style;
+
+  if (stream == nullptr)
+    wrap_buffer.append (style.to_ansi ());
+  else
+    fputs_unfiltered (style.to_ansi ().c_str (), stream);
+}
+
+/* Set the current output style.  This will affect future uses of the
+   _filtered output functions.  */
+
+static void
+set_output_style (struct ui_file *stream, const ui_file_style &style)
+{
+  if (!stream->can_emit_style_escape ())
+    return;
+
+  /* Note that we may not pass STREAM here, when we want to emit to
+     the wrap buffer, not directly to STREAM.  */
+  if (stream == gdb_stdout)
+    stream = nullptr;
+  emit_style_escape (style, stream);
+}
+
+/* See utils.h.  */
+
+void
+reset_terminal_style (struct ui_file *stream)
+{
+  if (stream->can_emit_style_escape ())
+    {
+      /* Force the setting, regardless of what we think the setting
+        might already be.  */
+      applied_style = ui_file_style ();
+      wrap_buffer.append (applied_style.to_ansi ());
+    }
+}
+
 /* Wait, so the user can read what's on the screen.  Prompt the user
    to continue by pressing RETURN.  'q' is also provided because
    telling users what to do in the prompt is more user-friendly than
@@ -1467,12 +1476,18 @@ prompt_for_continue (void)
      prompt_for_continue_wait_time.  */
   using namespace std::chrono;
   steady_clock::time_point prompt_started = steady_clock::now ();
+  bool disable_pagination = pagination_disabled_for_command;
+
+  /* Clear the current styling.  */
+  if (gdb_stdout->can_emit_style_escape ())
+    emit_style_escape (ui_file_style (), gdb_stdout);
 
   if (annotation_level > 1)
     printf_unfiltered (("\n\032\032pre-prompt-for-continue\n"));
 
   strcpy (cont_prompt,
-         "---Type <return> to continue, or q <return> to quit---");
+         "--Type <RET> for more, q to quit, "
+         "c to continue without paging--");
   if (annotation_level > 1)
     strcat (cont_prompt, "\n\032\032prompt-for-continue\n");
 
@@ -1502,11 +1517,14 @@ prompt_for_continue (void)
       if (p[0] == 'q')
        /* Do not call quit here; there is no possibility of SIGINT.  */
        throw_quit ("Quit");
+      if (p[0] == 'c')
+       disable_pagination = true;
     }
 
   /* Now we have to do this again, so that GDB will know that it doesn't
      need to save the ---Type <return>--- line at the top of the screen.  */
   reinitialize_more_filter ();
+  pagination_disabled_for_command = disable_pagination;
 
   dont_repeat ();              /* Forget prev cmd -- CR won't repeat it.  */
 }
@@ -1536,6 +1554,19 @@ reinitialize_more_filter (void)
 {
   lines_printed = 0;
   chars_printed = 0;
+  pagination_disabled_for_command = false;
+}
+
+/* Flush the wrap buffer to STREAM, if necessary.  */
+
+static void
+flush_wrap_buffer (struct ui_file *stream)
+{
+  if (stream == gdb_stdout && !wrap_buffer.empty ())
+    {
+      fputs_unfiltered (wrap_buffer.c_str (), stream);
+      wrap_buffer.clear ();
+    }
 }
 
 /* Indicate that if the next sequence of characters overflows the line,
@@ -1563,17 +1594,11 @@ void
 wrap_here (const char *indent)
 {
   /* This should have been allocated, but be paranoid anyway.  */
-  if (!wrap_buffer)
+  if (!filter_initialized)
     internal_error (__FILE__, __LINE__,
                    _("failed internal consistency check"));
 
-  if (wrap_buffer[0])
-    {
-      *wrap_pointer = '\0';
-      fputs_unfiltered (wrap_buffer, gdb_stdout);
-    }
-  wrap_pointer = wrap_buffer;
-  wrap_buffer[0] = '\0';
+  flush_wrap_buffer (gdb_stdout);
   if (chars_per_line == UINT_MAX)      /* No line overflow checking.  */
     {
       wrap_column = 0;
@@ -1592,6 +1617,7 @@ wrap_here (const char *indent)
        wrap_indent = "";
       else
        wrap_indent = indent;
+      wrap_style = applied_style;
     }
 }
 
@@ -1680,15 +1706,25 @@ 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
+      || pagination_disabled_for_command
       || batch_flag
       || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX)
       || top_level_interpreter () == NULL
       || top_level_interpreter ()->interp_ui_out ()->is_mi_like_p ())
     {
+      flush_wrap_buffer (stream);
       fputs_unfiltered (linebuffer, stream);
       return;
     }
 
+  auto buffer_clearer
+    = make_scope_exit ([&] ()
+                      {
+                        wrap_buffer.clear ();
+                        wrap_column = 0;
+                        wrap_indent = "";
+                      });
+
   /* Go through and output each character.  Show line extension
      when this is necessary; prompt user for new page when this is
      necessary.  */
@@ -1696,31 +1732,38 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
   lineptr = linebuffer;
   while (*lineptr)
     {
-      /* Possible new page.  */
-      if (filter && (lines_printed >= lines_per_page - 1))
+      /* Possible new page.  Note that PAGINATION_DISABLED_FOR_COMMAND
+        might be set during this loop, so we must continue to check
+        it here.  */
+      if (filter && (lines_printed >= lines_per_page - 1)
+         && !pagination_disabled_for_command)
        prompt_for_continue ();
 
       while (*lineptr && *lineptr != '\n')
        {
+         int skip_bytes;
+
          /* Print a single line.  */
          if (*lineptr == '\t')
            {
-             if (wrap_column)
-               *wrap_pointer++ = '\t';
-             else
-               fputc_unfiltered ('\t', stream);
+             wrap_buffer.push_back ('\t');
              /* Shifting right by 3 produces the number of tab stops
                 we have already passed, and then adding one and
                 shifting left 3 advances to the next tab stop.  */
              chars_printed = ((chars_printed >> 3) + 1) << 3;
              lineptr++;
            }
+         else if (*lineptr == '\033'
+                  && skip_ansi_escape (lineptr, &skip_bytes))
+           {
+             wrap_buffer.append (lineptr, skip_bytes);
+             /* Note that we don't consider this a character, so we
+                don't increment chars_printed here.  */
+             lineptr += skip_bytes;
+           }
          else
            {
-             if (wrap_column)
-               *wrap_pointer++ = *lineptr;
-             else
-               fputc_unfiltered (*lineptr, stream);
+             wrap_buffer.push_back (*lineptr);
              chars_printed++;
              lineptr++;
            }
@@ -1729,24 +1772,50 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
            {
              unsigned int save_chars = chars_printed;
 
+             /* If we change the style, below, we'll want to reset it
+                before continuing to print.  If there is no wrap
+                column, then we'll only reset the style if the pager
+                prompt is given; and to avoid emitting style
+                sequences in the middle of a run of text, we track
+                this as well.  */
+             ui_file_style save_style;
+             bool did_paginate = false;
+
              chars_printed = 0;
              lines_printed++;
-             /* If we aren't actually wrapping, don't output newline --
-                if chars_per_line is right, we probably just overflowed
-                anyway; if it's wrong, let us keep going.  */
              if (wrap_column)
-               fputc_unfiltered ('\n', stream);
+               {
+                 save_style = wrap_style;
+                 if (stream->can_emit_style_escape ())
+                   emit_style_escape (ui_file_style (), stream);
+                 /* If we aren't actually wrapping, don't output
+                    newline -- if chars_per_line is right, we
+                    probably just overflowed anyway; if it's wrong,
+                    let us keep going.  */
+                 fputc_unfiltered ('\n', stream);
+               }
+             else
+               {
+                 save_style = applied_style;
+                 flush_wrap_buffer (stream);
+               }
 
-             /* Possible new page.  */
-             if (lines_printed >= lines_per_page - 1)
-               prompt_for_continue ();
+             /* Possible new page.  Note that
+                PAGINATION_DISABLED_FOR_COMMAND might be set during
+                this loop, so we must continue to check it here.  */
+             if (lines_printed >= lines_per_page - 1
+                 && !pagination_disabled_for_command)
+               {
+                 prompt_for_continue ();
+                 did_paginate = true;
+               }
 
              /* Now output indentation and wrapped string.  */
              if (wrap_column)
                {
                  fputs_unfiltered (wrap_indent, stream);
-                 *wrap_pointer = '\0'; /* Null-terminate saved stuff, */
-                 fputs_unfiltered (wrap_buffer, stream); /* and eject it.  */
+                 if (stream->can_emit_style_escape ())
+                   emit_style_escape (save_style, stream);
                  /* FIXME, this strlen is what prevents wrap_indent from
                     containing tabs.  However, if we recurse to print it
                     and count its chars, we risk trouble if wrap_indent is
@@ -1755,10 +1824,10 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
                     if we are printing a long string.  */
                  chars_printed = strlen (wrap_indent)
                    + (save_chars - wrap_column);
-                 wrap_pointer = wrap_buffer;   /* Reset buffer */
-                 wrap_buffer[0] = '\0';
                  wrap_column = 0;      /* And disable fancy wrap */
                }
+             else if (did_paginate && stream->can_emit_style_escape ())
+               emit_style_escape (save_style, stream);
            }
        }
 
@@ -1772,6 +1841,8 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
          lineptr++;
        }
     }
+
+  buffer_clearer.release ();
 }
 
 void
@@ -1780,6 +1851,60 @@ fputs_filtered (const char *linebuffer, struct ui_file *stream)
   fputs_maybe_filtered (linebuffer, stream, 1);
 }
 
+/* See utils.h.  */
+
+void
+fputs_styled (const char *linebuffer, const ui_file_style &style,
+             struct ui_file *stream)
+{
+  /* This just makes it so we emit somewhat fewer escape
+     sequences.  */
+  if (style.is_default ())
+    fputs_maybe_filtered (linebuffer, stream, 1);
+  else
+    {
+      set_output_style (stream, style);
+      fputs_maybe_filtered (linebuffer, stream, 1);
+      set_output_style (stream, ui_file_style ());
+    }
+}
+
+/* See utils.h.  */
+
+void
+fputs_highlighted (const char *str, const compiled_regex &highlight,
+                  struct ui_file *stream)
+{
+  regmatch_t pmatch;
+
+  while (*str && highlight.exec (str, 1, &pmatch, 0) == 0)
+    {
+      size_t n_highlight = pmatch.rm_eo - pmatch.rm_so;
+
+      /* Output the part before pmatch with current style.  */
+      while (pmatch.rm_so > 0)
+       {
+         fputc_filtered (*str, stream);
+         pmatch.rm_so--;
+         str++;
+       }
+
+      /* Output pmatch with the highlight style.  */
+      set_output_style (stream, highlight_style.style ());
+      while (n_highlight > 0)
+       {
+         fputc_filtered (*str, stream);
+         n_highlight--;
+         str++;
+       }
+      set_output_style (stream, ui_file_style ());
+    }
+
+  /* Output the trailing part of STR not matching HIGHLIGHT.  */
+  if (*str)
+    fputs_filtered (str, stream);
+}
+
 int
 putchar_unfiltered (int c)
 {
@@ -2007,6 +2132,21 @@ fprintfi_filtered (int spaces, struct ui_file *stream, const char *format,
   va_end (args);
 }
 
+/* See utils.h.  */
+
+void
+fprintf_styled (struct ui_file *stream, const ui_file_style &style,
+               const char *format, ...)
+{
+  va_list args;
+
+  set_output_style (stream, style);
+  va_start (args, format);
+  vfprintf_filtered (stream, format, args);
+  va_end (args);
+  set_output_style (stream, ui_file_style ());
+}
+
 
 void
 printf_filtered (const char *format, ...)
@@ -2631,7 +2771,7 @@ subset_compare (const char *string_to_compare, const char *template_string)
 {
   int match;
 
-  if (template_string != (char *) NULL && string_to_compare != (char *) NULL
+  if (template_string != NULL && string_to_compare != NULL
       && strlen (string_to_compare) <= strlen (template_string))
     match =
       (startswith (template_string, string_to_compare));
@@ -2708,10 +2848,11 @@ address_significant (gdbarch *gdbarch, CORE_ADDR addr)
   /* Clear insignificant bits of a target address and sign extend resulting
      address, avoiding shifts larger or equal than the width of a CORE_ADDR.
      The local variable ADDR_BIT stops the compiler reporting a shift overflow
-     when it won't occur.  */
+     when it won't occur.  Skip updating of target address if current target
+     has not set gdbarch significant_addr_bit.  */
   int addr_bit = gdbarch_significant_addr_bit (gdbarch);
 
-  if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
+  if (addr_bit && (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT)))
     {
       CORE_ADDR sign = (CORE_ADDR) 1 << (addr_bit - 1);
       addr &= ((CORE_ADDR) 1 << addr_bit) - 1;
@@ -2930,39 +3071,26 @@ compare_positive_ints (const void *ap, const void *bp)
 #define AMBIGUOUS_MESS2        \
   ".\nUse \"set gnutarget format-name\" to specify the format."
 
-const char *
+std::string
 gdb_bfd_errmsg (bfd_error_type error_tag, char **matching)
 {
-  char *ret, *retp;
-  int ret_len;
   char **p;
 
   /* Check if errmsg just need simple return.  */
   if (error_tag != bfd_error_file_ambiguously_recognized || matching == NULL)
     return bfd_errmsg (error_tag);
 
-  ret_len = strlen (bfd_errmsg (error_tag)) + strlen (AMBIGUOUS_MESS1)
-            + strlen (AMBIGUOUS_MESS2);
-  for (p = matching; *p; p++)
-    ret_len += strlen (*p) + 1;
-  ret = (char *) xmalloc (ret_len + 1);
-  retp = ret;
-  make_cleanup (xfree, ret);
-
-  strcpy (retp, bfd_errmsg (error_tag));
-  retp += strlen (retp);
-
-  strcpy (retp, AMBIGUOUS_MESS1);
-  retp += strlen (retp);
+  std::string ret (bfd_errmsg (error_tag));
+  ret += AMBIGUOUS_MESS1;
 
   for (p = matching; *p; p++)
     {
-      sprintf (retp, " %s", *p);
-      retp += strlen (retp);
+      ret += " ";
+      ret += *p;
     }
-  xfree (matching);
+  ret += AMBIGUOUS_MESS2;
 
-  strcpy (retp, AMBIGUOUS_MESS2);
+  xfree (matching);
 
   return ret;
 }
@@ -2987,23 +3115,6 @@ parse_pid_to_attach (const 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);
-}
-
 /* 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
@@ -3241,6 +3352,99 @@ strip_leading_path_elements (const char *path, int n)
   return p;
 }
 
+/* See utils.h.  */
+
+void
+copy_bitwise (gdb_byte *dest, ULONGEST dest_offset,
+             const gdb_byte *source, ULONGEST source_offset,
+             ULONGEST nbits, int bits_big_endian)
+{
+  unsigned int buf, avail;
+
+  if (nbits == 0)
+    return;
+
+  if (bits_big_endian)
+    {
+      /* Start from the end, then work backwards.  */
+      dest_offset += nbits - 1;
+      dest += dest_offset / 8;
+      dest_offset = 7 - dest_offset % 8;
+      source_offset += nbits - 1;
+      source += source_offset / 8;
+      source_offset = 7 - source_offset % 8;
+    }
+  else
+    {
+      dest += dest_offset / 8;
+      dest_offset %= 8;
+      source += source_offset / 8;
+      source_offset %= 8;
+    }
+
+  /* Fill BUF with DEST_OFFSET bits from the destination and 8 -
+     SOURCE_OFFSET bits from the source.  */
+  buf = *(bits_big_endian ? source-- : source++) >> source_offset;
+  buf <<= dest_offset;
+  buf |= *dest & ((1 << dest_offset) - 1);
+
+  /* NBITS: bits yet to be written; AVAIL: BUF's fill level.  */
+  nbits += dest_offset;
+  avail = dest_offset + 8 - source_offset;
+
+  /* Flush 8 bits from BUF, if appropriate.  */
+  if (nbits >= 8 && avail >= 8)
+    {
+      *(bits_big_endian ? dest-- : dest++) = buf;
+      buf >>= 8;
+      avail -= 8;
+      nbits -= 8;
+    }
+
+  /* Copy the middle part.  */
+  if (nbits >= 8)
+    {
+      size_t len = nbits / 8;
+
+      /* Use a faster method for byte-aligned copies.  */
+      if (avail == 0)
+       {
+         if (bits_big_endian)
+           {
+             dest -= len;
+             source -= len;
+             memcpy (dest + 1, source + 1, len);
+           }
+         else
+           {
+             memcpy (dest, source, len);
+             dest += len;
+             source += len;
+           }
+       }
+      else
+       {
+         while (len--)
+           {
+             buf |= *(bits_big_endian ? source-- : source++) << avail;
+             *(bits_big_endian ? dest-- : dest++) = buf;
+             buf >>= 8;
+           }
+       }
+      nbits %= 8;
+    }
+
+  /* Write the last byte.  */
+  if (nbits)
+    {
+      if (avail < nbits)
+       buf |= *source << avail;
+
+      buf &= (1 << nbits) - 1;
+      *dest = (*dest & (~0 << nbits)) | buf;
+    }
+}
+
 void
 _initialize_utils (void)
 {
This page took 0.035469 seconds and 4 git commands to generate.