This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Fix python gdb.execute to not paginate


Hi,

downstream Bug: https://bugzilla.redhat.com/show_bug.cgi?id=620930
(gdb) python for i in range(100): a = gdb.execute('info registers', to_string=True)
---Type <return> to continue, or q <return> to quit---

When at it I have merged it with making --batch more batch, as the output IMO
should not depend on the momentarily terminal - wrapping and indenting the
output on its width.

The patch makes python gdb.execute running in the --batch mode.  I understand
it may not be universally right but so far I believe it is.  What do you
think?

(--batch should be IMO somehow merged now with `set interactive-mode'.  That
is not a part of this patch.)


Regards,
Jan


gdb/
2010-08-05  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* defs.h (make_cleanup_restore_uinteger)
	(make_cleanup_restore_page_info): New declarations.
	* python/python.c: Include main.h.
	(execute_gdb_command) <to_string>: Temporarily set BATCH_FLAG and call
	init_page_info.
	* utils.c (make_cleanup_restore_uinteger)
	(init_page_info) <batch_flag>
	(do_restore_page_info_cleanup, make_cleanup_restore_page_info): New.

gdb/testsuite/
2010-08-05  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.python/python.exp (show height, set height 10)
	(verify pagination beforehand, verify pagination beforehand: q)
	(gdb.execute does not page, verify pagination afterwards)
	(verify pagination afterwards: q): New.

gdb/doc/
2010-08-05  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.texinfo (Mode Options) <-batch>
	(Basic Python) <gdb.execute>: Describe setting width and height.

--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -351,6 +351,7 @@ struct obstack;
 extern struct cleanup *make_cleanup_obstack_free (struct obstack *obstack);
 
 extern struct cleanup *make_cleanup_restore_integer (int *variable);
+extern struct cleanup *make_cleanup_restore_uinteger (unsigned int *variable);
 
 struct target_ops;
 extern struct cleanup *make_cleanup_unpush_target (struct target_ops *ops);
@@ -385,6 +386,7 @@ extern int nquery (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
 extern int yquery (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
 
 extern void init_page_info (void);
+extern struct cleanup *make_cleanup_restore_page_info (void);
 
 extern char *gdb_realpath (const char *);
 extern char *xfullpath (const char *);
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -46,6 +46,7 @@ static int gdbpy_should_print_stack = 1;
 #include "version.h"
 #include "target.h"
 #include "gdbthread.h"
+#include "main.h"
 
 static PyMethodDef GdbMethods[];
 
@@ -380,6 +381,13 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
 
       if (to_string)
 	{
+	  /* GDB_STDOUT should be better already restored during these
+	     restoration callbacks.  */
+	  make_cleanup_restore_page_info ();
+	  make_cleanup_restore_integer (&batch_flag);
+	  batch_flag = 1;
+	  init_page_info ();
+
 	  str_file = mem_fileopen ();
 
 	  make_cleanup_restore_ui_file (&gdb_stdout);
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -352,6 +352,14 @@ 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
@@ -2052,6 +2060,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
@@ -2096,6 +2110,25 @@ init_page_info (void)
   set_width ();
 }
 
+static void
+do_restore_page_info_cleanup (void *arg)
+{
+  set_screen_size ();
+  set_width ();
+}
+
+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;
+}
+
 /* Set the screen size based on LINES_PER_PAGE and CHARS_PER_LINE.  */
 
 static void
--- a/gdb/testsuite/gdb.python/python.exp
+++ b/gdb/testsuite/gdb.python/python.exp
@@ -87,3 +87,26 @@ gdb_test "python import itertools; print 'IMPOR'+'TED'" "IMPORTED" "pythonX.Y/li
 gdb_test_no_output \
     "python x = gdb.execute('printf \"%d\", 23', to_string = True)"
 gdb_test "python print x" "23"
+
+# Test (no) pagination of the executed command.
+gdb_test "show height" {Number of lines gdb thinks are in a page is unlimited\.}
+set lines 10
+gdb_test_no_output "set height $lines"
+
+set test "verify pagination beforehand"
+gdb_test_multiple "python print \"\\n\" * $lines" $test {
+    -re "---Type <return> to continue, or q <return> to quit---$" {
+	pass $test
+    }
+}
+gdb_test "q" "Quit" "verify pagination beforehand: q"
+
+gdb_test "python if gdb.execute('python print \"\\\\n\" * $lines', to_string=True) == \"\\n\" * [expr $lines + 1]: print \"yes\"" "yes" "gdb.execute does not page"
+
+set test "verify pagination afterwards"
+gdb_test_multiple "python print \"\\n\" * $lines" $test {
+    -re "---Type <return> to continue, or q <return> to quit---$" {
+	pass $test
+    }
+}
+gdb_test "q" "Quit" "verify pagination afterwards: q"
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -1031,9 +1031,9 @@ Run in batch mode.  Exit with status @code{0} after processing all the
 command files specified with @samp{-x} (and all commands from
 initialization files, if not inhibited with @samp{-n}).  Exit with
 nonzero status if an error occurs in executing the @value{GDBN} commands
-in the command files.  Batch mode also disables pagination;
-@pxref{Screen Size} and acts as if @kbd{set confirm off} were in
-effect (@pxref{Messages/Warnings}).
+in the command files.  Batch mode also disables pagination, sets unlimited
+terminal width and height; @pxref{Screen Size} and acts as if @kbd{set confirm
+off} were in effect (@pxref{Messages/Warnings}).
 
 Batch mode may be useful for running @value{GDBN} as a filter, for
 example to download and run a program on another computer; in order to
@@ -20484,7 +20484,9 @@ By default, any output produced by @var{command} is sent to
 @value{GDBN}'s standard output.  If the @var{to_string} parameter is
 @code{True}, then output will be collected by @code{gdb.execute} and
 returned as a string.  The default is @code{False}, in which case the
-return value is @code{None}.
+return value is @code{None}.  With @code{True} @var{to_string} the
+@value{GDBN} virtual terminal has temporarily set unlimited width and height
+with disabled pagination; @pxref{Screen Size}.
 @end defun
 
 @findex gdb.breakpoints


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]