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