1#!/bin/sh
2
3# User Interface Events.
4#
5# Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2007
6# Free Software Foundation, Inc.
7#
8# Contributed by Cygnus Solutions.
9#
10# This file is part of GDB.
11#
12# This program is free software; you can redistribute it and/or modify
13# it under the terms of the GNU General Public License as published by
14# the Free Software Foundation; either version 3 of the License, or
15# (at your option) any later version.
16#
17# This program is distributed in the hope that it will be useful,
18# but WITHOUT ANY WARRANTY; without even the implied warranty of
19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20# GNU General Public License for more details.
21#
22# You should have received a copy of the GNU General Public License
23# along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
25IFS=:
26
27read="class returntype function formal actual attrib"
28
29function_list ()
30{
31  # category:
32  #        # -> disable
33  #        * -> compatibility - pointer variable that is initialized
34  #             by set_gdb_events().
35  #        ? -> Predicate and function proper.
36  #        f -> always call (must have a void returntype)
37  # return-type
38  # name
39  # formal argument list
40  # actual argument list
41  # attributes
42  # description
43  cat <<EOF |
44f:void:breakpoint_create:int b:b
45f:void:breakpoint_delete:int b:b
46f:void:breakpoint_modify:int b:b
47f:void:tracepoint_create:int number:number
48f:void:tracepoint_delete:int number:number
49f:void:tracepoint_modify:int number:number
50f:void:architecture_changed:void
51EOF
52  grep -v '^#'
53}
54
55copyright ()
56{
57  cat <<EOF
58/* User Interface Events.
59
60   Copyright (C) 1999, 2001, 2002, 2004, 2005, 2007
61   Free Software Foundation, Inc.
62
63   Contributed by Cygnus Solutions.
64
65   This file is part of GDB.
66
67   This program is free software; you can redistribute it and/or modify
68   it under the terms of the GNU General Public License as published by
69   the Free Software Foundation; either version 3 of the License, or
70   (at your option) any later version.
71   
72   This program is distributed in the hope that it will be useful,
73   but WITHOUT ANY WARRANTY; without even the implied warranty of
74   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
75   GNU General Public License for more details.
76   
77   You should have received a copy of the GNU General Public License
78   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
79
80/* Work in progress */
81
82/* This file was created with the aid of \`\`gdb-events.sh''.
83
84   The bourn shell script \`\`gdb-events.sh'' creates the files
85   \`\`new-gdb-events.c'' and \`\`new-gdb-events.h and then compares
86   them against the existing \`\`gdb-events.[hc]''.  Any differences
87   found being reported.
88
89   If editing this file, please also run gdb-events.sh and merge any
90   changes into that script. Conversely, when making sweeping changes
91   to this file, modifying gdb-events.sh and using its output may
92   prove easier.  */
93
94EOF
95}
96
97#
98# The .h file
99#
100
101exec > new-gdb-events.h
102copyright
103cat <<EOF
104
105#ifndef GDB_EVENTS_H
106#define GDB_EVENTS_H
107EOF
108
109# pointer declarations
110echo ""
111echo ""
112cat <<EOF
113/* COMPAT: pointer variables for old, unconverted events.
114   A call to set_gdb_events() will automatically update these. */
115EOF
116echo ""
117function_list | while eval read $read
118do
119  case "${class}" in
120    "*" )
121	echo "extern ${returntype} (*${function}_event) (${formal})${attrib};"
122	;;
123  esac
124done
125
126# function typedef's
127echo ""
128echo ""
129cat <<EOF
130/* Type definition of all hook functions.  Recommended pratice is to
131   first declare each hook function using the below ftype and then
132   define it.  */
133EOF
134echo ""
135function_list | while eval read $read
136do
137  echo "typedef ${returntype} (gdb_events_${function}_ftype) (${formal});"
138done
139
140# gdb_events object
141echo ""
142echo ""
143cat <<EOF
144/* gdb-events: object. */
145EOF
146echo ""
147echo "struct gdb_events"
148echo "  {"
149function_list | while eval read $read
150do
151  echo "    gdb_events_${function}_ftype *${function}${attrib};"
152done
153echo "  };"
154
155# function declarations
156echo ""
157echo ""
158cat <<EOF
159/* Interface into events functions.
160   Where a *_p() predicate is present, it must be called before
161   calling the hook proper.  */
162EOF
163function_list | while eval read $read
164do
165  case "${class}" in
166    "*" ) continue ;;
167    "?" )
168	echo "extern int ${function}_p (void);"
169        echo "extern ${returntype} ${function}_event (${formal})${attrib};"
170	;;
171    "f" )
172	echo "extern ${returntype} ${function}_event (${formal})${attrib};"
173	;;
174  esac
175done
176
177# our set function
178cat <<EOF
179
180/* Install custom gdb-events hooks.  */
181extern struct gdb_events *deprecated_set_gdb_event_hooks (struct gdb_events *vector);
182
183/* Deliver any pending events.  */
184extern void gdb_events_deliver (struct gdb_events *vector);
185
186/* Clear event handlers.  */
187extern void clear_gdb_event_hooks (void);
188EOF
189
190# close it off
191echo ""
192echo "#endif"
193exec 1>&2
194#../move-if-change new-gdb-events.h gdb-events.h
195if test -r gdb-events.h
196then
197  diff -c gdb-events.h new-gdb-events.h
198  if [ $? = 1 ]
199  then
200    echo "gdb-events.h changed? cp new-gdb-events.h gdb-events.h" 1>&2
201  fi
202else
203  echo "File missing? mv new-gdb-events.h gdb-events.h" 1>&2
204fi
205
206
207
208#
209# C file
210#
211
212exec > new-gdb-events.c
213copyright
214cat <<EOF
215
216#include "defs.h"
217#include "gdb-events.h"
218#include "gdbcmd.h"
219
220static struct gdb_events null_event_hooks;
221static struct gdb_events queue_event_hooks;
222static struct gdb_events *current_event_hooks = &null_event_hooks;
223
224int gdb_events_debug;
225static void
226show_gdb_events_debug (struct ui_file *file, int from_tty,
227                       struct cmd_list_element *c, const char *value)
228{
229  fprintf_filtered (file, _("Event debugging is %s.\\n"), value);
230}
231
232EOF
233
234# function bodies
235function_list | while eval read $read
236do
237  case "${class}" in
238    "*" ) continue ;;
239    "?" )
240cat <<EOF
241
242int
243${function}_event_p (${formal})
244{
245  return current_event_hooks->${function};
246}
247
248${returntype}
249${function}_event (${formal})
250{
251  return current_events->${function} (${actual});
252}
253EOF
254	;;
255     "f" )
256cat <<EOF
257
258void
259${function}_event (${formal})
260{
261  if (gdb_events_debug)
262    fprintf_unfiltered (gdb_stdlog, "${function}_event\n");
263  if (!current_event_hooks->${function})
264    return;
265  current_event_hooks->${function} (${actual});
266}
267EOF
268	;;
269  esac
270done
271
272# Set hooks function
273echo ""
274cat <<EOF
275struct gdb_events *
276deprecated_set_gdb_event_hooks (struct gdb_events *vector)
277{
278  struct gdb_events *old_events = current_event_hooks;
279  if (vector == NULL)
280    current_event_hooks = &queue_event_hooks;
281  else
282    current_event_hooks = vector;
283  return old_events;
284EOF
285function_list | while eval read $read
286do
287  case "${class}" in
288    "*" )
289      echo "  ${function}_event = hooks->${function};"
290      ;;
291  esac
292done
293cat <<EOF
294}
295EOF
296
297# Clear hooks function
298echo ""
299cat <<EOF
300void
301clear_gdb_event_hooks (void)
302{
303  deprecated_set_gdb_event_hooks (&null_event_hooks);
304}
305EOF
306
307# event type
308echo ""
309cat <<EOF
310enum gdb_event
311{
312EOF
313function_list | while eval read $read
314do
315  case "${class}" in
316    "f" )
317      echo "  ${function},"
318      ;;
319  esac
320done
321cat <<EOF
322  nr_gdb_events
323};
324EOF
325
326# event data
327echo ""
328function_list | while eval read $read
329do
330  case "${class}" in
331    "f" )
332      if test ${actual}
333      then
334        echo "struct ${function}"
335        echo "  {"
336        echo "    `echo ${formal} | tr '[,]' '[;]'`;"
337        echo "  };"
338        echo ""
339      fi
340      ;;
341  esac
342done
343
344# event queue
345cat <<EOF
346struct event
347  {
348    enum gdb_event type;
349    struct event *next;
350    union
351      {
352EOF
353function_list | while eval read $read
354do
355  case "${class}" in
356    "f" )
357      if test ${actual}
358      then
359        echo "        struct ${function} ${function};"
360      fi
361      ;;
362  esac
363done
364cat <<EOF
365      }
366    data;
367  };
368struct event *pending_events;
369struct event *delivering_events;
370EOF
371
372# append
373echo ""
374cat <<EOF
375static void
376append (struct event *new_event)
377{
378  struct event **event = &pending_events;
379  while ((*event) != NULL)
380    event = &((*event)->next);
381  (*event) = new_event;
382  (*event)->next = NULL;
383}
384EOF
385
386# schedule a given event
387function_list | while eval read $read
388do
389  case "${class}" in
390    "f" )
391      echo ""
392      echo "static void"
393      echo "queue_${function} (${formal})"
394      echo "{"
395      echo "  struct event *event = XMALLOC (struct event);"
396      echo "  event->type = ${function};"
397      for arg in `echo ${actual} | tr '[,]' '[:]' | tr -d '[ ]'`; do
398        echo "  event->data.${function}.${arg} = ${arg};"
399      done
400      echo "  append (event);"
401      echo "}"
402      ;;
403  esac
404done
405
406# deliver
407echo ""
408cat <<EOF
409void
410gdb_events_deliver (struct gdb_events *vector)
411{
412  /* Just zap any events left around from last time. */
413  while (delivering_events != NULL)
414    {
415      struct event *event = delivering_events;
416      delivering_events = event->next;
417      xfree (event);
418    }
419  /* Process any pending events.  Because one of the deliveries could
420     bail out we move everything off of the pending queue onto an
421     in-progress queue where it can, later, be cleaned up if
422     necessary. */
423  delivering_events = pending_events;
424  pending_events = NULL;
425  while (delivering_events != NULL)
426    {
427      struct event *event = delivering_events;
428      switch (event->type)
429        {
430EOF
431function_list | while eval read $read
432do
433  case "${class}" in
434    "f" )
435      echo "        case ${function}:"
436      if test ${actual}
437      then
438        echo "          vector->${function}"
439        sep="            ("
440        ass=""
441        for arg in `echo ${actual} | tr '[,]' '[:]' | tr -d '[ ]'`; do
442          ass="${ass}${sep}event->data.${function}.${arg}"
443	  sep=",
444               "
445        done
446        echo "${ass});"
447      else
448        echo "          vector->${function} ();"
449      fi
450      echo "          break;"
451      ;;
452  esac
453done
454cat <<EOF
455        }
456      delivering_events = event->next;
457      xfree (event);
458    }
459}
460EOF
461
462# Finally the initialization
463echo ""
464cat <<EOF
465void _initialize_gdb_events (void);
466void
467_initialize_gdb_events (void)
468{
469  struct cmd_list_element *c;
470EOF
471function_list | while eval read $read
472do
473  case "${class}" in
474    "f" )
475      echo "  queue_event_hooks.${function} = queue_${function};"
476      ;;
477  esac
478done
479cat <<EOF
480
481  add_setshow_zinteger_cmd ("event", class_maintenance,
482                            &gdb_events_debug, _("\\
483Set event debugging."), _("\\
484Show event debugging."), _("\\
485When non-zero, event/notify debugging is enabled."),
486                            NULL,
487                            show_gdb_events_debug,
488                            &setdebuglist, &showdebuglist);
489}
490EOF
491
492# close things off
493exec 1>&2
494#../move-if-change new-gdb-events.c gdb-events.c
495# Replace any leading spaces with tabs
496sed < new-gdb-events.c > tmp-gdb-events.c \
497    -e 's/\(	\)*        /\1	/g'
498mv tmp-gdb-events.c new-gdb-events.c
499# Move if changed?
500if test -r gdb-events.c
501then
502  diff -c gdb-events.c new-gdb-events.c
503  if [ $? = 1 ]
504  then
505    echo "gdb-events.c changed? cp new-gdb-events.c gdb-events.c" 1>&2
506  fi
507else
508  echo "File missing? mv new-gdb-events.c gdb-events.c" 1>&2
509fi
510