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