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