** gdb.Objfile now has an attribute named "is_file". This is True
if the objfile comes from a file, and False otherwise.
+ ** New function gdb.print_options that returns a dictionary of the
+ prevailing print options, in the form accepted by
+ gdb.Value.format_string.
+
+ ** gdb.Value.format_string now uses the format provided by 'print',
+ if it is called during a 'print' or other similar operation.
+
* New features in the GDB remote stub, GDBserver
** GDBserver is now supported on LoongArch GNU/Linux.
printer exists, then this returns @code{None}.
@end defun
+Normally, a pretty-printer can respect the user's print settings
+(including temporarily applied settings, such as @samp{/x}) simply by
+calling @code{Value.format_string} (@pxref{Values From Inferior}).
+However, these settings can also be queried directly:
+
+@findex gdb.print_options
+@defun gdb.print_options ()
+Return a dictionary whose keys are the valid keywords that can be
+given to @code{Value.format_string}, and whose values are the user's
+settings. During a @code{print} or other operation, the values will
+reflect any flags that are temporarily in effect.
+
+@smallexample
+(gdb) python print (gdb.print_options ()['max_elements'])
+200
+@end smallexample
+@end defun
+
@node Selecting Pretty-Printers
@subsubsection Selecting Pretty-Printers
@cindex selecting python pretty-printers
string_repr_ok
};
+/* If non-null, points to options that are in effect while
+ printing. */
+const struct value_print_options *gdbpy_current_print_options;
+
/* Helper function for find_pretty_printer which iterates over a list,
calls each function and inspects output. This will return a
printer object if one recognizes VALUE. If no printer is found, it
if (printer == Py_None)
return EXT_LANG_RC_NOP;
+ scoped_restore set_options = make_scoped_restore (&gdbpy_current_print_options,
+ options);
+
/* If we are printing a map, we want some special formatting. */
gdb::unique_xmalloc_ptr<char> hint (gdbpy_get_display_hint (printer.get ()));
gdbpy_ref<>
apply_varobj_pretty_printer (PyObject *printer_obj,
struct value **replacement,
- struct ui_file *stream)
+ struct ui_file *stream,
+ const value_print_options *opts)
{
+ scoped_restore set_options = make_scoped_restore (&gdbpy_current_print_options,
+ opts);
+
*replacement = NULL;
gdbpy_ref<> py_str = pretty_print_one_value (printer_obj, replacement);
return find_pretty_printer (val_obj).release ();
}
+
+/* Helper function to set a boolean in a dictionary. */
+static int
+set_boolean (PyObject *dict, const char *name, bool val)
+{
+ gdbpy_ref<> val_obj (PyBool_FromLong (val));
+ if (val_obj == nullptr)
+ return -1;
+ return PyDict_SetItemString (dict, name, val_obj.get ());
+}
+
+/* Helper function to set an integer in a dictionary. */
+static int
+set_unsigned (PyObject *dict, const char *name, unsigned int val)
+{
+ gdbpy_ref<> val_obj = gdb_py_object_from_ulongest (val);
+ if (val_obj == nullptr)
+ return -1;
+ return PyDict_SetItemString (dict, name, val_obj.get ());
+}
+
+/* Implement gdb.print_options. */
+PyObject *
+gdbpy_print_options (PyObject *unused1, PyObject *unused2)
+{
+ gdbpy_ref<> result (PyDict_New ());
+ if (result == nullptr)
+ return nullptr;
+
+ value_print_options opts;
+ gdbpy_get_print_options (&opts);
+
+ if (set_boolean (result.get (), "raw",
+ opts.raw) < 0
+ || set_boolean (result.get (), "pretty_arrays",
+ opts.prettyformat_arrays) < 0
+ || set_boolean (result.get (), "pretty_structs",
+ opts.prettyformat_structs) < 0
+ || set_boolean (result.get (), "array_indexes",
+ opts.print_array_indexes) < 0
+ || set_boolean (result.get (), "symbols",
+ opts.symbol_print) < 0
+ || set_boolean (result.get (), "unions",
+ opts.unionprint) < 0
+ || set_boolean (result.get (), "address",
+ opts.addressprint) < 0
+ || set_boolean (result.get (), "deref_refs",
+ opts.deref_ref) < 0
+ || set_boolean (result.get (), "actual_objects",
+ opts.objectprint) < 0
+ || set_boolean (result.get (), "static_members",
+ opts.static_field_print) < 0
+ || set_boolean (result.get (), "deref_refs",
+ opts.deref_ref) < 0
+ || set_unsigned (result.get (), "max_elements",
+ opts.print_max) < 0
+ || set_unsigned (result.get (), "max_depth",
+ opts.max_depth) < 0
+ || set_unsigned (result.get (), "repeat_threshold",
+ opts.repeat_count_threshold) < 0)
+ return nullptr;
+
+ if (opts.format != 0)
+ {
+ char str[2] = { (char) opts.format, 0 };
+ gdbpy_ref<> fmtstr = host_string_to_python_string (str);
+ if (fmtstr == nullptr)
+ return nullptr;
+ if (PyDict_SetItemString (result.get (), "format", fmtstr.get ()) < 0)
+ return nullptr;
+ }
+
+ return result.release ();
+}
+
+/* Helper function that either finds the prevailing print options, or
+ calls get_user_print_options. */
+void
+gdbpy_get_print_options (value_print_options *opts)
+{
+ if (gdbpy_current_print_options != nullptr)
+ *opts = *gdbpy_current_print_options;
+ else
+ get_user_print_options (opts);
+}
}
struct value_print_options opts;
- get_user_print_options (&opts);
+ gdbpy_get_print_options (&opts);
opts.deref_ref = 0;
/* We need objects for booleans as the "p" flag for bools is new in
{
struct value_print_options opts;
- get_user_print_options (&opts);
+ gdbpy_get_print_options (&opts);
opts.deref_ref = 0;
string_file stb;
#include "python-internal.h"
#include "varobj.h"
#include "varobj-iter.h"
+#include "valprint.h"
/* A dynamic varobj iterator "class" for python pretty-printed
varobjs. This inherits struct varobj_iter. */
struct py_varobj_iter : public varobj_iter
{
- py_varobj_iter (struct varobj *var, gdbpy_ref<> &&pyiter);
+ py_varobj_iter (struct varobj *var, gdbpy_ref<> &&pyiter,
+ const value_print_options *opts);
~py_varobj_iter () override;
std::unique_ptr<varobj_item> next () override;
/* The python iterator returned by the printer's 'children' method,
or NULL if not available. */
PyObject *m_iter;
+
+ /* The print options to use. */
+ value_print_options m_opts;
};
/* Implementation of the 'dtor' method of pretty-printed varobj
gdbpy_enter_varobj enter_py (m_var);
+ scoped_restore set_options = make_scoped_restore (&gdbpy_current_print_options,
+ &m_opts);
+
gdbpy_ref<> item (PyIter_Next (m_iter));
if (item == NULL)
whose children the iterator will be iterating over. PYITER is the
python iterator actually responsible for the iteration. */
-py_varobj_iter::py_varobj_iter (struct varobj *var, gdbpy_ref<> &&pyiter)
+py_varobj_iter::py_varobj_iter (struct varobj *var, gdbpy_ref<> &&pyiter,
+ const value_print_options *opts)
: m_var (var),
- m_iter (pyiter.release ())
+ m_iter (pyiter.release ()),
+ m_opts (*opts)
{
}
over VAR's children. */
std::unique_ptr<varobj_iter>
-py_varobj_get_iterator (struct varobj *var, PyObject *printer)
+py_varobj_get_iterator (struct varobj *var, PyObject *printer,
+ const value_print_options *opts)
{
gdbpy_enter_varobj enter_py (var);
if (!PyObject_HasAttr (printer, gdbpy_children_cst))
return NULL;
+ scoped_restore set_options = make_scoped_restore (&gdbpy_current_print_options,
+ opts);
+
gdbpy_ref<> children (PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
NULL));
if (children == NULL)
}
return std::unique_ptr<varobj_iter> (new py_varobj_iter (var,
- std::move (iter)));
+ std::move (iter),
+ opts));
}
other pretty-printer functions, because they refer to PyObject. */
gdbpy_ref<> apply_varobj_pretty_printer (PyObject *print_obj,
struct value **replacement,
- struct ui_file *stream);
+ struct ui_file *stream,
+ const value_print_options *opts);
gdbpy_ref<> gdbpy_get_varobj_pretty_printer (struct value *value);
gdb::unique_xmalloc_ptr<char> gdbpy_get_display_hint (PyObject *printer);
PyObject *gdbpy_default_visualizer (PyObject *self, PyObject *args);
+PyObject *gdbpy_print_options (PyObject *self, PyObject *args);
+void gdbpy_get_print_options (value_print_options *opts);
+extern const struct value_print_options *gdbpy_current_print_options;
+
void bpfinishpy_pre_stop_hook (struct gdbpy_breakpoint_object *bp_obj);
void bpfinishpy_post_stop_hook (struct gdbpy_breakpoint_object *bp_obj);
struct varobj_iter;
struct varobj;
-std::unique_ptr<varobj_iter> py_varobj_get_iterator (struct varobj *var,
- PyObject *printer);
+std::unique_ptr<varobj_iter> py_varobj_get_iterator
+ (struct varobj *var,
+ PyObject *printer,
+ const value_print_options *opts);
/* Deleter for Py_buffer unique_ptr specialization. */
"current_language () -> string\n\
Return the name of the currently selected language." },
+ { "print_options", gdbpy_print_options, METH_NOARGS,
+ "print_options () -> dict\n\
+Return the current print options." },
+
{NULL, NULL, 0, NULL}
};
"0010 1010" \
"42 with option ${opts}"
- check_format_string "a_point_t" $opts
+ check_format_string "a_point_t" $opts \
+ [string_to_regexp "Pretty Point (0010 1010, 1100)"]
check_format_string "a_point_t_pointer" $opts \
$binary_pointer_regexp
- check_format_string "another_point" $opts
+ check_format_string "another_point" $opts \
+ [string_to_regexp "Pretty Point (0111 1011, 0001 1100 1000)"]
check_format_string "a_struct_with_union" $opts \
"\\{the_union = \\{an_int = 0010 1010 0010 1010 0010 1010 0010 1010, a_char = 0010 1010\\}\\}"
"0010'1010" \
"42 with option ${opts}"
- check_format_string "a_point_t" $opts
+ check_format_string "a_point_t" $opts \
+ [string_to_regexp "Pretty Point (0010'1010, 1100)"]
check_format_string "a_point_t_pointer" $opts \
$binary_pointer_regexp
- check_format_string "another_point" $opts
+ check_format_string "another_point" $opts \
+ [string_to_regexp "Pretty Point (0111'1011, 0001'1100'1000)"]
check_format_string "a_struct_with_union" $opts \
"\\{the_union = \\{an_int = 0010'1010'0010'1010'0010'1010'0010'1010, a_char = 0010'1010\\}\\}"
check_format_string "a_symbol_pointer" $opts \
$binary_pointer_regexp
- check_format_string "a_point_t_ref" $opts
+ check_format_string "a_point_t_ref" $opts \
+ [string_to_regexp "Pretty Point (0010'1010, 1100)"]
check_format_string "a_base_ref" $opts
}
}
"0x2a" \
"42 with option ${opts}"
- check_format_string "a_point_t" $opts
+ check_format_string "a_point_t" $opts \
+ "Pretty Point \\(0x2a, 0xc\\)"
check_format_string "a_point_t_pointer" $opts
- check_format_string "another_point" $opts
+ check_format_string "another_point" $opts \
+ "Pretty Point \\(0x7b, 0x1c8\\)"
check_format_string "a_struct_with_union" $opts \
"\\{the_union = \\{an_int = 0x2a2a2a2a, a_char = 0x2a\\}\\}"
check_format_string "an_enum" $opts \
$default_pointer_regexp
if { $current_lang == "c++" } {
- check_format_string "a_point_t_ref" $opts
+ check_format_string "a_point_t_ref" $opts \
+ "Pretty Point \\(0x2a, 0xc\\)"
check_format_string "a_base_ref" $opts
}
}
"101010" \
"42 with option ${opts}"
- check_format_string "a_point_t" $opts
+ check_format_string "a_point_t" $opts \
+ "Pretty Point \\(101010, 1100\\)"
check_format_string "a_point_t_pointer" $opts \
$binary_pointer_regexp
- check_format_string "another_point" $opts
+ check_format_string "another_point" $opts \
+ "Pretty Point \\(1111011, 111001000\\)"
check_format_string "a_struct_with_union" $opts \
"\\{the_union = \\{an_int = 101010001010100010101000101010, a_char = 101010\\}\\}"
check_format_string "an_enum" $opts \
$binary_pointer_regexp
if { $current_lang == "c++" } {
- check_format_string "a_point_t_ref" $opts
+ check_format_string "a_point_t_ref" $opts \
+ "Pretty Point \\(101010, 1100\\)"
check_format_string "a_base_ref" $opts
}
}
"{[style x variable] = 42, [style y variable] = 12}"
}
+# Test the gdb.print_options API.
+proc test_print_options {} {
+ gdb_test_no_output "set print elements 500"
+ gdb_test "python print(gdb.print_options()\['max_elements'\])" "500" \
+ "examine max elements"
+ gdb_test "python print('format' in gdb.print_options())" "False" \
+ "examine format"
+
+ check_format_string "a_point_t" "format='t'" \
+ "Pretty Point \\(101010, 1100\\)" \
+ "print in binary to fetch options"
+ gdb_test "python print(saved_options\['format'\] == 't')" "True" \
+ "format was set"
+}
+
# Run all the tests in common for both C and C++.
proc_with_prefix test_all_common {} {
# No options.
test_mixed
# Various error conditions.
test_invalid_args
+ test_print_options
}
# The current language ("c" or "c++" while running tests).
import gdb
+saved_options = {}
+
class PointPrinter(object):
def __init__(self, val):
self.val = val
def to_string(self):
+ global saved_options
+ saved_options = gdb.print_options()
return "Pretty Point (%s, %s)" % (self.val["x"], self.val["y"])
{
#if HAVE_PYTHON
if (var->dynamic->pretty_printer)
- return py_varobj_get_iterator (var, var->dynamic->pretty_printer);
+ {
+ value_print_options opts;
+ varobj_formatted_print_options (&opts, var->format);
+ return py_varobj_get_iterator (var, var->dynamic->pretty_printer, &opts);
+ }
#endif
gdb_assert_not_reached ("requested an iterator from a non-dynamic varobj");
string_file stb;
std::string thevalue;
+ varobj_formatted_print_options (&opts, format);
+
#if HAVE_PYTHON
if (gdb_python_initialized)
{
gdbpy_ref<> output = apply_varobj_pretty_printer (value_formatter,
&replacement,
- &stb);
+ &stb,
+ &opts);
/* If we have string like output ... */
if (output != NULL)
}
#endif
- varobj_formatted_print_options (&opts, format);
-
/* If the THEVALUE has contents, it is a regular string. */
if (!thevalue.empty ())
current_language->printstr (&stb, type, (gdb_byte *) thevalue.c_str (),