Close gdbserver in mi_gdb_exit
[deliverable/binutils-gdb.git] / gdb / utils.c
index a3c707658a942fdc8d44a7b25e110ac1f7c7f08c..2afff806ad6020e678bb105dfc6507335caae422 100644 (file)
@@ -1,6 +1,6 @@
 /* General utility routines for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2015 Free Software Foundation, Inc.
+   Copyright (C) 1986-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -109,19 +109,6 @@ static int debug_timestamp = 0;
 
 int job_control;
 
-/* Nonzero means quit immediately if Control-C is typed now, rather
-   than waiting until QUIT is executed.  Be careful in setting this;
-   code which executes with immediate_quit set has to be very careful
-   about being able to deal with being interrupted at any time.  It is
-   almost always better to use QUIT; the only exception I can think of
-   is being able to quit out of a system call (using EINTR loses if
-   the SIGINT happens between the previous QUIT and the system call).
-   To immediately quit in the case in which a SIGINT happens between
-   the previous QUIT and setting immediate_quit (desirable anytime we
-   expect to block), call QUIT after setting immediate_quit.  */
-
-int immediate_quit;
-
 /* 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.)  */
@@ -182,7 +169,7 @@ make_cleanup_dyn_string_delete (dyn_string_t arg)
 static void
 do_bfd_close_cleanup (void *arg)
 {
-  gdb_bfd_unref (arg);
+  gdb_bfd_unref ((bfd *) arg);
 }
 
 struct cleanup *
@@ -196,7 +183,7 @@ make_cleanup_bfd_unref (bfd *abfd)
 static void
 do_fclose_cleanup (void *arg)
 {
-  FILE *file = arg;
+  FILE *file = (FILE *) arg;
 
   fclose (file);
 }
@@ -214,7 +201,7 @@ make_cleanup_fclose (FILE *file)
 static void
 do_obstack_free (void *arg)
 {
-  struct obstack *ob = arg;
+  struct obstack *ob = (struct obstack *) arg;
 
   obstack_free (ob, NULL);
 }
@@ -230,7 +217,7 @@ make_cleanup_obstack_free (struct obstack *obstack)
 static void
 do_ui_file_delete (void *arg)
 {
-  ui_file_delete (arg);
+  ui_file_delete ((struct ui_file *) arg);
 }
 
 struct cleanup *
