2011-02-21 Hui Zhu <teawater@gmail.com>
[deliverable/binutils-gdb.git] / gdb / utils.c
index 875faafe10009b6ae9b319c63450fb9cfe4e6353..82e3adbafb7e2c01fb5d6c9178e0a5f5042a975a 100644 (file)
@@ -2,7 +2,7 @@
 
    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 Free Software Foundation, Inc.
+   2009, 2010, 2011 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -38,7 +38,7 @@
 #include <pc.h>
 #endif
 
-/* SunOS's curses.h has a '#define reg register' in it.  Thank you Sun. */
+/* SunOS's curses.h has a '#define reg register' in it.  Thank you Sun.  */
 #ifdef reg
 #undef reg
 #endif
@@ -73,6 +73,7 @@
 
 #include "gdb_usleep.h"
 #include "interps.h"
+#include "gdb_regex.h"
 
 #if !HAVE_DECL_MALLOC
 extern PTR malloc ();          /* ARI: PTR */
@@ -113,7 +114,7 @@ static int debug_timestamp = 0;
 static struct cleanup *cleanup_chain;  /* cleaned up after a failed command */
 static struct cleanup *final_cleanup_chain;    /* cleaned up when gdb exits */
 
-/* Nonzero if we have job control. */
+/* Nonzero if we have job control.  */
 
 int job_control;
 
@@ -142,8 +143,9 @@ static void
 show_demangle (struct ui_file *file, int from_tty,
               struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("\
-Demangling of encoded C++/ObjC names when displaying symbols is %s.\n"),
+  fprintf_filtered (file,
+                   _("Demangling of encoded C++/ObjC names "
+                     "when displaying symbols is %s.\n"),
                    value);
 }
 
@@ -156,8 +158,9 @@ static void
 show_asm_demangle (struct ui_file *file, int from_tty,
                   struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("\
-Demangling of C++/ObjC names in disassembly listings is %s.\n"),
+  fprintf_filtered (file,
+                   _("Demangling of C++/ObjC names in "
+                     "disassembly listings is %s.\n"),
                    value);
 }
 
@@ -170,8 +173,8 @@ static void
 show_sevenbit_strings (struct ui_file *file, int from_tty,
                       struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("\
-Printing of 8-bit characters in strings as \\nnn is %s.\n"),
+  fprintf_filtered (file, _("Printing of 8-bit characters "
+                           "in strings as \\nnn is %s.\n"),
                    value);
 }
 
@@ -250,6 +253,7 @@ static void
 do_close_cleanup (void *arg)
 {
   int *fd = arg;
+
   close (*fd);
 }
 
@@ -257,6 +261,7 @@ struct cleanup *
 make_cleanup_close (int fd)
 {
   int *saved_fd = xmalloc (sizeof (fd));
+
   *saved_fd = fd;
   return make_cleanup_dtor (do_close_cleanup, saved_fd, xfree);
 }
@@ -267,7 +272,8 @@ static void
 do_fclose_cleanup (void *arg)
 {
   FILE *file = arg;
-  fclose (arg);
+
+  fclose (file);
 }
 
 /* Return a new cleanup that closes FILE.  */
@@ -284,6 +290,7 @@ static void
 do_obstack_free (void *arg)
 {
   struct obstack *ob = arg;
+
   obstack_free (ob, NULL);
 }
 
@@ -307,6 +314,26 @@ make_cleanup_ui_file_delete (struct ui_file *arg)
   return make_my_cleanup (&cleanup_chain, do_ui_file_delete, arg);
 }
 
+/* Helper function for make_cleanup_ui_out_redirect_pop.  */
+
+static void
+do_ui_out_redirect_pop (void *arg)
+{
+  struct ui_out *uiout = arg;
+
+  if (ui_out_redirect (uiout, NULL) < 0)
+    warning (_("Cannot restore redirection of the current output protocol"));
+}
+
+/* Return a new cleanup that pops the last redirection by ui_out_redirect
+   with NULL parameter.  */
+
+struct cleanup *
+make_cleanup_ui_out_redirect_pop (struct ui_out *uiout)
+{
+  return make_my_cleanup (&cleanup_chain, do_ui_out_redirect_pop, uiout);
+}
+
 static void
 do_free_section_addr_info (void *arg)
 {
@@ -329,16 +356,19 @@ static void
 restore_integer (void *p)
 {
   struct restore_integer_closure *closure = p;
+
   *(closure->variable) = closure->value;
 }
 
-/* Remember the current value of *VARIABLE and make it restored when the cleanup
-   is run.  */
+/* Remember the current value of *VARIABLE and make it restored when
+   the cleanup is run.  */
+
 struct cleanup *
 make_cleanup_restore_integer (int *variable)
 {
   struct restore_integer_closure *c =
     xmalloc (sizeof (struct restore_integer_closure));
+
   c->variable = variable;
   c->value = *variable;
 
@@ -346,6 +376,61 @@ make_cleanup_restore_integer (int *variable)
                           xfree);
 }
 
