This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH 3/4] observer on create/modify/delete itsets
Hi,
This patch is about adding MI notifications to creating, modifying and
deleting named itsets in console. Originally, it is not allowed to
'modify' a named itset, however, when taking 'predefined itset from
remote target' into account, an itset may be modified time and time
again as it is changing in remote target.
gdb/doc:
2012-08-30 Yao Qi <yao@codesourcery.com>
* gdb.texinfo (GDB/MI Async Records): Document new MI notifications
'=itset-created' '=itset-modified' and '=itset-deleted'.
* observer.texi (GDB Observers): Add new observers
'itset_created' 'itset_deleted' and 'itset_modified'.
gdb:
2012-08-30 Yao Qi <yao@codesourcery.com>
* itset.c: Include 'observer.h'.
(named_itset_create): Call observer_notify_itset_modified
and observer_notify_itset_created respectively.
(undefset_command): Call observer_notify_itset_deleted.
* mi/mi-interp.c : Declare mi_itset_created, mi_itset_deleted
and mi_itset_modified.
(mi_interpreter_init): Call observer_attach_itset_created
observer_attach_itset_deleted and
observer_attach_itset_modified.
(mi_itset_created, mi_itset_deleted, mi_itset_modified): New.
gdb/testsuite:
2012-08-30 Yao Qi <yao@codesourcery.com>
*gdb.mi/mi-itset-changed.exp: New.
---
gdb/doc/gdb.texinfo | 10 ++++
gdb/doc/observer.texi | 12 +++++
gdb/itset.c | 15 +++++-
gdb/mi/mi-interp.c | 76 +++++++++++++++++++++++++++++
gdb/testsuite/gdb.mi/mi-itset-changed.exp | 50 +++++++++++++++++++
5 files changed, 161 insertions(+), 2 deletions(-)
create mode 100644 gdb/testsuite/gdb.mi/mi-itset-changed.exp
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index c9228d3..7d2a470 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -27705,6 +27705,16 @@ thread group in whose context the library was unloaded. If the field is
absent, it means the library was unloaded in the context of all present
thread groups.
+@item =itset-created,name=@var{name},spec=@var{spec}
+@item =itset-modified,name=@var{name},spec=@var{spec}
+Reports that a named itset is created or modified respecitvely. The name
+of the itset is @var{name}, and the specificaiton of the itset is
+@var{spec}.
+@item =itset-deleted,name=@var{name}
+Reports that the named itset whose name is @var{name} is deleted.
+@item =itset-deleted
+Reports that all named itsets are deleted.
+
@item =breakpoint-created,bkpt=@{...@}
@itemx =breakpoint-modified,bkpt=@{...@}
@itemx =breakpoint-deleted,id=@var{number}
diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi
index c81e137..9da915d 100644
--- a/gdb/doc/observer.texi
+++ b/gdb/doc/observer.texi
@@ -235,7 +235,19 @@ The parameter of some @code{set} commands in console are changed. This
method is called after a command @code{set @var{param} @var{value}}.
@var{param} is the parameter of @code{set} command, and @var{value}
is the value of changed parameter.
+@end deftypefun
+
+@deftypefun void itset_created (const char *@var{name}, const char *@var{spec})
+called after a named itset @var{name} is created, and its specification is @var{spec}.
+@end deftypefun
+
+@deftypefun void itset_deleted (const char *@var{name})
+called after a named itset @var{name} is deleted. If @var{name} is equal to
+@code{NULL}, all named itsets are deleted.
+@end deftypefun
+@deftypefun void itset_modified (const char *@var{name}, const char *@var{spec})
+called after a named itset @var{name} is modified, and its specification is @var{spec}.
@end deftypefun
@deftypefun void test_notification (int @var{somearg})
diff --git a/gdb/itset.c b/gdb/itset.c
index d3f79f7..573f332 100644
--- a/gdb/itset.c
+++ b/gdb/itset.c
@@ -18,6 +18,7 @@
#include "defs.h"
#include "itset.h"
+#include "observer.h"
#include "vec.h"
#include "bfd.h"
#include "inferior.h"
@@ -2047,8 +2048,15 @@ named_itset_create (char *set_name, char *spec)
itset_free (itset);
discard_cleanups (old_chain);
- if (!found)
- add_to_named_itset_chain (named_itset);
+ if (found)
+ observer_notify_itset_modified (itset_name (named_itset->set),
+ itset_spec (named_itset->set));
+ else
+ {
+ add_to_named_itset_chain (named_itset);
+ observer_notify_itset_created (itset_name (named_itset->set),
+ itset_spec (named_itset->set));
+ }
}
static void
@@ -2106,6 +2114,7 @@ undefset_command (char *arg, int from_tty)
it_link = &it->next;
it = *it_link;
}
+ observer_notify_itset_deleted (NULL);
return;
}
@@ -2120,6 +2129,8 @@ undefset_command (char *arg, int from_tty)
error (_("cannot delete builtin I/T set"));
*it_link = it->next;
+ observer_notify_itset_deleted (itset_name (it->set));
+
free_named_itset (it);
found = 1;
break;
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index 94df818..a5e172b 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -58,6 +58,9 @@ static void mi_insert_notify_hooks (void);
static void mi_remove_notify_hooks (void);
static void mi_on_normal_stop (struct bpstats *bs, int print_frame);
+static void mi_itset_created (const char *name, const char *spec);
+static void mi_itset_deleted (const char *name);
+static void mi_itset_modified (const char *name, const char *spec);
static void mi_new_thread (struct thread_info *t);
static void mi_thread_exit (struct thread_info *t, int silent);
static void mi_inferior_added (struct inferior *inf);
@@ -121,6 +124,9 @@ mi_interpreter_init (struct interp *interp, int top_level)
observer_attach_inferior_appeared (mi_inferior_appeared);
observer_attach_inferior_exit (mi_inferior_exit);
observer_attach_inferior_removed (mi_inferior_removed);
+ observer_attach_itset_created (mi_itset_created);
+ observer_attach_itset_deleted (mi_itset_deleted);
+ observer_attach_itset_modified (mi_itset_modified);
observer_attach_normal_stop (mi_on_normal_stop);
observer_attach_target_resumed (mi_on_resume);
observer_attach_solib_loaded (mi_solib_loaded);
@@ -599,6 +605,76 @@ mi_breakpoint_modified (struct breakpoint *b)
gdb_flush (mi->event_channel);
}
+/* Emit notification about the created named itset. */
+
+static void
+mi_itset_created (const char *name, const char *spec)
+{
+ struct mi_interp *mi = top_level_interpreter_data ();
+ struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
+
+ target_terminal_ours ();
+
+ fprintf_unfiltered (mi->event_channel,
+ "itset-created");
+
+ ui_out_redirect (mi_uiout, mi->event_channel);
+
+ ui_out_field_string (mi_uiout, "name", name);
+ ui_out_field_string (mi_uiout, "spec", spec);
+
+ ui_out_redirect (mi_uiout, NULL);
+
+ gdb_flush (mi->event_channel);
+}
+
+/* Emit notification about deleted named itset. NAME is the name of deleted
+ itset. If NAME is NULL, it means delete all named itsets. */
+
+static void
+mi_itset_deleted (const char *name)
+{
+ struct mi_interp *mi = top_level_interpreter_data ();
+ struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
+
+ target_terminal_ours ();
+
+ fprintf_unfiltered (mi->event_channel,
+ "itset-deleted");
+
+ ui_out_redirect (mi_uiout, mi->event_channel);
+
+ if (name != NULL)
+ ui_out_field_string (mi_uiout, "name", name);
+
+ ui_out_redirect (mi_uiout, NULL);
+
+ gdb_flush (mi->event_channel);
+}
+
+/* Emit notification about the modified named itset. */
+
+static void
+mi_itset_modified (const char *name, const char *spec)
+{
+ struct mi_interp *mi = top_level_interpreter_data ();
+ struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
+
+ target_terminal_ours ();
+
+ fprintf_unfiltered (mi->event_channel,
+ "itset-modified");
+
+ ui_out_redirect (mi_uiout, mi->event_channel);
+
+ ui_out_field_string (mi_uiout, "name", name);
+ ui_out_field_string (mi_uiout, "spec", spec);
+
+ ui_out_redirect (mi_uiout, NULL);
+
+ gdb_flush (mi->event_channel);
+}
+
static int
mi_output_running_pid (struct thread_info *info, void *arg)
{
diff --git a/gdb/testsuite/gdb.mi/mi-itset-changed.exp b/gdb/testsuite/gdb.mi/mi-itset-changed.exp
new file mode 100644
index 0000000..4767547
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-itset-changed.exp
@@ -0,0 +1,50 @@
+# Copyright 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+standard_testfile basics.c
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested mi-itset-changed.exp
+ return -1
+}
+
+if [mi_gdb_start] {
+ return
+}
+mi_run_to_main
+
+mi_gdb_test "defset itset1 !i1.t1-2,i2\.t3-4" \
+ ".*=itset-created,name=\"itset1\",spec=\"!i1.t1-2,i2.t3-4\".*\\^done" \
+ "defset itset1"
+mi_gdb_test "defset itset2 c1-2" \
+ ".*=itset-created,name=\"itset2\",spec=\"c1-2\".*\\^done" \
+ "defset itset2"
+
+mi_gdb_test "defset itset2 c1" \
+ ".*=itset-modified,name=\"itset2\",spec=\"c1\".*\\^done" \
+ "defset itset2 again"
+
+mi_gdb_test "undefset itset2" ".*=itset-deleted,name=\"itset2\".*\\^done" \
+ "undefset itset2"
+
+mi_gdb_test "undefset -all" ".*=itset-deleted.*\\^done" \
+ "undefset all"
+
+mi_gdb_exit
+
+return 0
--
1.7.7.6