This is the mail archive of the archer@sourceware.org mailing list for the Archer 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]

[python][rfc] Change gdb.Breakpoint to use attributes instead ofmethods.


Hi,

Here's a patch that changes almost all of gdb.Breakpoint methods to
attributes. Most are settable. I kept is_valid as a method because I
think it conveys better the idea that the validity of the breakpoint may
change over time.

'number' and 'location' are readonly attributes because GDB doesn't
provide a way to change them. 'commands' is readonly because it would
involve some work to make it settable from Python. I won't work on that,
at least for now.

The setter for 'hit_count' imposes the artificial restriction that you
can only set it to zero (to keep the semantics of the previous
'clear_hit_count' method. Would it be useful to lift the restriction?

The 'silent' attribute has a gotcha: if it is True, then it's guaranteed
that the breakpoint will be silent. But if it's False, then it may still
be silent if the first command associated with the breakpoint is
"silent". This is due to the way a breakpoint is silenced (see the
places which set bs->print to 0 in bpstat_stop_status). Again, I won't
work on that, at least for now.

The 'condition' attribute also has a gotcha: if the expression is not
valid, an exception will be thrown but the expression will still be set
as the condition of the breakpoint. This also happens with the
"condition" command in the CLI, so it's an issue (or a feature?) of GDB
itself, and not this code.

Finally, since this patch refactors condition_command, I'll run a
regression test on it before committing to the branch in case you agree
with the changes.

What do you think?
-- 
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center


2008-12-10  Thiago Jung Bauermann  <bauerman@br.ibm.com>

	Change gdb.Breakpoint to use attributes instead of methods.
	* breakpoint.c (set_breakpoint_condition): New function, with code
	factored out of condition_command.
	(condition_command): Call set_breakpoint_condition.
	* breakpoint.h (set_breakpoint_command): New prototype.
	* python/python-breakpoint.c (BPPY_SET_REQUIRE_VALID): New macro.
	(bppy_is_enabled): Rename to ...
	(bppy_get_enabled): ... this.  Change to conform to Python attribute
	getter signature.
	(bppy_is_silent): Rename to ...
	(bppy_get_silent): ... this.  Change to conform to Python attribute
	getter signature.
	(bppy_set_enabled): Convert to Python attribute getter.
	(bppy_set_silent): Likewise.
	(bppy_set_thread): Likewise.
	(bppy_set_ignore_count): Likewise.
	(bppy_clear_hit_count): Rename to ...
	(bppy_set_hit_count): ... this.  Convert to Python attribute getter.
	(bppy_get_location): Change to conform to Python attribute getter
	signature.
	(bppy_get_condition): Likewise.
	(bppy_set_condition): New function.
	(bppy_get_commands): Change to conform to Python attribute getter
	signature.
	(bppy_get_number): Change to conform to Python attribute getter
	signature.
	(bppy_get_thread): Change to conform to Python attribute getter
	signature.
	(bppy_get_hit_count): Change to conform to Python attribute getter
	signature.
	(bppy_get_ignore_count): Change to conform to Python attribute getter
	signature.
	(gdbpy_get_breakpoints): Rename to ...
	(gdbpy_breakpoints): ... this.
	(breakpoint_object_getset): New array.
	(breakpoint_object_methods): Remove most methods in favour of
	attributes.
	(breakpoint_object_type): Register breakpoint_object_getset.
	* python/python-internal.h (gdbpy_get_breakpoints): Rename prototype
	to ...
	(gdbpy_breakpoints): ... this.
	(GDB_PY_SET_HANDLE_EXCEPTION): New macro.
	* python/python.c (GdbMethods): Rename `get_breakpoints' entry to
	`breakpoints'.
	* python/lib/gdb/command/save_breakpoints.py: Adjust to
	new gdb.Breakpoint attributes.

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 9737ece..6d8c027 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -522,8 +522,54 @@ get_number_or_range (char **pp)
   return last_retval;
 }
 
-
 