+/* Remember the current value of *VARIABLE and make it restored when
+   the cleanup is run.  */
+
+struct cleanup *
+make_cleanup_restore_uinteger (unsigned int *variable)
+{
+  return make_cleanup_restore_integer ((int *) variable);
+}
+
+/* Helper for make_cleanup_unpush_target.  */
+
+static void
+do_unpush_target (void *arg)
+{
+  struct target_ops *ops = arg;
+
+  unpush_target (ops);
+}
+
+/* Return a new cleanup that unpushes OPS.  */
+
+struct cleanup *
+make_cleanup_unpush_target (struct target_ops *ops)
+{
+  return make_my_cleanup (&cleanup_chain, do_unpush_target, ops);
+}
+
+struct restore_ui_file_closure
+{
+  struct ui_file **variable;
+  struct ui_file *value;
+};
+
+static void
+do_restore_ui_file (void *p)
+{
+  struct restore_ui_file_closure *closure = p;
+
+  *(closure->variable) = closure->value;
+}
+
+/* Remember the current value of *VARIABLE and make it restored when
+   the cleanup is run.  */
+
+struct cleanup *
+make_cleanup_restore_ui_file (struct ui_file **variable)
+{
+  struct restore_ui_file_closure *c = XNEW (struct restore_ui_file_closure);
+
+  c->variable = variable;
+  c->value = *variable;
+
+  return make_cleanup_dtor (do_restore_ui_file, (void *) c, xfree);
+}
+
 struct cleanup *
 make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function,
                  void *arg,  void (*free_arg) (void *))
@@ -390,9 +475,10 @@ 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 incase recursion */
+      *pmy_chain = ptr->next;  /* Do this first in case of recursion.  */
       (*ptr->function) (ptr->arg);
       if (ptr->free_arg)
        (*ptr->free_arg) (ptr->arg);
