| /* User Interface Events. |
| |
| Copyright (C) 1999, 2001, 2002, 2004, 2005 Free Software Foundation, |
| Inc. |
| |
| Contributed by Cygnus Solutions. |
| |
| This file is part of GDB. |
| |
| 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 2 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, write to the Free Software |
| Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| Boston, MA 02110-1301, USA. */ |
| |
| /* Work in progress */ |
| |
| /* This file was created with the aid of ``gdb-events.sh''. |
| |
| The bourn shell script ``gdb-events.sh'' creates the files |
| ``new-gdb-events.c'' and ``new-gdb-events.h and then compares |
| them against the existing ``gdb-events.[hc]''. Any differences |
| found being reported. |
| |
| If editing this file, please also run gdb-events.sh and merge any |
| changes into that script. Conversely, when making sweeping changes |
| to this file, modifying gdb-events.sh and using its output may |
| prove easier. */ |
| |
| |
| #include "defs.h" |
| #include "gdb-events.h" |
| #include "gdbcmd.h" |
| |
| static struct gdb_events null_event_hooks; |
| static struct gdb_events queue_event_hooks; |
| static struct gdb_events *current_event_hooks = &null_event_hooks; |
| |
| int gdb_events_debug; |
| static void |
| show_gdb_events_debug (struct ui_file *file, int from_tty, |
| struct cmd_list_element *c, const char *value) |
| { |
| fprintf_filtered (file, _("Event debugging is %s.\n"), value); |
| } |
| |
| |
| void |
| breakpoint_create_event (int b) |
| { |
| if (gdb_events_debug) |
| fprintf_unfiltered (gdb_stdlog, "breakpoint_create_event\n"); |
| if (!current_event_hooks->breakpoint_create) |
| return; |
| current_event_hooks->breakpoint_create (b); |
| } |
| |
| void |
| breakpoint_delete_event (int b) |
| { |
| if (gdb_events_debug) |
| fprintf_unfiltered (gdb_stdlog, "breakpoint_delete_event\n"); |
| if (!current_event_hooks->breakpoint_delete) |
| return; |
| current_event_hooks->breakpoint_delete (b); |
| } |
| |
| void |
| breakpoint_modify_event (int b) |
| { |
| if (gdb_events_debug) |
| fprintf_unfiltered (gdb_stdlog, "breakpoint_modify_event\n"); |
| if (!current_event_hooks->breakpoint_modify) |
| return; |
| current_event_hooks->breakpoint_modify (b); |
| } |
| |
| void |
| tracepoint_create_event (int number) |
| { |
| if (gdb_events_debug) |
| fprintf_unfiltered (gdb_stdlog, "tracepoint_create_event\n"); |
| if (!current_event_hooks->tracepoint_create) |
| return; |
| current_event_hooks->tracepoint_create (number); |
| } |
| |
| void |
| tracepoint_delete_event (int number) |
| { |
| if (gdb_events_debug) |
| fprintf_unfiltered (gdb_stdlog, "tracepoint_delete_event\n"); |
| if (!current_event_hooks->tracepoint_delete) |
| return; |
| current_event_hooks->tracepoint_delete (number); |
| } |
| |
| void |
| tracepoint_modify_event (int number) |
| { |
| if (gdb_events_debug) |
| fprintf_unfiltered (gdb_stdlog, "tracepoint_modify_event\n"); |
| if (!current_event_hooks->tracepoint_modify) |
| return; |
| current_event_hooks->tracepoint_modify (number); |
| } |
| |
| void |
| architecture_changed_event (void) |
| { |
| if (gdb_events_debug) |
| fprintf_unfiltered (gdb_stdlog, "architecture_changed_event\n"); |
| if (!current_event_hooks->architecture_changed) |
| return; |
| current_event_hooks->architecture_changed (); |
| } |
| |
| struct gdb_events * |
| deprecated_set_gdb_event_hooks (struct gdb_events *vector) |
| { |
| struct gdb_events *old_events = current_event_hooks; |
| if (vector == NULL) |
| current_event_hooks = &queue_event_hooks; |
| else |
| current_event_hooks = vector; |
| return old_events; |
| } |
| |
| void |
| clear_gdb_event_hooks (void) |
| { |
| deprecated_set_gdb_event_hooks (&null_event_hooks); |
| } |
| |
| enum gdb_event |
| { |
| breakpoint_create, |
| breakpoint_delete, |
| breakpoint_modify, |
| tracepoint_create, |
| tracepoint_delete, |
| tracepoint_modify, |
| architecture_changed, |
| nr_gdb_events |
| }; |
| |
| struct breakpoint_create |
| { |
| int b; |
| }; |
| |
| struct breakpoint_delete |
| { |
| int b; |
| }; |
| |
| struct breakpoint_modify |
| { |
| int b; |
| }; |
| |
| struct tracepoint_create |
| { |
| int number; |
| }; |
| |
| struct tracepoint_delete |
| { |
| int number; |
| }; |
| |
| struct tracepoint_modify |
| { |
| int number; |
| }; |
| |
| struct event |
| { |
| enum gdb_event type; |
| struct event *next; |
| union |
| { |
| struct breakpoint_create breakpoint_create; |
| struct breakpoint_delete breakpoint_delete; |
| struct breakpoint_modify breakpoint_modify; |
| struct tracepoint_create tracepoint_create; |
| struct tracepoint_delete tracepoint_delete; |
| struct tracepoint_modify tracepoint_modify; |
| } |
| data; |
| }; |
| struct event *pending_events; |
| struct event *delivering_events; |
| |
| static void |
| append (struct event *new_event) |
| { |
| struct event **event = &pending_events; |
| while ((*event) != NULL) |
| event = &((*event)->next); |
| (*event) = new_event; |
| (*event)->next = NULL; |
| } |
| |
| static void |
| queue_breakpoint_create (int b) |
| { |
| struct event *event = XMALLOC (struct event); |
| event->type = breakpoint_create; |
| event->data.breakpoint_create.b = b; |
| append (event); |
| } |
| |
| static void |
| queue_breakpoint_delete (int b) |
| { |
| struct event *event = XMALLOC (struct event); |
| event->type = breakpoint_delete; |
| event->data.breakpoint_delete.b = b; |
| append (event); |
| } |
| |
| static void |
| queue_breakpoint_modify (int b) |
| { |
| struct event *event = XMALLOC (struct event); |
| event->type = breakpoint_modify; |
| event->data.breakpoint_modify.b = b; |
| append (event); |
| } |
| |
| static void |
| queue_tracepoint_create (int number) |
| { |
| struct event *event = XMALLOC (struct event); |
| event->type = tracepoint_create; |
| event->data.tracepoint_create.number = number; |
| append (event); |
| } |
| |
| static void |
| queue_tracepoint_delete (int number) |
| { |
| struct event *event = XMALLOC (struct event); |
| event->type = tracepoint_delete; |
| event->data.tracepoint_delete.number = number; |
| append (event); |
| } |
| |
| static void |
| queue_tracepoint_modify (int number) |
| { |
| struct event *event = XMALLOC (struct event); |
| event->type = tracepoint_modify; |
| event->data.tracepoint_modify.number = number; |
| append (event); |
| } |
| |
| static void |
| queue_architecture_changed (void) |
| { |
| struct event *event = XMALLOC (struct event); |
| event->type = architecture_changed; |
| append (event); |
| } |
| |
| void |
| gdb_events_deliver (struct gdb_events *vector) |
| { |
| /* Just zap any events left around from last time. */ |
| while (delivering_events != NULL) |
| { |
| struct event *event = delivering_events; |
| delivering_events = event->next; |
| xfree (event); |
| } |
| /* Process any pending events. Because one of the deliveries could |
| bail out we move everything off of the pending queue onto an |
| in-progress queue where it can, later, be cleaned up if |
| necessary. */ |
| delivering_events = pending_events; |
| pending_events = NULL; |
| while (delivering_events != NULL) |
| { |
| struct event *event = delivering_events; |
| switch (event->type) |
| { |
| case breakpoint_create: |
| vector->breakpoint_create |
| (event->data.breakpoint_create.b); |
| break; |
| case breakpoint_delete: |
| vector->breakpoint_delete |
| (event->data.breakpoint_delete.b); |
| break; |
| case breakpoint_modify: |
| vector->breakpoint_modify |
| (event->data.breakpoint_modify.b); |
| break; |
| case tracepoint_create: |
| vector->tracepoint_create |
| (event->data.tracepoint_create.number); |
| break; |
| case tracepoint_delete: |
| vector->tracepoint_delete |
| (event->data.tracepoint_delete.number); |
| break; |
| case tracepoint_modify: |
| vector->tracepoint_modify |
| (event->data.tracepoint_modify.number); |
| break; |
| case architecture_changed: |
| vector->architecture_changed (); |
| break; |
| } |
| delivering_events = event->next; |
| xfree (event); |
| } |
| } |
| |
| void _initialize_gdb_events (void); |
| void |
| _initialize_gdb_events (void) |
| { |
| struct cmd_list_element *c; |
| queue_event_hooks.breakpoint_create = queue_breakpoint_create; |
| queue_event_hooks.breakpoint_delete = queue_breakpoint_delete; |
| queue_event_hooks.breakpoint_modify = queue_breakpoint_modify; |
| queue_event_hooks.tracepoint_create = queue_tracepoint_create; |
| queue_event_hooks.tracepoint_delete = queue_tracepoint_delete; |
| queue_event_hooks.tracepoint_modify = queue_tracepoint_modify; |
| queue_event_hooks.architecture_changed = queue_architecture_changed; |
| |
| add_setshow_zinteger_cmd ("event", class_maintenance, |
| &gdb_events_debug, _("\ |
| Set event debugging."), _("\ |
| Show event debugging."), _("\ |
| When non-zero, event/notify debugging is enabled."), |
| NULL, |
| show_gdb_events_debug, |
| &setdebuglist, &showdebuglist); |
| } |