Move putchar_filtered() to utils.c.
[platform/upstream/binutils.git] / gdb / gdb-events.sh
1 #!/bin/sh
2
3 # User Interface Events.
4 # Copyright 1999-2000 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 #*: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,struct ui_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 be called before
217    calling 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 struct gdb_events *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 struct gdb_events *
365 set_gdb_event_hooks (struct gdb_events *vector)
366 {
367   struct gdb_events *old_events = current_event_hooks;
368   if (vector == NULL)
369     current_event_hooks = &queue_event_hooks;
370   else
371     current_event_hooks = vector;
372   return old_events;
373 EOF
374 function_list | while eval read $read
375 do
376   case "${class}" in
377     "*" )
378       echo "  ${function}_event = hooks->${function};"
379       ;;
380   esac
381 done
382 cat <<EOF
383 }
384 #endif
385 EOF
386
387 # event type
388 echo ""
389 cat <<EOF
390 enum gdb_event
391 {
392 EOF
393 function_list | while eval read $read
394 do
395   case "${class}" in
396     "f" )
397       echo "  ${function},"
398       ;;
399   esac
400 done
401 cat <<EOF
402   nr_gdb_events
403 };
404 EOF
405
406 # event data
407 echo ""
408 function_list | while eval read $read
409 do
410   case "${class}" in
411     "f" )
412       echo "struct ${function}"
413       echo "  {"
414       echo "    `echo ${formal} | tr '[,]' '[;]'`;"
415       echo "  };"
416       echo ""
417       ;;
418   esac
419 done
420
421 # event queue
422 cat <<EOF
423 struct event
424   {
425     enum gdb_event type;
426     struct event *next;
427     union
428       {
429 EOF
430 function_list | while eval read $read
431 do
432   case "${class}" in
433     "f" )
434       echo "        struct ${function} ${function};"
435       ;;
436   esac
437 done
438 cat <<EOF
439       }
440     data;
441   };
442 struct event *pending_events;
443 struct event *delivering_events;
444 EOF
445
446 # append
447 echo ""
448 cat <<EOF
449 static void
450 append (struct event *new_event)
451 {
452   struct event **event = &pending_events;
453   while ((*event) != NULL)
454     event = &((*event)->next);
455   (*event) = new_event;
456   (*event)->next = NULL;
457 }
458 EOF
459
460 # schedule a given event
461 function_list | while eval read $read
462 do
463   case "${class}" in
464     "f" )
465       echo ""
466       echo "static void"
467       echo "queue_${function} (${formal})"
468       echo "{"
469       echo "  struct event *event = XMALLOC (struct event);"
470       echo "  event->type = ${function};"
471       for arg in `echo ${actual} | tr '[,]' '[ ]'`; do
472         echo "  event->data.${function}.${arg} = ${arg};"
473       done
474       echo "  append (event);"
475       echo "}"
476       ;;
477   esac
478 done
479
480 # deliver
481 echo ""
482 cat <<EOF
483 void
484 gdb_events_deliver (struct gdb_events *vector)
485 {
486   /* Just zap any events left around from last time. */
487   while (delivering_events != NULL)
488     {
489       struct event *event = delivering_events;
490       delivering_events = event->next;
491       free (event);
492     }
493   /* Process any pending events.  Because one of the deliveries could
494      bail out we move everything off of the pending queue onto an
495      in-progress queue where it can, later, be cleaned up if
496      necessary. */
497   delivering_events = pending_events;
498   pending_events = NULL;
499   while (delivering_events != NULL)
500     {
501       struct event *event = delivering_events;
502       switch (event->type)
503         {
504 EOF
505 function_list | while eval read $read
506 do
507   case "${class}" in
508     "f" )
509       echo "        case ${function}:"
510       echo "          vector->${function}"
511       sep="            ("
512       ass=""
513       for arg in `echo ${actual} | tr '[,]' '[ ]'`; do
514         ass="${ass}${sep}event->data.${function}.${arg}"
515         sep=",
516              "
517       done
518       echo "${ass});"
519       echo "          break;"
520       ;;
521   esac
522 done
523 cat <<EOF
524         }
525       delivering_events = event->next;
526       free (event);
527     }
528 }
529 EOF
530
531 # Finally the initialization
532 echo ""
533 cat <<EOF
534 void _initialize_gdb_events (void);
535 void
536 _initialize_gdb_events (void)
537 {
538   struct cmd_list_element *c;
539 #if WITH_GDB_EVENTS
540 EOF
541 function_list | while eval read $read
542 do
543   case "${class}" in
544     "f" )
545       echo "  queue_event_hooks.${function} = queue_${function};"
546       ;;
547   esac
548 done
549 cat <<EOF
550 #endif
551
552   c = add_set_cmd ("eventdebug", class_maintenance, var_zinteger,
553                    (char *) (&gdb_events_debug), "Set event debugging.\n\\
554 When non-zero, event/notify debugging is enabled.", &setlist);
555   deprecate_cmd (c, "set debug event");
556   deprecate_cmd (add_show_from_set (c, &showlist), "show debug event");
557
558   add_show_from_set (add_set_cmd ("event",
559                                   class_maintenance,
560                                   var_zinteger,
561                                   (char *) (&gdb_events_debug),
562                                   "Set event debugging.\n\\
563 When non-zero, event/notify debugging is enabled.", &setdebuglist),
564                      &showdebuglist);
565 }
566 EOF
567
568 # close things off
569 exec 1>&2
570 #../move-if-change new-gdb-events.c gdb-events.c
571 # Replace any leading spaces with tabs
572 sed < new-gdb-events.c > tmp-gdb-events.c \
573     -e 's/\(    \)*        /\1  /g'
574 mv tmp-gdb-events.c new-gdb-events.c
575 # Move if changed?
576 if ! test -r gdb-events.c
577 then
578   echo "File missing? mv new-gdb-events.c gdb-events.c" 1>&2
579 elif ! diff -c gdb-events.c new-gdb-events.c
580 then
581   echo "gdb-events.c changed? cp new-gdb-events.c gdb-events.c" 1>&2
582 fi