@@ -420,6 +506,7 @@ discard_my_cleanups (struct cleanup **pmy_chain,
                     struct cleanup *old_chain)
 {
   struct cleanup *ptr;
+
   while ((ptr = *pmy_chain) != old_chain)
     {
       *pmy_chain = ptr->next;
@@ -482,6 +569,7 @@ void
 free_current_contents (void *ptr)
 {
   void **location = ptr;
+
   if (location == NULL)
     internal_error (__FILE__, __LINE__,
                    _("free_current_contents: NULL pointer"));
@@ -497,13 +585,107 @@ free_current_contents (void *ptr)
    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. */
+   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;
+
+/* 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_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_time;
+
+      printf_unfiltered (msg_type == 0
+                        ? _("Startup time: %ld.%06ld\n")
+                        : _("Command execution time: %ld.%06ld\n"),
+                        cmd_time / 1000000, cmd_time % 1000000);
+    }
+
+  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 (%c%ld during startup)\n")
+                        : _("Space used: %ld (%c%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)
+{
+  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_time = get_run_time ();
+
+  return make_cleanup_dtor (report_command_stats, new_stat, xfree);
+}
+
 /* Continuations are implemented as cleanups internally.  Inherit from
    cleanups.  */
 struct continuation
@@ -553,7 +735,6 @@ add_inferior_continuation (void (*continuation_hook) (void *), void *args,
 void
 do_all_inferior_continuations (void)
 {
-  struct cleanup *old_chain;
   struct cleanup *as_cleanup;
   struct inferior *inf = current_inferior ();
 
@@ -578,6 +759,7 @@ void
 discard_all_inferior_continuations (struct inferior *inf)
 {
   struct cleanup *continuation_ptr = &inf->continuations->base;
+
   discard_my_cleanups (&continuation_ptr, NULL);
   inf->continuations = NULL;
 }
@@ -586,6 +768,7 @@ static void
 restore_thread_cleanup (void *arg)
 {
   ptid_t *ptid_p = arg;
+
   switch_to_thread (*ptid_p);
 }
 
@@ -666,6 +849,7 @@ discard_all_continuations_thread_callback (struct thread_info *thread,
                                           void *data)
 {
   struct cleanup *continuation_ptr = &thread->continuations->base;
+
   discard_my_cleanups (&continuation_ptr, NULL);
   thread->continuations = NULL;
   return 0;
@@ -706,13 +890,13 @@ add_intermediate_continuation (struct thread_info *thread,
 }
 
 /* Walk down the cmd_continuation list, and execute all the
-   continuations. There is a problem though. In some cases new
+   continuations.  There is a problem though.  In some cases new
    continuations may be added while we are in the middle of this
-   loop. If this happens they will be added in the front, and done
+   loop.  If this happens they will be added in the front, and done
    before we have a chance of exhausting those that were already
-   there. We need to then save the beginning of the list in a pointer
+   there.  We need to then save the beginning of the list in a pointer
    and do the continuations from there on, instead of using the
-   global beginning of list as our iteration pointer.*/
+   global beginning of list as our iteration pointer.  */
 static int
 do_all_intermediate_continuations_thread_callback (struct thread_info *thread,
                                                   void *data)
@@ -733,7 +917,8 @@ do_all_intermediate_continuations_thread (struct thread_info *thread)
 void
 do_all_intermediate_continuations (void)
 {
-  iterate_over_threads (do_all_intermediate_continuations_thread_callback, NULL);
+  iterate_over_threads (do_all_intermediate_continuations_thread_callback,
+                       NULL);
 }
 
 /* Callback for iterate over threads.  */
@@ -742,6 +927,7 @@ discard_all_intermediate_continuations_thread_callback (struct thread_info *thre
                                                        void *data)
 {
   struct cleanup *continuation_ptr = &thread->intermediate_continuations->base;
+
   discard_my_cleanups (&continuation_ptr, NULL);
   thread->intermediate_continuations = NULL;
   return 0;
@@ -758,7 +944,8 @@ discard_all_intermediate_continuations_thread (struct thread_info *thread)
 void
 discard_all_intermediate_continuations (void)
 {
-  iterate_over_threads (discard_all_intermediate_continuations_thread_callback, NULL);
+  iterate_over_threads (discard_all_intermediate_continuations_thread_callback,
+                       NULL);
 }
 \f
 
@@ -777,7 +964,7 @@ vwarning (const char *string, va_list args)
   else
     {
       target_terminal_ours ();
-      wrap_here ("");          /* Force out any buffered output */
+      wrap_here ("");          /* Force out any buffered output */
       gdb_flush (gdb_stdout);
       if (warning_pre_print)
        fputs_unfiltered (warning_pre_print, gdb_stderr);
@@ -797,6 +984,7 @@ void
 warning (const char *string, ...)
 {
   va_list args;
+
   va_start (args, string);
   vwarning (string, args);
   va_end (args);
@@ -816,6 +1004,7 @@ void
 error (const char *string, ...)
 {
   va_list args;
+
   va_start (args, string);
   throw_verror (GENERIC_ERROR, string, args);
   va_end (args);
@@ -835,6 +1024,7 @@ void
 fatal (const char *string, ...)
 {
   va_list args;
+
   va_start (args, string);
   throw_vfatal (string, args);
   va_end (args);
@@ -844,6 +1034,7 @@ void
 error_stream (struct ui_file *stream)
 {
   char *message = ui_file_xstrdup (stream, NULL);
+
   make_cleanup (xfree, message);
   error (("%s"), message);
 }
@@ -862,7 +1053,8 @@ dump_core (void)
   abort ();            /* NOTE: GDB has only three calls to abort().  */
 }
 
-/* Check whether GDB will be able to dump core using the dump_core function.  */
+/* Check whether GDB will be able to dump core using the dump_core
+   function.  */
 
 static int
 can_dump_core (const char *reason)
@@ -877,8 +1069,9 @@ can_dump_core (const char *reason)
   if (rlim.rlim_max == 0)
     {
       fprintf_unfiltered (gdb_stderr,
-                         _("%s\nUnable to dump core, use `ulimit -c unlimited'"
-                           " before executing GDB next time.\n"), reason);
+                         _("%s\nUnable to dump core, use `ulimit -c"
+                           " unlimited' before executing GDB next time.\n"),
+                         reason);
       return 0;
     }
 #endif /* HAVE_GETRLIMIT */
@@ -899,9 +1092,8 @@ static const char *internal_problem_modes[] =
   internal_problem_no,
   NULL
 };
-static const char *internal_problem_mode = internal_problem_ask;
 
-/* Print a message reporting an internal error/warning. Ask the user
+/* Print a message reporting an internal error/warning.  Ask the user
    if they want to continue, dump core, or just exit.  Return
    something to indicate a quit.  */
 
@@ -928,6 +1120,7 @@ internal_vproblem (struct internal_problem *problem,
   /* Don't allow infinite error/warning recursion.  */
   {
     static char msg[] = "Recursive internal problem.\n";
+
     switch (dejavu)
       {
       case 0:
@@ -961,11 +1154,12 @@ internal_vproblem (struct internal_problem *problem,
      so that the user knows that they are living on the edge.  */
   {
     char *msg;
+
     msg = xstrvprintf (fmt, ap);
-    reason = xstrprintf ("\
-%s:%d: %s: %s\n\
-A problem internal to GDB has been detected,\n\
-further debugging may prove unreliable.", file, line, problem->name, msg);
+    reason = xstrprintf ("%s:%d: %s: %s\n"
+                        "A problem internal to GDB has been detected,\n"
+                        "further debugging may prove unreliable.",
+                        file, line, problem->name, msg);
     xfree (msg);
     make_cleanup (xfree, reason);
   }
@@ -1047,6 +1241,7 @@ void
 internal_error (const char *file, int line, const char *string, ...)
 {
   va_list ap;
+
   va_start (ap, string);
   internal_verror (file, line, string, ap);
   va_end (ap);
@@ -1066,6 +1261,7 @@ void
 internal_warning (const char *file, int line, const char *string, ...)
 {
   va_list ap;
+
   va_start (ap, string);
   internal_vwarning (file, line, string, ap);
   va_end (ap);
@@ -1131,11 +1327,11 @@ add_internal_problem_command (struct internal_problem *problem)
                          (char *) NULL),
                  0/*allow-unknown*/, &maintenance_show_cmdlist);
 
-  set_doc = xstrprintf (_("\
-Set whether GDB should quit when an %s is detected"),
+  set_doc = xstrprintf (_("Set whether GDB should quit "
+                         "when an %s is detected"),
                        problem->name);
-  show_doc = xstrprintf (_("\
-Show whether GDB will quit when an %s is detected"),
+  show_doc = xstrprintf (_("Show whether GDB will quit "
+                          "when an %s is detected"),
                         problem->name);
   add_setshow_enum_cmd ("quit", class_maintenance,
                        internal_problem_modes,
@@ -1151,11 +1347,11 @@ Show whether GDB will quit when an %s is detected"),
   xfree (set_doc);
   xfree (show_doc);
 
-  set_doc = xstrprintf (_("\
-Set whether GDB should create a core file of GDB when %s is detected"),
+  set_doc = xstrprintf (_("Set whether GDB should create a core "
+                         "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"),
+  show_doc = xstrprintf (_("Show whether GDB will create a core "
+                          "file of GDB when %s is detected"),
                         problem->name);
   add_setshow_enum_cmd ("corefile", class_maintenance,
                        internal_problem_modes,
@@ -1190,7 +1386,7 @@ perror_with_name (const char *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
-     unreasonable. */
+     unreasonable.  */
   bfd_set_error (bfd_error_no_error);
   errno = 0;
 
@@ -1240,7 +1436,7 @@ quit (void)
 
 \f
 /* Called when a memory allocation fails, with the number of bytes of
-   memory requested in SIZE. */
+   memory requested in SIZE.  */
 
 void
 nomem (long size)
@@ -1338,13 +1534,14 @@ xfree (void *ptr)
 \f
 
 /* Like asprintf/vasprintf but get an internal_error if the call
-   fails. */
+   fails.  */
 
 char *
 xstrprintf (const char *format, ...)
 {
   char *ret;
   va_list args;
+
   va_start (args, format);
   ret = xstrvprintf (format, args);
   va_end (args);
@@ -1355,6 +1552,7 @@ void
 xasprintf (char **ret, const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   (*ret) = xstrvprintf (format, args);
   va_end (args);
@@ -1371,6 +1569,7 @@ xstrvprintf (const char *format, va_list ap)
 {
   char *ret = NULL;
   int status = vasprintf (&ret, format, ap);
+
   /* NULL is returned when there was a memory allocation problem, or
      any other error (for instance, a bad format string).  A negative
      status (the printed length) with a non-NULL buffer should never
@@ -1424,6 +1623,7 @@ char *
 savestring (const char *ptr, size_t size)
 {
   char *p = (char *) xmalloc (size + 1);
+
   memcpy (p, ptr, size);
   p[size] = 0;
   return p;
@@ -1444,6 +1644,37 @@ gdb_print_host_address (const void *addr, struct ui_file *stream)
 }
 \f
 
+/* A cleanup function that calls regfree.  */
+
+static void
+do_regfree_cleanup (void *r)
+{
+  regfree (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 = xmalloc (length);
+
+  regerror (code, rx, result, length);
+  return result;
+}
+
+\f
+
 /* This function supports the query, nquery, and yquery functions.
    Ask user a y-or-n question and return 0 if answer is no, 1 if
    answer is yes, or default the answer to the specified default
@@ -1499,12 +1730,13 @@ 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 (batch_flag || ! input_from_terminal_p ())
+  if (! input_from_terminal_p ())
     {
       wrap_here ("");
       vfprintf_filtered (gdb_stdout, ctlstr, args);
 
-      printf_filtered (_("(%s or %s) [answered %c; input not from terminal]\n"),
+      printf_filtered (_("(%s or %s) [answered %c; "
+                        "input not from terminal]\n"),
                       y_string, n_string, def_answer);
       gdb_flush (gdb_stdout);
 
@@ -1521,7 +1753,7 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
 
   while (1)
     {
-      wrap_here ("");          /* Flush any buffered output */
+      wrap_here ("");          /* Flush any buffered output */
       gdb_flush (gdb_stdout);
 
       if (annotation_level > 1)
@@ -1563,7 +1795,7 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
          retval = def_value;
          break;
        }
-      /* Eat rest of input line, to EOF or newline */
+      /* Eat rest of input line, to EOF or newline */
       if (answer != '\n')
        do
          {
@@ -1697,8 +1929,9 @@ host_char_to_target (struct gdbarch *gdbarch, int c, int *target_c)
 int
 parse_escape (struct gdbarch *gdbarch, char **string_ptr)
 {
-  int target_char = -2;        /* initialize to avoid GCC warnings */
+  int target_char = -2;        /* Initialize to avoid GCC warnings.  */
   int c = *(*string_ptr)++;
+
   switch (c)
     {
       case '\n':
@@ -1772,14 +2005,13 @@ parse_escape (struct gdbarch *gdbarch, char **string_ptr)
 /* 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
-   of the program being debugged. */
+   of the program being debugged.  */
 
 static void
 printchar (int c, void (*do_fputs) (const char *, struct ui_file *),
           void (*do_fprintf) (struct ui_file *, const char *, ...)
           ATTRIBUTE_FPTR_PRINTF_2, struct ui_file *stream, int quoter)
 {
-
   c &= 0xFF;                   /* Avoid sign bit follies */
 
   if (c < 0x20 ||              /* Low control chars */
@@ -1825,7 +2057,7 @@ printchar (int c, void (*do_fputs) (const char *, struct ui_file *),
 /* Print the character C on STREAM as part of the contents of a
    literal string whose delimiter is QUOTER.  Note that these routines
    should only be call for printing things which are independent of
-   the language of the program being debugged. */
+   the language of the program being debugged.  */
 
 void
 fputstr_filtered (const char *str, int quoter, struct ui_file *stream)
@@ -1846,6 +2078,7 @@ fputstrn_filtered (const char *str, int n, int quoter,
                   struct ui_file *stream)
 {
   int i;
+
   for (i = 0; i < n; i++)
     printchar (str[i], fputs_filtered, fprintf_filtered, stream, quoter);
 }
@@ -1855,6 +2088,7 @@ fputstrn_unfiltered (const char *str, int n, int quoter,
                     struct ui_file *stream)
 {
   int i;
+
   for (i = 0; i < n; i++)
     printchar (str[i], fputs_unfiltered, fprintf_unfiltered, stream, quoter);
 }
@@ -1866,8 +2100,8 @@ static void
 show_lines_per_page (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("\
-Number of lines gdb thinks are in a page is %s.\n"),
+  fprintf_filtered (file,
+                   _("Number of lines gdb thinks are in a page is %s.\n"),
                    value);
 }
 
@@ -1877,8 +2111,9 @@ static void
 show_chars_per_line (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("\
-Number of characters gdb thinks are in a line is %s.\n"),
+  fprintf_filtered (file,
+                   _("Number of characters gdb thinks "
+                     "are in a line is %s.\n"),
                    value);
 }
 
@@ -1915,6 +2150,12 @@ static int wrap_column;
 void
 init_page_info (void)
 {
+  if (batch_flag)
+    {
+      lines_per_page = UINT_MAX;
+      chars_per_line = UINT_MAX;
+    }
+  else
 #if defined(TUI)
   if (!tui_get_command_dimension (&chars_per_line, &lines_per_page))
 #endif
@@ -1959,6 +2200,44 @@ init_page_info (void)
   set_width ();
 }
 
+/* Helper for make_cleanup_restore_page_info.  */
+
+static void
+do_restore_page_info_cleanup (void *arg)
+{
+  set_screen_size ();
+  set_width ();
+}
+
+/* Provide cleanup for restoring the terminal size.  */
+
+struct cleanup *
+make_cleanup_restore_page_info (void)
+{
+  struct cleanup *back_to;
+
+  back_to = make_cleanup (do_restore_page_info_cleanup, NULL);
+  make_cleanup_restore_uinteger (&lines_per_page);
+  make_cleanup_restore_uinteger (&chars_per_line);
+
+  return back_to;
+}
+
+/* Temporarily set BATCH_FLAG and the associated unlimited terminal size.
+   Provide cleanup for restoring the original state.  */
+
+struct cleanup *
+set_batch_flag_and_make_cleanup_restore_page_info (void)
+{
+  struct cleanup *back_to = make_cleanup_restore_page_info ();
+  
+  make_cleanup_restore_integer (&batch_flag);
+  batch_flag = 1;
+  init_page_info ();
+
+  return back_to;
+}
+
 /* Set the screen size based on LINES_PER_PAGE and CHARS_PER_LINE.  */
 
 static void
@@ -2050,6 +2329,7 @@ prompt_for_continue (void)
   if (ignore)
     {
       char *p = ignore;
+
       while (*p == ' ' || *p == '\t')
        ++p;
       if (p[0] == 'q')
@@ -2062,7 +2342,7 @@ prompt_for_continue (void)
      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. */
+  dont_repeat ();              /* Forget prev cmd -- CR won't repeat it.  */
 }
 
 /* Reinitialize filter; ie. tell it to reset to original values.  */
@@ -2075,7 +2355,7 @@ reinitialize_more_filter (void)
 }
 
 /* Indicate that if the next sequence of characters overflows the line,
-   a newline should be inserted here rather than when it hits the end. 
+   a newline should be inserted here rather than when it hits the end.
    If INDENT is non-null, it is a string to be printed to indent the
    wrapped part on the next line.  INDENT must remain accessible until
    the next call to wrap_here() or until a newline is printed through
@@ -2098,9 +2378,10 @@ reinitialize_more_filter (void)
 void
 wrap_here (char *indent)
 {
-  /* This should have been allocated, but be paranoid anyway. */
+  /* This should have been allocated, but be paranoid anyway.  */
   if (!wrap_buffer)
-    internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
+    internal_error (__FILE__, __LINE__,
+                   _("failed internal consistency check"));
 
   if (wrap_buffer[0])
     {
@@ -2109,7 +2390,7 @@ wrap_here (char *indent)
     }
   wrap_pointer = wrap_buffer;
   wrap_buffer[0] = '\0';
-  if (chars_per_line == UINT_MAX)      /* No line overflow checking */
+  if (chars_per_line == UINT_MAX)      /* No line overflow checking */
     {
       wrap_column = 0;
     }
@@ -2131,11 +2412,11 @@ wrap_here (char *indent)
 }
 
 /* Print input string to gdb_stdout, filtered, with wrap, 
-   arranging strings in columns of n chars. String can be
+   arranging strings in columns of n chars.  String can be
    right or left justified in the column.  Never prints 
    trailing spaces.  String should never be longer than
    width.  FIXME: this could be useful for the EXAMINE 
-   command, which currently doesn't tabulate very well */
+   command, which currently doesn't tabulate very well */
 
 void
 puts_filtered_tabular (char *string, int width, int right)
@@ -2176,9 +2457,9 @@ puts_filtered_tabular (char *string, int width, int right)
 
 
 /* Ensure that whatever gets printed next, using the filtered output
-   commands, starts at the beginning of the line.  I.E. if there is
+   commands, starts at the beginning of the line.  I.e. if there is
    any pending output for the current line, flush it and start a new
-   line.  Otherwise do nothing. */
+   line.  Otherwise do nothing.  */
 
 void
 begin_line (void)
@@ -2214,7 +2495,8 @@ 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_enabled
+      || ! input_from_terminal_p ()
       || (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 ())))
@@ -2275,16 +2557,16 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
              if (lines_printed >= lines_per_page - 1)
                prompt_for_continue ();
 
-             /* Now output indentation and wrapped string */
+             /* 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 */
+                 *wrap_pointer = '\0'; /* Null-terminate saved stuff, */
+                 fputs_unfiltered (wrap_buffer, stream); /* and eject it.  */
                  /* 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
-                    longer than (the user settable) chars_per_line. 
+                    longer than (the user settable) chars_per_line.
                     Note also that this can set chars_printed > chars_per_line
                     if we are printing a long string.  */
                  chars_printed = strlen (wrap_indent)
@@ -2299,7 +2581,8 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
       if (*lineptr == '\n')
        {
          chars_printed = 0;
-         wrap_here ((char *) 0);       /* Spit out chars, cancel further wraps */
+         wrap_here ((char *) 0);       /* Spit out chars, cancel
+                                          further wraps.  */
          lines_printed++;
          fputc_unfiltered ('\n', stream);
          lineptr++;
@@ -2317,6 +2600,7 @@ int
 putchar_unfiltered (int c)
 {
   char buf = c;
+
   ui_file_write (gdb_stdout, &buf, 1);
   return c;
 }
@@ -2334,6 +2618,7 @@ int
 fputc_unfiltered (int c, struct ui_file *stream)
 {
   char buf = c;
+
   ui_file_write (stream, &buf, 1);
   return c;
 }
@@ -2515,6 +2800,7 @@ void
 fprintf_filtered (struct ui_file *stream, const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   vfprintf_filtered (stream, format, args);
   va_end (args);
@@ -2524,6 +2810,7 @@ void
 fprintf_unfiltered (struct ui_file *stream, const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   vfprintf_unfiltered (stream, format, args);
   va_end (args);
@@ -2537,6 +2824,7 @@ fprintfi_filtered (int spaces, struct ui_file *stream, const char *format,
                   ...)
 {
   va_list args;
+
   va_start (args, format);
   print_spaces_filtered (spaces, stream);
 
@@ -2549,6 +2837,7 @@ void
 printf_filtered (const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   vfprintf_filtered (gdb_stdout, format, args);
   va_end (args);
@@ -2559,6 +2848,7 @@ void
 printf_unfiltered (const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   vfprintf_unfiltered (gdb_stdout, format, args);
   va_end (args);
@@ -2571,6 +2861,7 @@ void
 printfi_filtered (int spaces, const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   print_spaces_filtered (spaces, gdb_stdout);
   vfprintf_filtered (gdb_stdout, format, args);
@@ -2629,7 +2920,7 @@ print_spaces_filtered (int n, struct ui_file *stream)
 /* fprintf_symbol_filtered attempts to demangle NAME, a symbol in language
    LANG, using demangling args ARG_MODE, and print it filtered to STREAM.
    If the name is not mangled, or the language for the name is unknown, or
-   demangling is off, the name is printed in its "raw" form. */
+   demangling is off, the name is printed in its "raw" form.  */
 
 void
 fprintf_symbol_filtered (struct ui_file *stream, char *name,
@@ -2663,7 +2954,7 @@ fprintf_symbol_filtered (struct ui_file *stream, char *name,
    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). */
+   function).  */
 
 int
 strcmp_iw (const char *string1, const char *string2)
@@ -2790,6 +3081,7 @@ int
 subset_compare (char *string_to_compare, char *template_string)
 {
   int match;
+
   if (template_string != (char *) NULL && string_to_compare != (char *) NULL
       && strlen (string_to_compare) <= strlen (template_string))
     match =
@@ -2816,15 +3108,14 @@ static void
 show_debug_timestamp (struct ui_file *file, int from_tty,
                      struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Timestamping debugging messages is %s.\n"), value);
+  fprintf_filtered (file, _("Timestamping debugging messages is %s.\n"),
+                   value);
 }
 \f
 
 void
 initialize_utils (void)
 {
-  struct cmd_list_element *c;
-
   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,
@@ -2889,13 +3180,13 @@ When set, debugging messages will be marked with seconds and microseconds."),
                           &setdebuglist, &showdebuglist);
 }
 
-/* Machine specific function to handle SIGWINCH signal. */
+/* 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 */
+/* Print routines to handle variable size regs, etc.  */
+/* Temporary storage using circular buffer.  */
 #define NUMCELLS 16
 #define CELLSIZE 50
 static char *
@@ -2903,6 +3194,7 @@ get_cell (void)
 {
   static char buf[NUMCELLS][CELLSIZE];
   static int cell = 0;
+
   if (++cell >= NUMCELLS)
     cell = 0;
   return buf[cell];
@@ -2914,7 +3206,7 @@ paddress (struct gdbarch *gdbarch, CORE_ADDR addr)
   /* Truncate address to the size of a target 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.  */
   /* NOTE: This assumes that the significant address information is
      kept in the least significant bits of ADDR - the upper bits were
      either zero or sign extended.  Should gdbarch_address_to_pointer or
@@ -2931,11 +3223,11 @@ static char *
 decimal2str (char *sign, ULONGEST addr, int width)
 {
   /* Steal code from valprint.c:print_decimal().  Should this worry
-     about the real size of addr as the above does? */
+     about the real size of addr as the above does?  */
   unsigned long temp[3];
   char *str = get_cell ();
-
   int i = 0;
+
   do
     {
       temp[i] = addr % (1000 * 1000 * 1000);
@@ -2975,8 +3267,8 @@ octal2str (ULONGEST addr, int width)
 {
   unsigned long temp[3];
   char *str = get_cell ();
-
   int i = 0;
+
   do
     {
       temp[i] = addr % (0100000 * 0100000);
@@ -3070,6 +3362,7 @@ phex_nz (ULONGEST l, int sizeof_l)
     case 8:
       {
        unsigned long high = (unsigned long) (l >> thirty_two);
+
        str = get_cell ();
        if (high == 0)
          xsnprintf (str, CELLSIZE, "%lx",
@@ -3101,6 +3394,7 @@ char *
 hex_string (LONGEST num)
 {
   char *result = get_cell ();
+
   xsnprintf (result, CELLSIZE, "0x%s", phex_nz (num, sizeof (num)));
   return result;
 }
@@ -3120,8 +3414,8 @@ hex_string_custom (LONGEST num, int width)
   if (hex_len > width)
     width = hex_len;
   if (width + 2 >= CELLSIZE)
-    internal_error (__FILE__, __LINE__,
-                   _("hex_string_custom: insufficient space to store result"));
+    internal_error (__FILE__, __LINE__, _("\
+hex_string_custom: insufficient space to store result"));
 
   strcpy (result_end - width - 2, "0x");
   memset (result_end - width, '0', width);
@@ -3134,7 +3428,7 @@ hex_string_custom (LONGEST num, int width)
  * otherwise VAL is interpreted as unsigned.  If WIDTH is supplied, 
  * it is the minimum width (0-padded if needed).  USE_C_FORMAT means
  * to use C format in all cases.  If it is false, then 'x' 
- * and 'o' formats do not include a prefix (0x or leading 0). */
+ * and 'o' formats do not include a prefix (0x or leading 0).  */
 
 char *
 int_string (LONGEST val, int radix, int is_signed, int width, 
@@ -3145,6 +3439,7 @@ int_string (LONGEST val, int radix, int is_signed, int width,
     case 16:
       {
        char *result;
+
        if (width == 0)
          result = hex_string (val);
        else
@@ -3163,6 +3458,7 @@ int_string (LONGEST val, int radix, int is_signed, int width,
     case 8:
       {
        char *result = octal2str (val, width);
+
        if (use_c_format || val == 0)
          return result;
        else
@@ -3179,6 +3475,7 @@ const char *
 core_addr_to_string (const CORE_ADDR addr)
 {
   char *str = get_cell ();
+
   strcpy (str, "0x");
   strcat (str, phex (addr, sizeof (addr)));
   return str;
@@ -3188,6 +3485,7 @@ const char *
 core_addr_to_string_nz (const CORE_ADDR addr)
 {
   char *str = get_cell ();
+
   strcpy (str, "0x");
   strcat (str, phex_nz (addr, sizeof (addr)));
   return str;
@@ -3203,6 +3501,7 @@ string_to_core_addr (const char *my_string)
     {
       /* Assume that it is in hex.  */
       int i;
+
       for (i = 2; my_string[i] != '\0'; i++)
        {
          if (isdigit (my_string[i]))
@@ -3217,6 +3516,7 @@ string_to_core_addr (const char *my_string)
     {
       /* Assume that it is in decimal.  */
       int i;
+
       for (i = 0; my_string[i] != '\0'; i++)
        {
          if (isdigit (my_string[i]))
@@ -3256,6 +3556,7 @@ gdb_realpath (const char *filename)
 # endif
 # if defined (USE_REALPATH)
     const char *rp = realpath (filename, buf);
+
     if (rp == NULL)
       rp = filename;
     return xstrdup (rp);
@@ -3269,6 +3570,7 @@ gdb_realpath (const char *filename)
 #if defined(HAVE_CANONICALIZE_FILE_NAME)
   {
     char *rp = canonicalize_file_name (filename);
+
     if (rp == NULL)
       return xstrdup (filename);
     else
@@ -3296,11 +3598,13 @@ gdb_realpath (const char *filename)
   {
     /* Find out the max path size.  */
     long path_max = pathconf ("/", _PC_PATH_MAX);
+
     if (path_max > 0)
       {
        /* PATH_MAX is bounded.  */
        char *buf = alloca (path_max);
        char *rp = realpath (filename, buf);
+
        return xstrdup (rp ? rp : filename);
       }
   }
@@ -3322,14 +3626,14 @@ xfullpath (const char *filename)
   char *result;
 
   /* Extract the basename of filename, and return immediately 
-     a copy of filename if it does not contain any directory prefix. */
+     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 */
+     then the closing \000 character */
   strncpy (dir_name, filename, base_name - filename);
   dir_name[base_name - filename] = '\000';
 
@@ -3344,7 +3648,7 @@ xfullpath (const char *filename)
 #endif
 
   /* Canonicalize the directory prefix, and build the resulting
-     filename. If the dirname realpath already contains an ending
+     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]))
@@ -3451,6 +3755,7 @@ hashtab_obstack_allocate (void *data, size_t size, size_t count)
 {
   unsigned int total = size * count;
   void *ptr = obstack_alloc ((struct obstack *) data, total);
+
   memset (ptr, 0, total);
   return ptr;
 }
@@ -3602,6 +3907,7 @@ char **
 gdb_buildargv (const char *s)
 {
   char **argv = buildargv (s);
+
   if (s != NULL && argv == NULL)
     nomem (0);
   return argv;
@@ -3616,7 +3922,8 @@ compare_positive_ints (const void *ap, const void *bp)
 }
 
 #define AMBIGUOUS_MESS1        ".\nMatching formats:"
-#define AMBIGUOUS_MESS2        ".\nUse \"set gnutarget format-name\" to specify the format."
+#define AMBIGUOUS_MESS2        \
+  ".\nUse \"set gnutarget format-name\" to specify the format."
 
 const char *
 gdb_bfd_errmsg (bfd_error_type error_tag, char **matching)
This page took 0.041795 seconds and 4 git commands to generate.