gdb.Symbol. The block argument must be an instance of gdb.Block. Returns
NULL on error, with a python exception set. */
static PyObject *
-frapy_read_var (PyObject *self, PyObject *args)
+frapy_read_var (PyObject *self, PyObject *args, PyObject *kw)
{
frame_info_ptr frame;
PyObject *sym_obj, *block_obj = NULL;
struct symbol *var = NULL; /* gcc-4.3.2 false warning. */
const struct block *block = NULL;
- if (!PyArg_ParseTuple (args, "O|O", &sym_obj, &block_obj))
- return NULL;
+ static const char *keywords[] = { "variable", "block", nullptr };
+ if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O|O!", keywords,
+ &sym_obj, &block_object_type,
+ &block_obj))
+ return nullptr;
if (PyObject_TypeCheck (sym_obj, &symbol_object_type))
var = symbol_object_to_symbol (sym_obj);
if (!var_name)
return NULL;
- if (block_obj)
+ if (block_obj != nullptr)
{
+ /* This call should only fail if the type of BLOCK_OBJ is wrong,
+ and we ensure the type is correct when we parse the arguments,
+ so we can just assert the return value is not nullptr. */
block = block_object_to_block (block_obj);
- if (!block)
- {
- PyErr_SetString (PyExc_RuntimeError,
- _("Second argument must be block."));
- return NULL;
- }
+ gdb_assert (block != nullptr);
}
try
}
else
{
- PyErr_SetString (PyExc_TypeError,
- _("Argument must be a symbol or string."));
+ PyErr_Format (PyExc_TypeError,
+ _("argument 1 must be gdb.Symbol or str, not %s"),
+ Py_TYPE (sym_obj)->tp_name);
return NULL;
}
{ "find_sal", frapy_find_sal, METH_NOARGS,
"find_sal () -> gdb.Symtab_and_line.\n\
Return the frame's symtab and line." },
- { "read_var", frapy_read_var, METH_VARARGS,
+ { "read_var", (PyCFunction) frapy_read_var, METH_VARARGS | METH_KEYWORDS,
"read_var (variable) -> gdb.Value.\n\
Return the value of the variable in this frame." },
{ "select", frapy_select, METH_NOARGS,
gdb_test "python print (bf1.read_var(\"f\"))" "\"foo\"" "test f"
gdb_test "python print (bf1.read_var(\"b\"))" "\"bar\"" "test b"
+# Check we can use a single named argument with read_var.
+gdb_test "python print (bf1.read_var(variable = \"b\"))" "\"bar\"" \
+ "test b using named arguments"
+
# Test the read_var function in another block other than the current
# block (in this case, the super block). Test thar read_var is reading
# the correct variables of i and f but they are the correct value and type.
gdb_test "python print (bf1.read_var(\"f\", sb))" "2.2.*" "test f = 2.2"
gdb_test "python print (bf1.read_var(\"f\", sb).type)" "double" "test double f"
+# Now test read_var with a variable and block using named arguments.
+gdb_test "python print (bf1.read_var(block = sb, variable = \"i\"))" "1.1.*" \
+ "test i = 1.1 usign named arguments"
+gdb_test "python print (bf1.read_var(block = sb, variable = \"f\"))" "2.2.*" \
+ "test f = 2.2 using named arguments"
+
# And again test another outerblock, this time testing "i" is the
# correct value and type.
gdb_py_test_silent_cmd "python sb = sb.superblock" "get superblock" 0
gdb_test "python print (bf1.read_var(\"i\", sb))" "99" "test i = 99"
gdb_test "python print (bf1.read_var(\"i\", sb).type)" "int" "test int i"
+# Test what happens when we provide a block of the wrong type.
+gdb_test "python print (bf1.read_var(\"i\", \"some_block\"))" \
+ [multi_line \
+ "TypeError: argument 2 must be gdb\\.Block, not str" \
+ "Error while executing Python code\\."] \
+ "check invalid block type error"
+gdb_test "python print (bf1.read_var(block = \"some_block\", variable = \"i\"))" \
+ [multi_line \
+ "TypeError: argument 2 must be gdb\\.Block, not str" \
+ "Error while executing Python code\\."] \
+ "check invalid block type error when named args are used"
+
+# Test what happens when we provide a variable of the wrong type.
+gdb_test "python print (bf1.read_var(None))" \
+ [multi_line \
+ "TypeError: argument 1 must be gdb\\.Symbol or str, not NoneType" \
+ "Error while executing Python code\\."] \
+ "check read_var error when variable is None"
+gdb_test "python print (bf1.read_var(sb))" \
+ [multi_line \
+ "TypeError: argument 1 must be gdb\\.Symbol or str, not gdb\\.Block" \
+ "Error while executing Python code\\."] \
+ "check read_var error when variable is a gdb.Block"
+
gdb_breakpoint "f2"
gdb_continue_to_breakpoint "breakpoint at f2"
gdb_py_test_silent_cmd "python bframe = gdb.selected_frame()" \