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