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