@@ -244,7 +231,7 @@ make_cleanup_ui_file_delete (struct ui_file *arg)
 static void
 do_ui_out_redirect_pop (void *arg)
 {
-  struct ui_out *uiout = 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"));
@@ -262,7 +249,7 @@ make_cleanup_ui_out_redirect_pop (struct ui_out *uiout)
 static void
 do_free_section_addr_info (void *arg)
 {
-  free_section_addr_info (arg);
+  free_section_addr_info ((struct section_addr_info *) arg);
 }
 
 struct cleanup *
@@ -280,7 +267,8 @@ struct restore_integer_closure
 static void
 restore_integer (void *p)
 {
-  struct restore_integer_closure *closure = p;
+  struct restore_integer_closure *closure
+    = (struct restore_integer_closure *) p;
 
   *(closure->variable) = closure->value;
 }
@@ -291,8 +279,7 @@ restore_integer (void *p)
 struct cleanup *
 make_cleanup_restore_integer (int *variable)
 {
-  struct restore_integer_closure *c =
-    xmalloc (sizeof (struct restore_integer_closure));
+  struct restore_integer_closure *c = XNEW (struct restore_integer_closure);
 
   c->variable = variable;
   c->value = *variable;
@@ -314,7 +301,7 @@ make_cleanup_restore_uinteger (unsigned int *variable)
 static void
 do_unpush_target (void *arg)
 {
-  struct target_ops *ops = arg;
+  struct target_ops *ops = (struct target_ops *) arg;
 
   unpush_target (ops);
 }
@@ -332,7 +319,7 @@ make_cleanup_unpush_target (struct target_ops *ops)
 static void
 do_htab_delete_cleanup (void *htab_voidp)
 {
-  htab_t htab = htab_voidp;
+  htab_t htab = (htab_t) htab_voidp;
 
   htab_delete (htab);
 }
@@ -345,6 +332,12 @@ make_cleanup_htab_delete (htab_t htab)
   return make_cleanup (do_htab_delete_cleanup, htab);
 }
 
+struct restore_ui_out_closure
+{
+  struct ui_out **variable;
+  struct ui_out *value;
+};
+
 struct restore_ui_file_closure
 {
   struct ui_file **variable;
@@ -354,7 +347,8 @@ struct restore_ui_file_closure
 static void
 do_restore_ui_file (void *p)
 {
-  struct restore_ui_file_closure *closure = p;
+  struct restore_ui_file_closure *closure
+    = (struct restore_ui_file_closure *) p;
 
   *(closure->variable) = closure->value;
 }
@@ -395,7 +389,7 @@ make_cleanup_value_free_to_mark (struct value *mark)
 static void
 do_value_free (void *value)
 {
-  value_free (value);
+  value_free ((struct value *) value);
 }
 
 /* Free VALUE.  */
@@ -411,7 +405,7 @@ make_cleanup_value_free (struct value *value)
 static void
 do_free_so (void *arg)
 {
-  struct so_list *so = arg;
+  struct so_list *so = (struct so_list *) arg;
 
   free_so (so);
 }
@@ -475,7 +469,7 @@ make_cleanup_clear_parser_state (struct parser_state **p)
 void
 free_current_contents (void *ptr)
 {
-  void **location = ptr;
+  void **location = (void **) ptr;
 
   if (location == NULL)
     internal_error (__FILE__, __LINE__,
@@ -502,8 +496,13 @@ vwarning (const char *string, va_list args)
     (*deprecated_warning_hook) (string, args);
   else
     {
+      struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+
       if (target_supports_terminal_ours ())
-       target_terminal_ours ();
+       {
+         make_cleanup_restore_target_terminal ();
+         target_terminal_ours_for_output ();
+       }
       if (filtered_printing_initialized ())
        wrap_here ("");         /* Force out any buffered output.  */
       gdb_flush (gdb_stdout);
@@ -511,6 +510,8 @@ vwarning (const char *string, va_list args)
        fputs_unfiltered (warning_pre_print, gdb_stderr);
       vfprintf_unfiltered (gdb_stderr, string, args);
       fprintf_unfiltered (gdb_stderr, "\n");
+
+      do_cleanups (old_chain);
     }
 }
 
@@ -708,7 +709,10 @@ internal_vproblem (struct internal_problem *problem,
 
   /* Try to get the message out and at the start of a new line.  */
   if (target_supports_terminal_ours ())
-    target_terminal_ours ();
+    {
+      make_cleanup_restore_target_terminal ();
+      target_terminal_ours_for_output ();
+    }
   if (filtered_printing_initialized ())
     begin_line ();
 
@@ -860,8 +864,8 @@ add_internal_problem_command (struct internal_problem *problem)
   char *set_doc;
   char *show_doc;
 
-  set_cmd_list = xmalloc (sizeof (*set_cmd_list));
-  show_cmd_list = xmalloc (sizeof (*set_cmd_list));
+  set_cmd_list = XNEW (struct cmd_list_element *);
+  show_cmd_list = XNEW (struct cmd_list_element *);
   *set_cmd_list = NULL;
   *show_cmd_list = NULL;
 
@@ -1020,10 +1024,12 @@ print_sys_errmsg (const char *string, int errcode)
 void
 quit (void)
 {
+  struct ui *ui = current_ui;
+
   if (sync_quit_force_run)
     {
       sync_quit_force_run = 0;
-      quit_force (NULL, stdin == instream);
+      quit_force (NULL, 0);
     }
 
 #ifdef __MSDOS__
@@ -1041,6 +1047,20 @@ quit (void)
 #endif
 }
 
+/* See defs.h.  */
+
+void
+maybe_quit (void)
+{
+  if (sync_quit_force_run)
+    quit ();
+
+  quit_handler ();
+
+  if (deprecated_interactive_hook)
+    deprecated_interactive_hook ();
+}
+
 \f
 /* Called when a memory allocation fails, with the number of bytes of
    memory requested in SIZE.  */
@@ -1091,7 +1111,7 @@ print_spaces (int n, struct ui_file *file)
 /* Print a host address.  */
 
 void
-gdb_print_host_address (const void *addr, struct ui_file *stream)
+gdb_print_host_address_1 (const void *addr, struct ui_file *stream)
 {
   fprintf_filtered (stream, "%s", host_address_to_string (addr));
 }
@@ -1101,7 +1121,7 @@ gdb_print_host_address (const void *addr, struct ui_file *stream)
 char *
 make_hex_string (const gdb_byte *data, size_t length)
 {
-  char *result = xmalloc (length * 2 + 1);
+  char *result = (char *) xmalloc (length * 2 + 1);
   char *p;
   size_t i;
 
@@ -1119,7 +1139,7 @@ make_hex_string (const gdb_byte *data, size_t length)
 static void
 do_regfree_cleanup (void *r)
 {
-  regfree (r);
+  regfree ((regex_t *) r);
 }
 
 /* Create a new cleanup that frees the compiled regular expression R.  */
@@ -1137,7 +1157,7 @@ char *
 get_regcomp_error (int code, regex_t *rx)
 {
   size_t length = regerror (code, rx, NULL, 0);
-  char *result = xmalloc (length);
+  char *result = (char *) xmalloc (length);
 
   regerror (code, rx, result, length);
   return result;
@@ -1166,6 +1186,33 @@ compile_rx_or_error (regex_t *pattern, const char *rx, const char *message)
   return make_regfree_cleanup (pattern);
 }
 
+/* A cleanup that simply calls ui_unregister_input_event_handler.  */
+
+static void
+ui_unregister_input_event_handler_cleanup (void *ui)
+{
+  ui_unregister_input_event_handler ((struct ui *) ui);
+}
+
+/* Set up to handle input.  */
+
+static struct cleanup *
+prepare_to_handle_input (void)
+{
+  struct cleanup *old_chain;
+
+  old_chain = make_cleanup_restore_target_terminal ();
+  target_terminal_ours ();
+
+  ui_register_input_event_handler (current_ui);
+  if (current_ui->prompt_state == PROMPT_BLOCKED)
+    make_cleanup (ui_unregister_input_event_handler_cleanup, current_ui);
+
+  make_cleanup_override_quit_handler (default_quit_handler);
+
+  return old_chain;
+}
+
 \f
 
 /* This function supports the query, nquery, and yquery functions.
@@ -1189,6 +1236,7 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
   /* Used to add duration we waited for user to respond to
      prompt_for_continue_wait_time.  */
   struct timeval prompt_started, prompt_ended, prompt_delta;
+  struct cleanup *old_chain;
 
   /* Set up according to which answer is the default.  */
   if (defchar == '\0')
@@ -1225,8 +1273,12 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
      question we're asking, and then answer the default automatically.  This
      way, important error messages don't get lost when talking to GDB
      over a pipe.  */
-  if (! input_from_terminal_p ())
+  if (current_ui->instream != current_ui->stdin_stream
+      || !input_interactive_p (current_ui))
     {
+      old_chain = make_cleanup_restore_target_terminal ();
+
+      target_terminal_ours_for_output ();
       wrap_here ("");
       vfprintf_filtered (gdb_stdout, ctlstr, args);
 
@@ -1235,25 +1287,34 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
                       y_string, n_string, def_answer);
       gdb_flush (gdb_stdout);
 
+      do_cleanups (old_chain);
       return def_value;
     }
 
   if (deprecated_query_hook)
     {
-      return deprecated_query_hook (ctlstr, args);
+      int res;
+
+      old_chain = make_cleanup_restore_target_terminal ();
+      res = deprecated_query_hook (ctlstr, args);
+      do_cleanups (old_chain);
+      return res;
     }
 
   /* Format the question outside of the loop, to avoid reusing args.  */
   question = xstrvprintf (ctlstr, args);
+  old_chain = make_cleanup (xfree, question);
   prompt = xstrprintf (_("%s%s(%s or %s) %s"),
                      annotation_level > 1 ? "\n\032\032pre-query\n" : "",
                      question, y_string, n_string,
                      annotation_level > 1 ? "\n\032\032query\n" : "");
-  xfree (question);
+  make_cleanup (xfree, prompt);
 
   /* Used for calculating time spend waiting for user.  */
   gettimeofday (&prompt_started, NULL);
 
+  prepare_to_handle_input ();
+
   while (1)
     {
       char *response, answer;
@@ -1300,9 +1361,9 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
   timeval_add (&prompt_for_continue_wait_time,
                &prompt_for_continue_wait_time, &prompt_delta);
 
-  xfree (prompt);
   if (annotation_level > 1)
     printf_filtered (("\n\032\032post-query\n"));
+  do_cleanups (old_chain);
   return retval;
 }
 \f
@@ -1482,7 +1543,7 @@ parse_escape (struct gdbarch *gdbarch, const char **string_ptr)
 \f
 /* Print the character C on STREAM as part of the contents of a literal
    string whose delimiter is QUOTER.  Note that this routine should only
-   be call for printing things which are independent of the language
+   be called for printing things which are independent of the language
    of the program being debugged.
 
    printchar will normally escape backslashes and instances of QUOTER. If
@@ -1664,8 +1725,9 @@ init_page_info (void)
          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"))
+       /* Also disable paging if inside Emacs.  $EMACS was used
+          before Emacs v25.1, $INSIDE_EMACS is used since then.  */
+         || getenv ("EMACS") || getenv ("INSIDE_EMACS"))
        {
          /* The number of lines per page is not mentioned in the terminal
             description or EMACS evironment variable is set.  This probably
@@ -1794,7 +1856,9 @@ set_screen_width_and_height (int width, int height)
 }
 
 /* Wait, so the user can read what's on the screen.  Prompt the user
-   to continue by pressing RETURN.  */
+   to continue by pressing RETURN.  'q' is also provided because
+   telling users what to do in the prompt is more user-friendly than
+   expecting them to think of Ctrl-C/SIGINT.  */
 
 static void
 prompt_for_continue (void)
@@ -1804,6 +1868,7 @@ prompt_for_continue (void)
   /* Used to add duration we waited for user to respond to
      prompt_for_continue_wait_time.  */
   struct timeval prompt_started, prompt_ended, prompt_delta;
+  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
 
   gettimeofday (&prompt_started, NULL);
 
@@ -1815,28 +1880,17 @@ prompt_for_continue (void)
   if (annotation_level > 1)
     strcat (cont_prompt, "\n\032\032prompt-for-continue\n");
 
-  /* We must do this *before* we call gdb_readline, else it will eventually
-     call us -- thinking that we're trying to print beyond the end of the 
-     screen.  */
+  /* We must do this *before* we call gdb_readline_wrapper, else it
+     will eventually call us -- thinking that we're trying to print
+     beyond the end of the screen.  */
   reinitialize_more_filter ();
 
-  immediate_quit++;
-  QUIT;
-
-  /* We'll need to handle input.  */
-  target_terminal_ours ();
+  prepare_to_handle_input ();
 
-  /* On a real operating system, the user can quit with SIGINT.
-     But not on GO32.
-
-     'q' is provided on all systems so users don't have to change habits
-     from system to system, and because telling them what to do in
-     the prompt is more user-friendly than expecting them to think of
-     SIGINT.  */
-  /* Call readline, not gdb_readline, because GO32 readline handles control-C
-     whereas control-C to gdb_readline will cause the user to get dumped
-     out to DOS.  */
+  /* Call gdb_readline_wrapper, not readline, in order to keep an
+     event loop running.  */
   ignore = gdb_readline_wrapper (cont_prompt);
+  make_cleanup (xfree, ignore);
 
   /* Add time spend in this routine to prompt_for_continue_wait_time.  */
   gettimeofday (&prompt_ended, NULL);
@@ -1847,23 +1901,24 @@ prompt_for_continue (void)
   if (annotation_level > 1)
     printf_unfiltered (("\n\032\032post-prompt-for-continue\n"));
 
-  if (ignore)
+  if (ignore != NULL)
     {
       char *p = ignore;
 
       while (*p == ' ' || *p == '\t')
        ++p;
       if (p[0] == 'q')
-       quit ();
-      xfree (ignore);
+       /* Do not call quit here; there is no possibility of SIGINT.  */
+       throw_quit ("Quit");
     }
-  immediate_quit--;
 
   /* 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 ();
 
   dont_repeat ();              /* Forget prev cmd -- CR won't repeat it.  */
+
+  do_cleanups (old_chain);
 }
 
 /* Initalize timer to keep track of how long we waited for the user.  */
@@ -1985,7 +2040,7 @@ puts_filtered_tabular (char *string, int width, int right)
   if (right)
     spaces += width - stringlen;
 
-  spacebuf = alloca (spaces + 1);
+  spacebuf = (char *) alloca (spaces + 1);
   spacebuf[spaces] = '\0';
   while (spaces--)
     spacebuf[spaces] = ' ';
@@ -2770,7 +2825,7 @@ print_core_address (struct gdbarch *gdbarch, CORE_ADDR address)
 hashval_t
 core_addr_hash (const void *ap)
 {
-  const CORE_ADDR *addrp = ap;
+  const CORE_ADDR *addrp = (const CORE_ADDR *) ap;
 
   return *addrp;
 }
@@ -2780,8 +2835,8 @@ core_addr_hash (const void *ap)
 int
 core_addr_eq (const void *ap, const void *bp)
 {
-  const CORE_ADDR *addr_ap = ap;
-  const CORE_ADDR *addr_bp = bp;
+  const CORE_ADDR *addr_ap = (const CORE_ADDR *) ap;
+  const CORE_ADDR *addr_bp = (const CORE_ADDR *) bp;
 
   return *addr_ap == *addr_bp;
 }
@@ -2891,7 +2946,7 @@ gdb_realpath_keepfile (const char *filename)
   if (base_name == filename)
     return xstrdup (filename);
 
-  dir_name = alloca ((size_t) (base_name - filename + 2));
+  dir_name = (char *) 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.  */
@@ -3002,7 +3057,7 @@ ldirname (const char *filename)
   if (base == filename)
     return NULL;
 
-  dirname = xmalloc (base - filename + 2);
+  dirname = (char *) xmalloc (base - filename + 2);
   memcpy (dirname, filename, base - filename);
 
   /* On DOS based file systems, convert "d:foo" to "d:.", so that we
@@ -3068,7 +3123,7 @@ gdb_bfd_errmsg (bfd_error_type error_tag, char **matching)
             + strlen (AMBIGUOUS_MESS2);
   for (p = matching; *p; p++)
     ret_len += strlen (*p) + 1;
-  ret = xmalloc (ret_len + 1);
+  ret = (char *) xmalloc (ret_len + 1);
   retp = ret;
   make_cleanup (xfree, ret);
 
@@ -3187,7 +3242,7 @@ producer_is_gcc (const char *producer, int *major, int *minor)
 static void
 do_free_char_ptr_vec (void *arg)
 {
-  VEC (char_ptr) *char_ptr_vec = arg;
+  VEC (char_ptr) *char_ptr_vec = (VEC (char_ptr) *) arg;
 
   free_char_ptr_vec (char_ptr_vec);
 }
@@ -3230,7 +3285,8 @@ substitute_path_component (char **stringp, const char *from, const char *to)
        {
          char *string_new;
 
-         string_new = xrealloc (string, (strlen (string) + to_len + 1));
+         string_new
+           = (char *) xrealloc (string, (strlen (string) + to_len + 1));
 
          /* Relocate the current S pointer.  */
          s = s - string + string_new;
@@ -3291,9 +3347,9 @@ wait_to_die_with_timeout (pid_t pid, int *status, int timeout)
       sa.sa_flags = 0;
       sigaction (SIGALRM, &sa, &old_sa);
 #else
-      void (*ofunc) ();
+      sighandler_t ofunc;
 
-      ofunc = (void (*)()) signal (SIGALRM, sigalrm_handler);
+      ofunc = signal (SIGALRM, sigalrm_handler);
 #endif
 
       alarm (timeout);
@@ -3341,14 +3397,14 @@ gdb_filename_fnmatch (const char *pattern, const char *string, int flags)
 
     /* Replace '\' by '/' in both strings.  */
 
-    pattern_slash = alloca (strlen (pattern) + 1);
+    pattern_slash = (char *) 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);
+    string_slash = (char *) alloca (strlen (string) + 1);
     strcpy (string_slash, string);
     string = string_slash;
     for (; *string_slash != 0; string_slash++)
@@ -3364,6 +3420,83 @@ gdb_filename_fnmatch (const char *pattern, const char *string, int flags)
   return fnmatch (pattern, string, flags);
 }
 
+/* Return the number of path elements in PATH.
+   / = 1
+   /foo = 2
+   /foo/ = 2
+   foo/bar = 2
+   foo/ = 1  */
+
+int
+count_path_elements (const char *path)
+{
+  int count = 0;
+  const char *p = path;
+
+  if (HAS_DRIVE_SPEC (p))
+    {
+      p = STRIP_DRIVE_SPEC (p);
+      ++count;
+    }
+
+  while (*p != '\0')
+    {
+      if (IS_DIR_SEPARATOR (*p))
+       ++count;
+      ++p;
+    }
+
+  /* Backup one if last character is /, unless it's the only one.  */
+  if (p > path + 1 && IS_DIR_SEPARATOR (p[-1]))
+    --count;
+
+  /* Add one for the file name, if present.  */
+  if (p > path && !IS_DIR_SEPARATOR (p[-1]))
+    ++count;
+
+  return count;
+}
+
+/* Remove N leading path elements from PATH.
+   N must be non-negative.
+   If PATH has more than N path elements then return NULL.
+   If PATH has exactly N path elements then return "".
+   See count_path_elements for a description of how we do the counting.  */
+
+const char *
+strip_leading_path_elements (const char *path, int n)
+{
+  int i = 0;
+  const char *p = path;
+
+  gdb_assert (n >= 0);
+
+  if (n == 0)
+    return p;
+
+  if (HAS_DRIVE_SPEC (p))
+    {
+      p = STRIP_DRIVE_SPEC (p);
+      ++i;
+    }
+
+  while (i < n)
+    {
+      while (*p != '\0' && !IS_DIR_SEPARATOR (*p))
+       ++p;
+      if (*p == '\0')
+       {
+         if (i + 1 == n)
+           return "";
+         return NULL;
+       }
+      ++p;
+      ++i;
+    }
+
+  return p;
+}
+
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 extern initialize_file_ftype _initialize_utils;
 
This page took 0.033324 seconds and 4 git commands to generate.