+/* Set break condition of breakpoint B to EXP.  */
+
+void
+set_breakpoint_condition (struct breakpoint *b, char *exp, int from_tty)
+{
+  struct bp_location *loc = b->loc;
+
+  for (; loc; loc = loc->next)
+    {
+      if (loc->cond)
+	{
+	  xfree (loc->cond);
+	  loc->cond = 0;
+	}
+    }
+
+  if (b->cond_string != NULL)
+    xfree (b->cond_string);
+
+  if (*exp == 0)
+    {
+      b->cond_string = NULL;
+      if (from_tty)
+	printf_filtered (_("Breakpoint %d now unconditional.\n"), b->number);
+    }
+  else
+    {
+      char *arg = exp;
+
+      /* I don't know if it matters whether this is the string the user
+	 typed in or the decompiled expression.  */
+      b->cond_string = savestring (arg, strlen (arg));
+      b->condition_not_parsed = 0;
+      for (loc = b->loc; loc; loc = loc->next)
+	{
+	  arg = exp;
+	  loc->cond =
+	    parse_exp_1 (&arg, block_for_pc (loc->address), 0);
+	  if (*arg)
+	    error (_("Junk at end of expression"));
+	}
+    }
+
+  breakpoints_changed ();
+  observer_notify_breakpoint_modified (b->number);
+}
+
 /* condition N EXP -- set break condition of breakpoint N to EXP.  */
 
 static void
@@ -544,42 +590,7 @@ condition_command (char *arg, int from_tty)
   ALL_BREAKPOINTS (b)
     if (b->number == bnum)
       {
-	struct bp_location *loc = b->loc;
-	for (; loc; loc = loc->next)
-	  {
-	    if (loc->cond)
-	      {
-		xfree (loc->cond);
-		loc->cond = 0;
-	      }
-	  }
-	if (b->cond_string != NULL)
-	  xfree (b->cond_string);
-
-	if (*p == 0)
-	  {
-	    b->cond_string = NULL;
-	    if (from_tty)
-	      printf_filtered (_("Breakpoint %d now unconditional.\n"), bnum);
-	  }
-	else
-	  {
-	    arg = p;
-	    /* I don't know if it matters whether this is the string the user
-	       typed in or the decompiled expression.  */
-	    b->cond_string = savestring (arg, strlen (arg));
-	    b->condition_not_parsed = 0;
-	    for (loc = b->loc; loc; loc = loc->next)
-	      {
-		arg = p;
-		loc->cond =
-		  parse_exp_1 (&arg, block_for_pc (loc->address), 0);
-		if (*arg)
-		  error (_("Junk at end of expression"));
-	      }
-	  }
-	breakpoints_changed ();
-	observer_notify_breakpoint_modified (b->number);
+	set_breakpoint_condition (b, p, from_tty);
 	return;
       }
 
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index cff6c3f..60d3245 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -863,4 +863,7 @@ extern void breakpoint_retire_moribund (void);
 /* Tell a breakpoint to be quiet.  */
 extern void make_breakpoint_silent (struct breakpoint *);
 
+/* Set break condition of breakpoint B to EXP.  */
+extern void set_breakpoint_condition (struct breakpoint *b, char *exp, int from_tty);
+
 #endif /* !defined (BREAKPOINT_H) */
