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