1#!/bin/sh 2 3# User Interface Events. 4# Copyright 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc. 5# 6# Contributed by Cygnus Solutions. 7# 8# This file is part of GDB. 9# 10# This program is free software; you can redistribute it and/or modify 11# it under the terms of the GNU General Public License as published by 12# the Free Software Foundation; either version 2 of the License, or 13# (at your option) any later version. 14# 15# This program is distributed in the hope that it will be useful, 16# but WITHOUT ANY WARRANTY; without even the implied warranty of 17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18# GNU General Public License for more details. 19# 20# You should have received a copy of the GNU General Public License 21# along with this program; if not, write to the Free Software 22# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 24# 25# What happens next: 26# 27 28# The gdb-events.h/gdb-events.c files this script generates are commited 29# and published. 30 31# Any UI module that is installing events is changed so that the 32# events are installed using the ``set_gdb_events()'' and 33# ``gdb_event_hooks()'' interfaces. There could prove to be an issue 34# here with respect to annotate. We might need to accomodate a hook 35# stack that allows several ui blocks to install their own events. 36 37# Each of the variable events (as currently generated) is converted 38# to either a straight function call or a function call with a 39# predicate. 40 41 42IFS=: 43 44read="class returntype function formal actual attrib" 45 46function_list () 47{ 48 # category: 49 # # -> disable 50 # * -> compatibility - pointer variable that is initialized 51 # by set_gdb_events(). 52 # ? -> Predicate and function proper. 53 # f -> always call (must have a void returntype) 54 # return-type 55 # name 56 # formal argument list 57 # actual argument list 58 # attributes 59 # description 60 cat <<EOF | 61f:void:breakpoint_create:int b:b 62f:void:breakpoint_delete:int b:b 63f:void:breakpoint_modify:int b:b 64f:void:tracepoint_create:int number:number 65f:void:tracepoint_delete:int number:number 66f:void:tracepoint_modify:int number:number 67f:void:architecture_changed:void 68f:void:target_changed:void 69f:void:selected_frame_level_changed:int level:level 70f:void:selected_thread_changed:int thread_num:thread_num 71#*:void:annotate_starting_hook:void 72#*:void:annotate_stopped_hook:void 73#*:void:annotate_signalled_hook:void 74#*:void:annotate_signal_hook:void 75#*:void:annotate_exited_hook:void 76##*:void:print_register_hook:int 77##*:CORE_ADDR:find_toc_address_hook:CORE_ADDR 78##*:void:sparc_print_register_hook:int regno:regno 79#*:void:target_resume_hook:void 80#*:void:target_wait_loop_hook:void 81#*:void:init_gdb_hook:char *argv0:argv0 82#*:void:command_loop_hook:void 83#*:void:fputs_unfiltered_hook:const char *linebuff,struct ui_file *stream:linebuff, stream 84#*:void:print_frame_info_listing_hook:struct symtab *s, int line, int stopline, int noerror:s, line, stopline, noerror 85#*:int:query_hook:const char *query, va_list args:query, args 86#*:void:warning_hook:const char *string, va_list args:string, args 87#*:void:target_output_hook:char *b:b 88#*:void:interactive_hook:void 89#*:void:registers_changed_hook:void 90#*:void:readline_begin_hook:char *format, ...:format 91#*:char *:readline_hook:char *prompt:prompt 92#*:void:readline_end_hook:void 93#*:int:target_wait_hook:int pid, struct target_waitstatus *status:pid, status 94#*:void:call_command_hook:struct cmd_list_element *c, char *cmd, int from_tty:c, cmd, from_tty 95#*:NORETURN void:error_hook:void:: ATTR_NORETURN 96#*:void:error_begin_hook:void 97##*:int:target_architecture_hook:const struct bfd_arch_info * 98#*:void:exec_file_display_hook:char *filename:filename 99#*:void:file_changed_hook:char *filename:filename 100##*:void:specify_exec_file_hook: 101#*:int:gdb_load_progress_hook:char *section, unsigned long num:section, num 102#*:void:pre_add_symbol_hook:char *name:name 103#*:void:post_add_symbol_hook:void 104#*:void:selected_frame_level_changed_hook:int level:level 105#*:int:gdb_loop_hook:int signo:signo 106##*:void:solib_create_inferior_hook:void 107##*:void:xcoff_relocate_symtab_hook:unsigned int 108EOF 109 grep -v '^#' 110} 111 112copyright () 113{ 114 cat <<EOF 115/* User Interface Events. 116 117 Copyright 1999, 2001, 2002 Free Software Foundation, Inc. 118 119 Contributed by Cygnus Solutions. 120 121 This file is part of GDB. 122 123 This program is free software; you can redistribute it and/or modify 124 it under the terms of the GNU General Public License as published by 125 the Free Software Foundation; either version 2 of the License, or 126 (at your option) any later version. 127 128 This program is distributed in the hope that it will be useful, 129 but WITHOUT ANY WARRANTY; without even the implied warranty of 130 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 131 GNU General Public License for more details. 132 133 You should have received a copy of the GNU General Public License 134 along with this program; if not, write to the Free Software 135 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 136 137/* Work in progress */ 138 139/* This file was created with the aid of \`\`gdb-events.sh''. 140 141 The bourn shell script \`\`gdb-events.sh'' creates the files 142 \`\`new-gdb-events.c'' and \`\`new-gdb-events.h and then compares 143 them against the existing \`\`gdb-events.[hc]''. Any differences 144 found being reported. 145 146 If editing this file, please also run gdb-events.sh and merge any 147 changes into that script. Conversely, when making sweeping changes 148 to this file, modifying gdb-events.sh and using its output may 149 prove easier. */ 150 151EOF 152} 153 154# 155# The .h file 156# 157 158exec > new-gdb-events.h 159copyright 160cat <<EOF 161 162#ifndef GDB_EVENTS_H 163#define GDB_EVENTS_H 164 165#ifndef WITH_GDB_EVENTS 166#define WITH_GDB_EVENTS 1 167#endif 168EOF 169 170# pointer declarations 171echo "" 172echo "" 173cat <<EOF 174/* COMPAT: pointer variables for old, unconverted events. 175 A call to set_gdb_events() will automatically update these. */ 176EOF 177echo "" 178function_list | while eval read $read 179do 180 case "${class}" in 181 "*" ) 182 echo "extern ${returntype} (*${function}_event) (${formal})${attrib};" 183 ;; 184 esac 185done 186 187# function typedef's 188echo "" 189echo "" 190cat <<EOF 191/* Type definition of all hook functions. 192 Recommended pratice is to first declare each hook function using 193 the below ftype and then define it. */ 194EOF 195echo "" 196function_list | while eval read $read 197do 198 echo "typedef ${returntype} (gdb_events_${function}_ftype) (${formal});" 199done 200 201# gdb_events object 202echo "" 203echo "" 204cat <<EOF 205/* gdb-events: object. */ 206EOF 207echo "" 208echo "struct gdb_events" 209echo " {" 210function_list | while eval read $read 211do 212 echo " gdb_events_${function}_ftype *${function}${attrib};" 213done 214echo " };" 215 216# function declarations 217echo "" 218echo "" 219cat <<EOF 220/* Interface into events functions. 221 Where a *_p() predicate is present, it must be called before 222 calling the hook proper. */ 223EOF 224function_list | while eval read $read 225do 226 case "${class}" in 227 "*" ) continue ;; 228 "?" ) 229 echo "extern int ${function}_p (void);" 230 echo "extern ${returntype} ${function}_event (${formal})${attrib};" 231 ;; 232 "f" ) 233 echo "extern ${returntype} ${function}_event (${formal})${attrib};" 234 ;; 235 esac 236done 237 238# function macros 239echo "" 240echo "" 241cat <<EOF 242/* When GDB_EVENTS are not being used, completely disable them. */ 243EOF 244echo "" 245echo "#if !WITH_GDB_EVENTS" 246function_list | while eval read $read 247do 248 case "${class}" in 249 "*" ) continue ;; 250 "?" ) 251 echo "#define ${function}_event_p() 0" 252 echo "#define ${function}_event(${actual}) 0" 253 ;; 254 "f" ) 255 echo "#define ${function}_event(${actual}) 0" 256 ;; 257 esac 258done 259echo "#endif" 260 261# our set function 262cat <<EOF 263 264/* Install custom gdb-events hooks. */ 265extern struct gdb_events *set_gdb_event_hooks (struct gdb_events *vector); 266 267/* Deliver any pending events. */ 268extern void gdb_events_deliver (struct gdb_events *vector); 269 270/* Clear event handlers */ 271extern void clear_gdb_event_hooks (void); 272 273#if !WITH_GDB_EVENTS 274#define set_gdb_events(x) 0 275#define set_gdb_event_hooks(x) 0 276#define gdb_events_deliver(x) 0 277#endif 278EOF 279 280# close it off 281echo "" 282echo "#endif" 283exec 1>&2 284#../move-if-change new-gdb-events.h gdb-events.h 285if test -r gdb-events.h 286then 287 diff -c gdb-events.h new-gdb-events.h 288 if [ $? = 1 ] 289 then 290 echo "gdb-events.h changed? cp new-gdb-events.h gdb-events.h" 1>&2 291 fi 292else 293 echo "File missing? mv new-gdb-events.h gdb-events.h" 1>&2 294fi 295 296 297 298# 299# C file 300# 301 302exec > new-gdb-events.c 303copyright 304cat <<EOF 305 306#include "defs.h" 307#include "gdb-events.h" 308#include "gdbcmd.h" 309 310#if WITH_GDB_EVENTS 311static struct gdb_events null_event_hooks; 312static struct gdb_events queue_event_hooks; 313static struct gdb_events *current_event_hooks = &null_event_hooks; 314#endif 315 316int gdb_events_debug; 317EOF 318 319# global pointer variables - always have this 320#echo "" 321#function_list | while eval read $read 322#do 323# case "${class}" in 324# "*" ) 325# echo "${returntype} (*${function}_event) (${formal})${attrib} = 0;" 326# ;; 327# esac 328#done 329 330# function bodies 331echo "" 332echo "#if WITH_GDB_EVENTS" 333function_list | while eval read $read 334do 335 case "${class}" in 336 "*" ) continue ;; 337 "?" ) 338cat <<EOF 339 340int 341${function}_event_p (${formal}) 342{ 343 return current_event_hooks->${function}; 344} 345 346${returntype} 347${function}_event (${formal}) 348{ 349 return current_events->${function} (${actual}); 350} 351EOF 352 ;; 353 "f" ) 354cat <<EOF 355 356void 357${function}_event (${formal}) 358{ 359 if (gdb_events_debug) 360 fprintf_unfiltered (gdb_stdlog, "${function}_event\n"); 361 if (!current_event_hooks->${function}) 362 return; 363 current_event_hooks->${function} (${actual}); 364} 365EOF 366 ;; 367 esac 368done 369echo "" 370echo "#endif" 371 372# Set hooks function 373echo "" 374cat <<EOF 375#if WITH_GDB_EVENTS 376struct gdb_events * 377set_gdb_event_hooks (struct gdb_events *vector) 378{ 379 struct gdb_events *old_events = current_event_hooks; 380 if (vector == NULL) 381 current_event_hooks = &queue_event_hooks; 382 else 383 current_event_hooks = vector; 384 return old_events; 385EOF 386function_list | while eval read $read 387do 388 case "${class}" in 389 "*" ) 390 echo " ${function}_event = hooks->${function};" 391 ;; 392 esac 393done 394cat <<EOF 395} 396#endif 397EOF 398 399# Clear hooks function 400echo "" 401cat <<EOF 402#if WITH_GDB_EVENTS 403void 404clear_gdb_event_hooks (void) 405{ 406 set_gdb_event_hooks (&null_event_hooks); 407} 408#endif 409EOF 410 411# event type 412echo "" 413cat <<EOF 414enum gdb_event 415{ 416EOF 417function_list | while eval read $read 418do 419 case "${class}" in 420 "f" ) 421 echo " ${function}," 422 ;; 423 esac 424done 425cat <<EOF 426 nr_gdb_events 427}; 428EOF 429 430# event data 431echo "" 432function_list | while eval read $read 433do 434 case "${class}" in 435 "f" ) 436 if test ${actual} 437 then 438 echo "struct ${function}" 439 echo " {" 440 echo " `echo ${formal} | tr '[,]' '[;]'`;" 441 echo " };" 442 echo "" 443 fi 444 ;; 445 esac 446done 447 448# event queue 449cat <<EOF 450struct event 451 { 452 enum gdb_event type; 453 struct event *next; 454 union 455 { 456EOF 457function_list | while eval read $read 458do 459 case "${class}" in 460 "f" ) 461 if test ${actual} 462 then 463 echo " struct ${function} ${function};" 464 fi 465 ;; 466 esac 467done 468cat <<EOF 469 } 470 data; 471 }; 472struct event *pending_events; 473struct event *delivering_events; 474EOF 475 476# append 477echo "" 478cat <<EOF 479static void 480append (struct event *new_event) 481{ 482 struct event **event = &pending_events; 483 while ((*event) != NULL) 484 event = &((*event)->next); 485 (*event) = new_event; 486 (*event)->next = NULL; 487} 488EOF 489 490# schedule a given event 491function_list | while eval read $read 492do 493 case "${class}" in 494 "f" ) 495 echo "" 496 echo "static void" 497 echo "queue_${function} (${formal})" 498 echo "{" 499 echo " struct event *event = XMALLOC (struct event);" 500 echo " event->type = ${function};" 501 for arg in `echo ${actual} | tr '[,]' '[:]' | tr -d '[ ]'`; do 502 echo " event->data.${function}.${arg} = ${arg};" 503 done 504 echo " append (event);" 505 echo "}" 506 ;; 507 esac 508done 509 510# deliver 511echo "" 512cat <<EOF 513void 514gdb_events_deliver (struct gdb_events *vector) 515{ 516 /* Just zap any events left around from last time. */ 517 while (delivering_events != NULL) 518 { 519 struct event *event = delivering_events; 520 delivering_events = event->next; 521 xfree (event); 522 } 523 /* Process any pending events. Because one of the deliveries could 524 bail out we move everything off of the pending queue onto an 525 in-progress queue where it can, later, be cleaned up if 526 necessary. */ 527 delivering_events = pending_events; 528 pending_events = NULL; 529 while (delivering_events != NULL) 530 { 531 struct event *event = delivering_events; 532 switch (event->type) 533 { 534EOF 535function_list | while eval read $read 536do 537 case "${class}" in 538 "f" ) 539 echo " case ${function}:" 540 if test ${actual} 541 then 542 echo " vector->${function}" 543 sep=" (" 544 ass="" 545 for arg in `echo ${actual} | tr '[,]' '[:]' | tr -d '[ ]'`; do 546 ass="${ass}${sep}event->data.${function}.${arg}" 547 sep=", 548 " 549 done 550 echo "${ass});" 551 else 552 echo " vector->${function} ();" 553 fi 554 echo " break;" 555 ;; 556 esac 557done 558cat <<EOF 559 } 560 delivering_events = event->next; 561 xfree (event); 562 } 563} 564EOF 565 566# Finally the initialization 567echo "" 568cat <<EOF 569void _initialize_gdb_events (void); 570void 571_initialize_gdb_events (void) 572{ 573 struct cmd_list_element *c; 574#if WITH_GDB_EVENTS 575EOF 576function_list | while eval read $read 577do 578 case "${class}" in 579 "f" ) 580 echo " queue_event_hooks.${function} = queue_${function};" 581 ;; 582 esac 583done 584cat <<EOF 585#endif 586 587 c = add_set_cmd ("eventdebug", class_maintenance, var_zinteger, 588 (char *) (&gdb_events_debug), "Set event debugging.\n\\ 589When non-zero, event/notify debugging is enabled.", &setlist); 590 deprecate_cmd (c, "set debug event"); 591 deprecate_cmd (add_show_from_set (c, &showlist), "show debug event"); 592 593 add_show_from_set (add_set_cmd ("event", 594 class_maintenance, 595 var_zinteger, 596 (char *) (&gdb_events_debug), 597 "Set event debugging.\n\\ 598When non-zero, event/notify debugging is enabled.", &setdebuglist), 599 &showdebuglist); 600} 601EOF 602 603# close things off 604exec 1>&2 605#../move-if-change new-gdb-events.c gdb-events.c 606# Replace any leading spaces with tabs 607sed < new-gdb-events.c > tmp-gdb-events.c \ 608 -e 's/\( \)* /\1 /g' 609mv tmp-gdb-events.c new-gdb-events.c 610# Move if changed? 611if test -r gdb-events.c 612then 613 diff -c gdb-events.c new-gdb-events.c 614 if [ $? = 1 ] 615 then 616 echo "gdb-events.c changed? cp new-gdb-events.c gdb-events.c" 1>&2 617 fi 618else 619 echo "File missing? mv new-gdb-events.c gdb-events.c" 1>&2 620fi 621