diff --git a/gdb/python/lib/gdb/command/save_breakpoints.py b/gdb/python/lib/gdb/command/save_breakpoints.py
index eeeb5dd..a2bed0d 100644
--- a/gdb/python/lib/gdb/command/save_breakpoints.py
+++ b/gdb/python/lib/gdb/command/save_breakpoints.py
@@ -38,22 +38,22 @@ The breakpoints can be restored using the 'source' command."""
 
     def invoke (self, arg, from_tty):
         self.dont_repeat ()
-        bps = gdb.get_breakpoints ()
+        bps = gdb.breakpoints ()
         if bps is None:
             raise RuntimeError, 'No breakpoints to save'
         with open (arg.strip (), 'w') as f:
             for bp in bps:
-                print >> f, "break", bp.get_location (),
-                if bp.get_thread () is not None:
-                    print >> f, " thread", bp.get_thread (),
-                if bp.get_condition () is not None:
-                    print >> f, " if", bp.get_condition (),
+                print >> f, "break", bp.location,
+                if bp.thread is not None:
+                    print >> f, " thread", bp.thread,
+                if bp.condition is not None:
+                    print >> f, " if", bp.condition,
                 print >> f
-                if not bp.is_enabled ():
-                    print >> f, "disable $bpnum"
+                if not bp.enabled:
+                    print >> f, "disable %d" % bp.number
                 # Note: we don't save the ignore count; there doesn't
                 # seem to be much point.
-                commands = bp.get_commands ()
+                commands = bp.commands
                 if commands is not None:
                     print >> f, "commands"
                     # Note that COMMANDS has a trailing newline.
diff --git a/gdb/python/python-breakpoint.c b/gdb/python/python-breakpoint.c
index 0dfeb28..4c79093 100644
--- a/gdb/python/python-breakpoint.c
+++ b/gdb/python/python-breakpoint.c
@@ -81,6 +81,18 @@ struct breakpoint_object
 			     (Breakpoint)->number);			\
     } while (0)
 
+/* Require that BREAKPOINT be a valid breakpoint ID; throw a Python
+   exception if it is invalid.  This macro is for use in setter functions.  */
+#define BPPY_SET_REQUIRE_VALID(Breakpoint)				\
+    do {								\
+      if (! BPPY_VALID_P ((Breakpoint)->number))			\
+        {								\
+	  PyErr_Format (PyExc_RuntimeError, "breakpoint %d is invalid", \
+			(Breakpoint)->number);				\
+	  return -1;							\
+	}								\
+    } while (0)
+
 /* Python function which checks the validity of a breakpoint object.  */
 static PyObject *
 bppy_is_valid (PyObject *self, PyObject *args)
@@ -92,7 +104,7 @@ bppy_is_valid (PyObject *self, PyObject *args)
 
 /* Python function to test whether or not the breakpoint is enabled.  */
 static PyObject *
-bppy_is_enabled (PyObject *self, PyObject *args)
+bppy_get_enabled (PyObject *self, void *closure)
 {
   if (! ((breakpoint_object *) self)->bp)
     Py_RETURN_FALSE;
@@ -104,7 +116,7 @@ bppy_is_enabled (PyObject *self, PyObject *args)
 
 /* Python function to test whether or not the breakpoint is silent.  */
 static PyObject *
-bppy_is_silent (PyObject *self, PyObject *args)
+bppy_get_silent (PyObject *self, void *closure)
 {
   BPPY_REQUIRE_VALID ((breakpoint_object *) self);
   if (((breakpoint_object *) self)->bp->silent)
@@ -113,98 +125,153 @@ bppy_is_silent (PyObject *self, PyObject *args)
 }
 
 /* Python function to set the enabled state of a breakpoint.  */
-static PyObject *
-bppy_set_enabled (PyObject *self, PyObject *newvalue)
+static int
+bppy_set_enabled (PyObject *self, PyObject *newvalue, void *closure)
 {
   breakpoint_object *self_bp = (breakpoint_object *) self;
 
-  BPPY_REQUIRE_VALID (self_bp);
-  if (! PyBool_Check (newvalue))
-    return PyErr_Format (PyExc_RuntimeError, "argument must be boolean");
+  BPPY_SET_REQUIRE_VALID (self_bp);
+
+  if (newvalue == NULL)
+    {
+      PyErr_SetString (PyExc_TypeError, "cannot delete `enabled' attribute");
+      return -1;
+    }
+  else if (! PyBool_Check (newvalue))
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "the value of `enabled' must be a boolean");
+      return -1;
+    }
 
   if (newvalue == Py_True)
     enable_breakpoint (self_bp->bp);
   else
     disable_breakpoint (self_bp->bp);
 
-  Py_RETURN_NONE;
+  return 0;
 }
 
 /* Python function to set the 'silent' state of a breakpoint.  */
-static PyObject *
-bppy_set_silent (PyObject *self, PyObject *newvalue)
+static int
+bppy_set_silent (PyObject *self, PyObject *newvalue, void *closure)
 {
   breakpoint_object *self_bp = (breakpoint_object *) self;
 
-  BPPY_REQUIRE_VALID (self_bp);
-  if (! PyBool_Check (newvalue))
-    return PyErr_Format (PyExc_RuntimeError, "argument must be boolean");
+  BPPY_SET_REQUIRE_VALID (self_bp);
+
+  if (newvalue == NULL)
+    {
+      PyErr_SetString (PyExc_TypeError, "cannot delete `silent' attribute");
+      return -1;
+    }
+  else if (! PyBool_Check (newvalue))
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "the value of `silent' must be a boolean");
+      return -1;
+    }
 
   self_bp->bp->silent = (newvalue == Py_True);
 
-  Py_RETURN_NONE;
+  return 0;
 }
 
 /* Python function to set the thread of a breakpoint.  */
-static PyObject *
-bppy_set_thread (PyObject *self, PyObject *newvalue)
+static int
+bppy_set_thread (PyObject *self, PyObject *newvalue, void *closure)
 {
   breakpoint_object *self_bp = (breakpoint_object *) self;
   int id;
 
-  BPPY_REQUIRE_VALID (self_bp);
-  if (PyInt_Check (newvalue))
+  BPPY_SET_REQUIRE_VALID (self_bp);
+
+  if (newvalue == NULL)
+    {
+      PyErr_SetString (PyExc_TypeError, "cannot delete `thread' attribute");
+      return -1;
+    }
+  else if (PyInt_Check (newvalue))
     {
       id = (int) PyInt_AsLong (newvalue);
       if (! valid_thread_id (id))
-	return PyErr_Format (PyExc_RuntimeError, "invalid thread id");
+	{
+	  PyErr_SetString (PyExc_RuntimeError, "invalid thread id");
+	  return -1;
+	}
     }
   else if (newvalue == Py_None)
     id = -1;
   else
-    return PyErr_Format (PyExc_RuntimeError, "invalid thread id");
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "the value of `thread' must be an integer or None");
+      return -1;
+    }
 
   self_bp->bp->thread = id;
 
-  Py_RETURN_NONE;
+  return 0;
 }
 
 /* Python function to set the ignore count of a breakpoint.  */
-static PyObject *
-bppy_set_ignore_count (PyObject *self, PyObject *newvalue)
+static int
+bppy_set_ignore_count (PyObject *self, PyObject *newvalue, void *closure)
 {
   breakpoint_object *self_bp = (breakpoint_object *) self;
   long value;
 
-  BPPY_REQUIRE_VALID (self_bp);
-  if (! PyInt_Check (newvalue))
-    return PyErr_Format (PyExc_RuntimeError, "argument must be integer");
+  BPPY_SET_REQUIRE_VALID (self_bp);
+
+  if (newvalue == NULL)
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "cannot delete `ignore_count' attribute");
+      return -1;
+    }
+  else if (! PyInt_Check (newvalue))
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "the value of `ignore_count' must be an integer");
+      return -1;
+    }
 
   value = PyInt_AsLong (newvalue);
   if (value < 0)
     value = 0;
   set_ignore_count (self_bp->number, (int) value, 0);
 
-  Py_RETURN_NONE;
+  return 0;
 }
 
-/* Python function to clear the hit count of a breakpoint.  */
-static PyObject *
-bppy_clear_hit_count (PyObject *self, PyObject *newvalue)
+/* Python function to set the hit count of a breakpoint.  */
+static int
+bppy_set_hit_count (PyObject *self, PyObject *newvalue, void *closure)
 {
   breakpoint_object *self_bp = (breakpoint_object *) self;
-  long value;
 
-  BPPY_REQUIRE_VALID (self_bp);
+  BPPY_SET_REQUIRE_VALID (self_bp);
+
+  if (newvalue == NULL)
+    {
+      PyErr_SetString (PyExc_TypeError, "cannot delete `hit_count' attribute");
+      return -1;
+    }
+  else if (! PyInt_Check (newvalue) || PyInt_AsLong (newvalue) != 0)
+    {
+      PyErr_SetString (PyExc_AttributeError,
+		       "the value of `hit_count' must be zero");
+      return -1;
+    }
 
   self_bp->bp->hit_count = 0;
 
-  Py_RETURN_NONE;
+  return 0;
 }
 
 /* Python function to get the location of a breakpoint.  */
 static PyObject *
-bppy_get_location (PyObject *self, PyObject *args)
+bppy_get_location (PyObject *self, void *closure)
 {
   char *str;
 
@@ -218,7 +285,7 @@ bppy_get_location (PyObject *self, PyObject *args)
 
 /* Python function to get the condition expression of a breakpoint.  */
 static PyObject *
-bppy_get_condition (PyObject *self, PyObject *args)
+bppy_get_condition (PyObject *self, void *closure)
 {
   char *str;
   BPPY_REQUIRE_VALID ((breakpoint_object *) self);
@@ -229,9 +296,41 @@ bppy_get_condition (PyObject *self, PyObject *args)
   return PyString_Decode (str, strlen (str), host_charset (), NULL);
 }
 
+static int
+bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure)
+{
+  char *exp;
+  breakpoint_object *self_bp = (breakpoint_object *) self;
+  volatile struct gdb_exception except;
+
+  BPPY_SET_REQUIRE_VALID (self_bp);
+
+  if (newvalue == NULL)
+    {
+      PyErr_SetString (PyExc_TypeError, "cannot delete `condition' attribute");
+      return -1;
+    }
+  else if (newvalue == Py_None)
+    exp = "";
+  else
+    {
+      exp = python_string_to_host_string (newvalue);
+      if (exp == NULL)
+	return -1;
+    }
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      set_breakpoint_condition (self_bp->bp, exp, 0);
+    }
+  GDB_PY_SET_HANDLE_EXCEPTION (except);
+
+  return 0;
+}
+
 /* Python function to get the commands attached to a breakpoint.  */
 static PyObject *
-bppy_get_commands (PyObject *self, PyObject *args)
+bppy_get_commands (PyObject *self, void *closure)
 {
   breakpoint_object *self_bp = (breakpoint_object *) self;
   long length;
@@ -268,7 +367,7 @@ bppy_get_commands (PyObject *self, PyObject *args)
 
 /* Python function to get the breakpoint's number.  */
 static PyObject *
-bppy_get_number (PyObject *self, PyObject *args)
+bppy_get_number (PyObject *self, void *closure)
 {
   breakpoint_object *self_bp = (breakpoint_object *) self;
 
@@ -279,7 +378,7 @@ bppy_get_number (PyObject *self, PyObject *args)
 
 /* Python function to get the breakpoint's thread ID.  */
 static PyObject *
-bppy_get_thread (PyObject *self, PyObject *args)
+bppy_get_thread (PyObject *self, void *closure)
 {
   breakpoint_object *self_bp = (breakpoint_object *) self;
 
@@ -287,12 +386,13 @@ bppy_get_thread (PyObject *self, PyObject *args)
 
   if (self_bp->bp->thread == -1)
     Py_RETURN_NONE;
+
   return PyInt_FromLong (self_bp->bp->thread);
 }
 
 /* Python function to get the breakpoint's hit count.  */
 static PyObject *
-bppy_get_hit_count (PyObject *self, PyObject *args)
+bppy_get_hit_count (PyObject *self, void *closure)
 {
   breakpoint_object *self_bp = (breakpoint_object *) self;
 
@@ -303,7 +403,7 @@ bppy_get_hit_count (PyObject *self, PyObject *args)
 
 /* Python function to get the breakpoint's ignore count.  */
 static PyObject *
-bppy_get_ignore_count (PyObject *self, PyObject *args)
+bppy_get_ignore_count (PyObject *self, void *closure)
 {
   breakpoint_object *self_bp = (breakpoint_object *) self;
 
@@ -351,7 +451,7 @@ bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
 /* Static function to return a tuple holding all breakpoints.  */
 
 PyObject *
-gdbpy_get_breakpoints (PyObject *self, PyObject *args)
+gdbpy_breakpoints (PyObject *self, PyObject *args)
 {
   PyObject *result;
 
@@ -484,47 +584,40 @@ gdbpy_initialize_breakpoints (void)
 
 
 
+static PyGetSetDef breakpoint_object_getset[] = {
+  { "enabled", bppy_get_enabled, bppy_set_enabled,
+    "Boolean telling whether the breakpoint is enabled.", NULL },
+  { "silent", bppy_get_silent, bppy_set_silent,
+    "Boolean telling whether the breakpoint is silent.", NULL },
+  { "thread", bppy_get_thread, bppy_set_thread,
+    "Thread ID for the breakpoint.\n\
+If the value is a thread ID (integer), then this is a thread-specific breakpoint.\n\
+If the value is None, then this breakpoint not thread-specific.\n\
+No other type of value can be used.", NULL },
+  { "ignore_count", bppy_get_ignore_count, bppy_set_ignore_count,
+    "Number of times this breakpoint should be automatically continued.",
+    NULL },
+  { "number", bppy_get_number, NULL,
+    "Breakpoint's number assigned by GDB.", NULL },
+  { "hit_count", bppy_get_hit_count, bppy_set_hit_count,
+    "Number of times the breakpoint has been hit.\n\
+Can be set to zero to clear the count. No other value is valid\n\
+when setting this property.", NULL },
+  { "location", bppy_get_location, NULL,
+    "Location of the breakpoint, as specified by the user.", NULL},
+  { "condition", bppy_get_condition, bppy_set_condition,
+    "Condition of the breakpoint, as specified by the user,\
+or None if no condition set."},
+  { "commands", bppy_get_commands, NULL,
+    "Commands of the breakpoint, as specified by the user."},
+  { NULL }  /* Sentinel.  */
+};
+
 static PyMethodDef breakpoint_object_methods[] =
 {
   { "is_valid", bppy_is_valid, METH_NOARGS,
     "Return true if this breakpoint is valid, false if not." },
-  { "is_enabled", bppy_is_enabled, METH_NOARGS,
-    "Return true if this breakpoint is enabled, false if disabled." },
-  { "is_silent", bppy_is_silent, METH_NOARGS,
-    "Return true if this breakpoint is silent, false if verbose." },
-
-  { "set_enabled", bppy_set_enabled, METH_O,
-    "Enable or disable this breakpoint" },
-  { "set_silent", bppy_set_silent, METH_O,
-    "Make this breakpoint quiet or verbose" },
-  { "set_thread", bppy_set_thread, METH_O,
-    "Set the thread ID for this breakpoint.\n\
-If the argument is a thread ID, make this a thread-specific breakpoint.\n\
-If the argument is None, make this breakpoint not thread-specific.\n\
-Any other argument is an error." },
-  { "set_ignore_count", bppy_set_ignore_count, METH_O,
-    "Set the ignore count for this breakpoint" },
-  { "clear_hit_count", bppy_set_ignore_count, METH_NOARGS,
-    "Set the hit count for this breakpoint to zero" },
-
-  { "get_location", bppy_get_location, METH_NOARGS,
-    "Return the location of this breakpoint, as specified by the user"},
-  { "get_condition", bppy_get_condition, METH_NOARGS,
-    "Return the condition of this breakpoint, as specified by the user.\n\
-Returns None if no condition set."},
-  { "get_commands", bppy_get_commands, METH_NOARGS,
-    "Return the commands of this breakpoint, as specified by the user"},
-  { "get_number", bppy_get_number, METH_NOARGS,
-    "Return this breakpoint's number." },
-  { "get_thread", bppy_get_thread, METH_NOARGS,
-    "For a thread-specific breakpoint, return the thread ID.\n\
-Otherwise, return None." },
-  { "get_hit_count", bppy_get_hit_count, METH_NOARGS,
-    "Return the number of times this breakpoint has been hit." },
-  { "get_ignore_count", bppy_get_ignore_count, METH_NOARGS,
-    "Return the number of times this breakpoint should be automatically continued." },
-
-  { 0 }
+  { NULL } /* Sentinel.  */
 };
 
 static PyTypeObject breakpoint_object_type =
@@ -557,5 +650,7 @@ static PyTypeObject breakpoint_object_type =
   0,				  /* tp_weaklistoffset */
   0,				  /* tp_iter */
   0,				  /* tp_iternext */
-  breakpoint_object_methods	  /* tp_methods */
+  breakpoint_object_methods,	  /* tp_methods */
+  0,				  /* tp_members */
+  breakpoint_object_getset	  /* tp_getset */
 };
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 6e31367..e35d9cb 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -70,7 +70,7 @@ extern PyTypeObject value_object_type;
 extern PyTypeObject symbol_object_type;
 
 PyObject *gdbpy_history (PyObject *self, PyObject *args);
-PyObject *gdbpy_get_breakpoints (PyObject *, PyObject *);
+PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
 PyObject *gdbpy_frames (PyObject *, PyObject *);
 PyObject *gdbpy_current_frame (PyObject *, PyObject *);
 PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
@@ -128,6 +128,19 @@ PyObject *gdbpy_parameter_value (enum var_types, void *);
 			     "%s", Exception.message);			\
     } while (0)
 
+/* Use this after a TRY_EXCEPT to throw the appropriate Python
+   exception.  This macro is for use inside setter functions.  */
+#define GDB_PY_SET_HANDLE_EXCEPTION(Exception)				\
+    do {								\
+      if (Exception.reason < 0)						\
+        {								\
+	  PyErr_Format (Exception.reason == RETURN_QUIT			\
+			? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \
+			"%s", Exception.message);			\
+	  return -1;							\
+	}								\
+    } while (0)
+
 
 void gdbpy_print_stack (void);
 
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 1432e5e..1eaee78 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1461,7 +1461,7 @@ static PyMethodDef GdbMethods[] =
   { "parameter", gdbpy_parameter, METH_VARARGS,
     "Return a gdb parameter's value" },
 
-  { "get_breakpoints", gdbpy_get_breakpoints, METH_NOARGS,
+  { "breakpoints", gdbpy_breakpoints, METH_NOARGS,
     "Return a tuple of all breakpoint objects" },
 
   { "default_visualizer", gdbpy_default_visualizer, METH_VARARGS,



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