Add gdb.current_language and gdb.Frame.language
authorTom Tromey <tromey@adacore.com>
Tue, 24 May 2022 16:15:17 +0000 (10:15 -0600)
committerTom Tromey <tromey@adacore.com>
Wed, 1 Jun 2022 12:15:53 +0000 (06:15 -0600)
This adds the gdb.current_language function, which can be used to find
the current language without (1) ever having the value "auto" or (2)
having to parse the output of "show language".

It also adds the gdb.Frame.language, which can be used to find the
language of a given frame.  This is normally preferable if one has a
Frame object handy.

gdb/NEWS
gdb/doc/python.texi
gdb/python/py-frame.c
gdb/python/python.c
gdb/testsuite/gdb.python/py-frame.exp
gdb/testsuite/gdb.python/py-parameter.exp
gdb/testsuite/gdb.rust/pp.exp

index dac6dabfa42f37066acf3bd96e00b980a7d17c26..960f90b4387b01ad02d144c2cd347e6ea45fb299 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -58,6 +58,13 @@ maintenance info line-table
      This is the same format that GDB uses when printing address, symbol,
      and offset information from the disassembler.
 
+  ** New function gdb.current_language that returns the name of the
+     current language.  Unlike gdb.parameter('language'), this will
+     never return 'auto'.
+
+  ** New method gdb.Frame.language that returns the name of the
+     frame's language.
+
 *** Changes in GDB 12
 
 * DBX mode is deprecated, and will be removed in GDB 13
index f933c7d30c9ad955706409235689d349ae71fa50..ba5a9b315e19f290f71d4fea26cdb7515822514f 100644 (file)
@@ -668,6 +668,14 @@ Here are some examples of the possible string formats:
 @end smallexample
 @end defun
 
+@defun gdb.current_language ()
+Return the name of the current language as a string.  Unlike
+@code{gdb.parameter('language')}, this function will never return
+@samp{auto}.  If a @code{gdb.Frame} object is available (@pxref{Frames
+In Python}), the @code{language} method might be preferable in some
+cases, as that is not affected by the user's language setting.
+@end defun
+
 @node Exception Handling
 @subsubsection Exception Handling
 @cindex python exceptions
@@ -5202,6 +5210,10 @@ Stack}.
 Return an integer, the stack frame level for this frame.  @xref{Frames, ,Stack Frames}.
 @end defun
 
+@defun Frame.language ()
+Return a string, the source language for this frame.
+@end defun
+
 @node Blocks In Python
 @subsubsection Accessing blocks from Python
 
index 769e28c1a2c361c0eac3662a3d100a11f0b76dc5..9a28c36c1cc5fefa895e72aafa04172936f3887c 100644 (file)
@@ -598,6 +598,29 @@ frapy_level (PyObject *self, PyObject *args)
   Py_RETURN_NONE;
 }
 
+/* The language for this frame.  */
+
+static PyObject *
+frapy_language (PyObject *self, PyObject *args)
+{
+  try
+    {
+      struct frame_info *fi;
+      FRAPY_REQUIRE_VALID (self, fi);
+
+      enum language lang = get_frame_language (fi);
+      const language_defn *lang_def = language_def (lang);
+
+      return host_string_to_python_string (lang_def->name ()).release ();
+    }
+  catch (const gdb_exception &except)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+
+  Py_RETURN_NONE;
+}
+
 /* Implementation of gdb.newest_frame () -> gdb.Frame.
    Returns the newest frame object.  */
 
@@ -771,6 +794,8 @@ Return the value of the variable in this frame." },
     "Select this frame as the user's current frame." },
   { "level", frapy_level, METH_NOARGS,
     "The stack level of this frame." },
+  { "language", frapy_language, METH_NOARGS,
+    "The language of this frame." },
   {NULL}  /* Sentinel */
 };
 
index 11aaa7ae778d5fb7ec6ffe4f9412231433d93b9e..9bef2252e88f9215b700d12902bf4f65abd41d10 100644 (file)
@@ -1571,6 +1571,14 @@ gdbpy_progspaces (PyObject *unused1, PyObject *unused2)
   return list.release ();
 }
 
+/* Return the name of the current language.  */
+
+static PyObject *
+gdbpy_current_language (PyObject *unused1, PyObject *unused2)
+{
+  return host_string_to_python_string (current_language->name ()).release ();
+}
+
 \f
 
 /* The "current" objfile.  This is set when gdb detects that a new
@@ -2534,6 +2542,10 @@ Format ADDRESS, an address within PROG_SPACE, a gdb.Progspace, using\n\
 ARCH, a gdb.Architecture to determine the address size.  The format of\n\
 the returned string is 'ADDRESS <SYMBOL+OFFSET>' without the quotes." },
 
+  { "current_language", gdbpy_current_language, METH_NOARGS,
+    "current_language () -> string\n\
+Return the name of the currently selected language." },
+
   {NULL, NULL, 0, NULL}
 };
 
index b91ffe62a83f2ec46241b8897e07c99bff9c79e3..4991e8a0c5db1113a78038b34a3df3f0619e9ca1 100644 (file)
@@ -128,3 +128,9 @@ if { $pc != "" } {
        " = True" \
        "test Frame.read_register($pc)"
 }
+
+# Test language.
+gdb_test "python print(gdb.selected_frame().language())" "c"
+gdb_test "set language ada"
+gdb_test "python print(gdb.selected_frame().language())" "c" \
+    "frame language is not affected by global language"
index 199d3bc16ec3d704cb826c97f4d0058b04633662..db158ddec26108c544aae5c41955f19851cef3ae 100644 (file)
@@ -370,6 +370,19 @@ proc_with_prefix test_throwing_parameter { } {
        "gdb.GdbError does not show Python stack"
 }
 
+proc_with_prefix test_language {} {
+    gdb_test "python print(gdb.parameter('language'))" "auto" \
+       "print language parameter"
+    gdb_test "python print(gdb.current_language())" "c" \
+       "print current language"
+    gdb_test_no_output "set lang rust"
+    gdb_test "python print(gdb.parameter('language'))" "rust" \
+       "print language parameter for rust"
+    gdb_test "python print(gdb.current_language())" "rust" \
+       "print current language for rust"
+    gdb_test_no_output "set lang auto"
+}
+
 test_directories
 test_data_directory
 test_boolean_parameter
@@ -380,6 +393,7 @@ test_really_undocumented_parameter
 test_deprecated_api_parameter
 test_integer_parameter
 test_throwing_parameter
+test_language
 
 # This caused a gdb crash.
 gdb_test "python print(gdb.parameter('endian'))" "auto" \
index 7c7c78b5847c666470a6f46b463923ab2138b480..e3e226c5db515daa83aaccfec716a086823b7881 100644 (file)
@@ -40,3 +40,5 @@ if {![runto ${srcfile}:$line]} {
 
 gdb_test "print outer" " = pp::Outer \\(x\\(5\\)\\)"
 gdb_test "print outer.0" " = x\\(5\\)"
+
+gdb_test "python print(gdb.selected_frame().language())" "rust"