4 # gtk-doc - GTK DocBook documentation generator.
5 # Copyright (C) 1998 Damon Chaplin
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 # This gets information about object heirarchies and signals
24 # by compiling a small C program. CFLAGS and LDFLAGS must be
25 # set appropriately before running this script.
27 # NOTE: the lookup_signal_arg_names() function contains the argument names of
28 # standard GTK signal handlers. This may need to be updated for new
29 # GTK signals or Gnome widget signals.
33 unshift @INC, "@PACKAGE_DATA_DIR@";
34 require "gtkdoc-common.pl";
38 # name of documentation module
43 my $TYPE_INIT_FUNC="g_type_init ()";
45 # --nogtkinit is deprecated, as it is the default now anyway.
46 %optctl = (module => \$MODULE,
47 types => \$TYPES_FILE,
48 nogtkinit => \$NO_GTK_INIT,
49 'type-init-func' => \$TYPE_INIT_FUNC,
50 'output-dir' => \$OUTPUT_DIR,
51 'version' => \$PRINT_VERSION,
52 'help' => \$PRINT_HELP);
54 GetOptions(\%optctl, "module=s", "types:s", "output-dir:s", "nogtkinit", "type-init-func:s", "version", "help");
57 # Do nothing. This just avoids a warning.
70 print "gtkdoc-scangobj version @VERSION@\n";
71 print "\n--module=MODULE_NAME Name of the doc module being parsed";
72 print "\n--types=FILE The name of the file to store the types in";
73 print "\n--type-init-func=FUNC The init function to call instead of g_type_init ()";
74 print "\n--output-dir=DIRNAME The directory where the results are stored";
75 print "\n--version Print the version of this program";
76 print "\n--help Print this help\n";
80 $OUTPUT_DIR = $OUTPUT_DIR ? $OUTPUT_DIR : ".";
82 $TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$OUTPUT_DIR/$MODULE.types";
84 open TYPES, $TYPES_FILE || die "Cannot open $TYPES_FILE: $!\n";
85 open OUTPUT, ">$MODULE-scan.c" || die "Cannot open $MODULE-scan.c: $!\n";
87 my $old_signals_filename = "$OUTPUT_DIR/$MODULE.signals";
88 my $new_signals_filename = "$OUTPUT_DIR/$MODULE.signals.new";
89 my $old_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy";
90 my $new_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy.new";
91 my $old_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces";
92 my $new_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces.new";
93 my $old_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites";
94 my $new_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites.new";
95 my $old_args_filename = "$OUTPUT_DIR/$MODULE.args";
96 my $new_args_filename = "$OUTPUT_DIR/$MODULE.args.new";
98 # write a C program to scan the types
116 $ntypes = @types + 1;
124 #ifdef GTK_IS_WIDGET_CLASS
125 #include <gtk/gtkversion.h>
127 GType object_types[$ntypes];
130 get_object_types (void)
136 print OUTPUT " object_types[i++] = $_ ();\n";
142 /* Need to make sure all the types are loaded in and initialize
143 * their signals and properties.
145 for (i=0; object_types[i]; i++)
146 if (G_TYPE_IS_CLASSED (object_types[i]))
147 g_type_class_ref (object_types[i]);
153 * This uses GTK type functions to output signal prototypes and the widget
157 /* The output files */
158 gchar *signals_filename = "$new_signals_filename";
159 gchar *hierarchy_filename = "$new_hierarchy_filename";
160 gchar *interfaces_filename = "$new_interfaces_filename";
161 gchar *prerequisites_filename = "$new_prerequisites_filename";
162 gchar *args_filename = "$new_args_filename";
165 static void output_signals (void);
166 static void output_widget_signals (FILE *fp,
168 static void output_widget_signal (FILE *fp,
170 const gchar *object_class_name,
172 static const gchar * get_type_name (GType type,
173 gboolean * is_pointer);
174 static gchar * get_gdk_event (const gchar * signal_name);
175 static gchar ** lookup_signal_arg_names (const gchar * type,
176 const gchar * signal_name);
178 static void output_widget_hierarchy (void);
179 static void output_hierarchy (FILE *fp,
183 static void output_widget_interfaces (void);
184 static void output_interfaces (FILE *fp,
187 static void output_interface_prerequisites (void);
188 static void output_prerequisites (FILE *fp,
191 static void output_args (void);
192 static void output_widget_args (FILE *fp, GType object_type);
195 main (int argc, char *argv[])
202 output_widget_hierarchy ();
203 output_widget_interfaces ();
204 output_interface_prerequisites ();
212 output_signals (void)
217 fp = fopen (signals_filename, "w");
220 g_warning ("Couldn't open output file: %s", signals_filename);
224 for (i = 0; object_types[i]; i++)
225 output_widget_signals (fp, object_types[i]);
231 compare_signals (const void *a, const void *b)
233 const guint *signal_a = a;
234 const guint *signal_b = b;
236 return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b));
239 /* This outputs all the signals of one widget. */
241 output_widget_signals (FILE *fp, GType object_type)
243 const gchar *object_class_name;
244 guint *signals, n_signals;
247 if (G_TYPE_IS_INSTANTIATABLE (object_type) ||
248 G_TYPE_IS_INTERFACE (object_type))
251 object_class_name = g_type_name (object_type);
253 signals = g_signal_list_ids (object_type, &n_signals);
254 qsort (signals, n_signals, sizeof (guint), compare_signals);
256 for (sig = 0; sig < n_signals; sig++)
258 output_widget_signal (fp, object_type, object_class_name,
266 /* This outputs one signal. */
268 output_widget_signal (FILE *fp,
270 const gchar *object_name,
273 GSignalQuery query_info;
274 const gchar *type_name, *ret_type, *object_arg;
275 gchar *pos, *arg_name, *object_arg_lower;
277 gchar ret_type_buffer[1024], buffer[1024];
280 gint param_num, widget_num, event_num, callback_num;
282 gchar signal_name[128];
285 /* g_print ("Object: %s Type: %i Signal: %u\\n", object_name, object_type,
289 widget_num = event_num = callback_num = 0;
291 g_signal_query (signal_id, &query_info);
293 /* Output the return type and function name. */
294 ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
295 sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
297 /* Output the signal object type and the argument name. We assume the
298 type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
299 convert to lower case for the argument name. */
301 sprintf (pos, "%s ", object_name);
304 if (!strncmp (object_name, "Gtk", 3))
305 object_arg = object_name + 3;
306 else if (!strncmp (object_name, "Gnome", 5))
307 object_arg = object_name + 5;
309 object_arg = object_name;
311 object_arg_lower = g_ascii_strdown (object_arg, -1);
312 sprintf (pos, "*%s\\n", object_arg_lower);
314 if (!strncmp (object_arg_lower, "widget", 6))
316 g_free(object_arg_lower);
318 /* Convert signal name to use underscores rather than dashes '-'. */
319 strcpy (signal_name, query_info.signal_name);
320 for (i = 0; signal_name[i]; i++)
322 if (signal_name[i] == '-')
323 signal_name[i] = '_';
326 /* Output the signal parameters. */
327 arg_names = lookup_signal_arg_names (object_name, signal_name);
329 for (param = 0; param < query_info.n_params; param++)
333 sprintf (pos, "%s\\n", arg_names[param]);
338 type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
340 /* Most arguments to the callback are called "arg1", "arg2", etc.
341 GdkWidgets are called "widget", "widget2", ...
342 GdkEvents are called "event", "event2", ...
343 GtkCallbacks are called "callback", "callback2", ... */
344 if (!strcmp (type_name, "GtkWidget"))
347 arg_num = &widget_num;
349 else if (!strcmp (type_name, "GdkEvent"))
351 type_name = get_gdk_event (signal_name);
353 arg_num = &event_num;
356 else if (!strcmp (type_name, "GtkCallback")
357 || !strcmp (type_name, "GtkCCallback"))
359 arg_name = "callback";
360 arg_num = &callback_num;
365 arg_num = ¶m_num;
367 sprintf (pos, "%s ", type_name);
370 if (!arg_num || *arg_num == 0)
371 sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
373 sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
388 "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n%s</SIGNAL>\\n\\n",
389 object_name, query_info.signal_name, ret_type_buffer, buffer);
393 /* Returns the type name to use for a signal argument or return value, given
394 the GtkType from the signal info. It also sets is_pointer to TRUE if the
395 argument needs a '*' since it is a pointer. */
397 get_type_name (GType type, gboolean * is_pointer)
399 const gchar *type_name;
402 type_name = g_type_name (type);
416 /* These all have normal C type names so they are OK. */
420 /* A GtkString is really a gchar*. */
426 /* We use a gint for both of these. Hopefully a subtype with a decent
427 name will be registered and used instead, as GTK+ does itself. */
431 /* The boxed type shouldn't be used itself, only subtypes. Though we
432 return 'gpointer' just in case. */
436 /* A GParam is really a GParamSpec*. */
444 /* For all GtkObject subclasses we can use the class name with a "*",
445 e.g. 'GtkWidget *'. */
446 if (g_type_is_a (type, G_TYPE_OBJECT))
449 /* All boxed subtypes will be pointers as well. */
450 if (g_type_is_a (type, G_TYPE_BOXED))
453 /* All pointer subtypes will be pointers as well. */
454 if (g_type_is_a (type, G_TYPE_POINTER))
462 get_gdk_event (const gchar * signal_name)
464 static gchar *GbGDKEvents[] =
466 "button_press_event", "GdkEventButton",
467 "button_release_event", "GdkEventButton",
468 "motion_notify_event", "GdkEventMotion",
469 "delete_event", "GdkEvent",
470 "destroy_event", "GdkEvent",
471 "expose_event", "GdkEventExpose",
472 "key_press_event", "GdkEventKey",
473 "key_release_event", "GdkEventKey",
474 "enter_notify_event", "GdkEventCrossing",
475 "leave_notify_event", "GdkEventCrossing",
476 "configure_event", "GdkEventConfigure",
477 "focus_in_event", "GdkEventFocus",
478 "focus_out_event", "GdkEventFocus",
479 "map_event", "GdkEvent",
480 "unmap_event", "GdkEvent",
481 "property_notify_event", "GdkEventProperty",
482 "selection_clear_event", "GdkEventSelection",
483 "selection_request_event", "GdkEventSelection",
484 "selection_notify_event", "GdkEventSelection",
485 "proximity_in_event", "GdkEventProximity",
486 "proximity_out_event", "GdkEventProximity",
487 "drag_begin_event", "GdkEventDragBegin",
488 "drag_request_event", "GdkEventDragRequest",
489 "drag_end_event", "GdkEventDragRequest",
490 "drop_enter_event", "GdkEventDropEnter",
491 "drop_leave_event", "GdkEventDropLeave",
492 "drop_data_available_event", "GdkEventDropDataAvailable",
493 "other_event", "GdkEventOther",
494 "client_event", "GdkEventClient",
495 "no_expose_event", "GdkEventNoExpose",
501 for (i = 0; GbGDKEvents[i]; i += 2)
503 if (!strcmp (signal_name, GbGDKEvents[i]))
504 return GbGDKEvents[i + 1];
510 /* This returns argument names to use for some known GTK signals.
511 It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
512 'select_row' and it returns a pointer to an array of argument types and
515 lookup_signal_arg_names (const gchar * type, const gchar * signal_name)
517 /* Each arg array starts with the object type name and the signal name,
518 and then signal arguments follow. */
519 static gchar *GbArgTable[][16] =
521 {"GtkCList", "select_row",
524 "GdkEventButton *event"},
525 {"GtkCList", "unselect_row",
528 "GdkEventButton *event"},
529 {"GtkCList", "click_column",
532 {"GtkCList", "resize_column",
536 {"GtkCList", "extend_selection",
537 "GtkScrollType scroll_type",
539 "gboolean auto_start_selection"},
540 {"GtkCList", "scroll_vertical",
541 "GtkScrollType scroll_type",
543 {"GtkCList", "scroll_horizontal",
544 "GtkScrollType scroll_type",
547 {"GtkCTree", "tree_select_row",
548 "GtkCTreeNode *node",
550 {"GtkCTree", "tree_unselect_row",
551 "GtkCTreeNode *node",
553 {"GtkCTree", "tree_expand",
554 "GtkCTreeNode *node"},
555 {"GtkCTree", "tree_collapse",
556 "GtkCTreeNode *node"},
557 {"GtkCTree", "tree_move",
558 "GtkCTreeNode *node",
559 "GtkCTreeNode *new_parent",
560 "GtkCTreeNode *new_sibling"},
561 {"GtkCTree", "change_focus_row_expansion",
562 "GtkCTreeExpansionType expansion"},
564 {"GtkEditable", "insert_text",
566 "gint new_text_length",
568 {"GtkEditable", "delete_text",
571 {"GtkEditable", "set_editable",
572 "gboolean is_editable"},
573 {"GtkEditable", "move_cursor",
576 {"GtkEditable", "move_word",
578 {"GtkEditable", "move_page",
581 {"GtkEditable", "move_to_row",
583 {"GtkEditable", "move_to_column",
586 {"GtkEditable", "kill_char",
588 {"GtkEditable", "kill_word",
590 {"GtkEditable", "kill_line",
594 {"GtkInputDialog", "enable_device",
595 "GdkDevice *deviceid"},
596 {"GtkInputDialog", "disable_device",
597 "GdkDevice *deviceid"},
599 {"GtkListItem", "extend_selection",
600 "GtkScrollType scroll_type",
602 "gboolean auto_start_selection"},
603 {"GtkListItem", "scroll_vertical",
604 "GtkScrollType scroll_type",
606 {"GtkListItem", "scroll_horizontal",
607 "GtkScrollType scroll_type",
610 {"GtkMenuShell", "move_current",
611 "GtkMenuDirectionType direction"},
612 {"GtkMenuShell", "activate_current",
613 "gboolean force_hide"},
616 {"GtkNotebook", "switch_page",
617 "GtkNotebookPage *page",
619 {"GtkStatusbar", "text_pushed",
622 {"GtkStatusbar", "text_popped",
625 {"GtkTipsQuery", "widget_entered",
628 "gchar *tip_private"},
629 {"GtkTipsQuery", "widget_selected",
632 "gchar *tip_private",
633 "GdkEventButton *event"},
634 {"GtkToolbar", "orientation_changed",
635 "GtkOrientation orientation"},
636 {"GtkToolbar", "style_changed",
637 "GtkToolbarStyle style"},
638 {"GtkWidget", "draw",
639 "GdkRectangle *area"},
640 {"GtkWidget", "size_request",
641 "GtkRequisition *requisition"},
642 {"GtkWidget", "size_allocate",
643 "GtkAllocation *allocation"},
644 {"GtkWidget", "state_changed",
645 "GtkStateType state"},
646 {"GtkWidget", "style_set",
647 "GtkStyle *previous_style"},
649 {"GtkWidget", "install_accelerator",
650 "gchar *signal_name",
654 {"GtkWidget", "add_accelerator",
655 "guint accel_signal_id",
656 "GtkAccelGroup *accel_group",
658 "GdkModifierType accel_mods",
659 "GtkAccelFlags accel_flags"},
661 {"GtkWidget", "parent_set",
662 "GtkObject *old_parent"},
664 {"GtkWidget", "remove_accelerator",
665 "GtkAccelGroup *accel_group",
667 "GdkModifierType accel_mods"},
668 {"GtkWidget", "debug_msg",
670 {"GtkWindow", "move_resize",
675 {"GtkWindow", "set_focus",
676 "GtkWidget *widget"},
678 {"GtkWidget", "selection_get",
679 "GtkSelectionData *data",
682 {"GtkWidget", "selection_received",
683 "GtkSelectionData *data",
686 {"GtkWidget", "drag_begin",
687 "GdkDragContext *drag_context"},
688 {"GtkWidget", "drag_end",
689 "GdkDragContext *drag_context"},
690 {"GtkWidget", "drag_data_delete",
691 "GdkDragContext *drag_context"},
692 {"GtkWidget", "drag_leave",
693 "GdkDragContext *drag_context",
695 {"GtkWidget", "drag_motion",
696 "GdkDragContext *drag_context",
700 {"GtkWidget", "drag_drop",
701 "GdkDragContext *drag_context",
705 {"GtkWidget", "drag_data_get",
706 "GdkDragContext *drag_context",
707 "GtkSelectionData *data",
710 {"GtkWidget", "drag_data_received",
711 "GdkDragContext *drag_context",
714 "GtkSelectionData *data",
723 for (i = 0; GbArgTable[i][0]; i++)
726 if (!strcmp (type, GbArgTable[i][0])
727 && !strcmp (signal_name, GbArgTable[i][1]))
728 return &GbArgTable[i][2];
734 /* This outputs the hierarchy of all widgets which have been initialized,
735 i.e. by calling their XXX_get_type() initialization function. */
737 output_widget_hierarchy (void)
741 fp = fopen (hierarchy_filename, "w");
744 g_warning ("Couldn't open output file: %s", hierarchy_filename);
747 output_hierarchy (fp, G_TYPE_OBJECT, 0);
748 output_hierarchy (fp, G_TYPE_INTERFACE, 0);
752 /* This is called recursively to output the hierarchy of a widget. */
754 output_hierarchy (FILE *fp,
765 for (i = 0; i < level; i++)
767 fprintf (fp, g_type_name (type));
770 children = g_type_children (type, &n_children);
772 for (i=0; i < n_children; i++)
773 output_hierarchy (fp, children[i], level + 1);
778 static void output_widget_interfaces (void)
782 fp = fopen (interfaces_filename, "w");
785 g_warning ("Couldn't open output file: %s", interfaces_filename);
788 output_interfaces (fp, G_TYPE_OBJECT);
793 output_interfaces (FILE *fp,
797 GType *children, *interfaces;
798 guint n_children, n_interfaces;
803 interfaces = g_type_interfaces (type, &n_interfaces);
805 if (n_interfaces > 0)
807 fprintf (fp, g_type_name (type));
808 for (i=0; i < n_interfaces; i++)
809 fprintf (fp, " %s", g_type_name (interfaces[i]));
814 children = g_type_children (type, &n_children);
816 for (i=0; i < n_children; i++)
817 output_interfaces (fp, children[i]);
822 static void output_interface_prerequisites (void)
826 fp = fopen (prerequisites_filename, "w");
829 g_warning ("Couldn't open output file: %s", prerequisites_filename);
832 output_prerequisites (fp, G_TYPE_INTERFACE);
837 output_prerequisites (FILE *fp,
840 #if GLIB_CHECK_VERSION(2,1,0)
842 GType *children, *prerequisites;
843 guint n_children, n_prerequisites;
848 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
850 if (n_prerequisites > 0)
852 fprintf (fp, g_type_name (type));
853 for (i=0; i < n_prerequisites; i++)
854 fprintf (fp, " %s", g_type_name (prerequisites[i]));
857 g_free (prerequisites);
859 children = g_type_children (type, &n_children);
861 for (i=0; i < n_children; i++)
862 output_prerequisites (fp, children[i]);
874 fp = fopen (args_filename, "w");
877 g_warning ("Couldn't open output file: %s", args_filename);
881 for (i = 0; object_types[i]; i++)
882 output_widget_args (fp, object_types[i]);
888 compare_param_specs (const void *a, const void *b)
890 GParamSpec *spec_a = *(GParamSpec **)a;
891 GParamSpec *spec_b = *(GParamSpec **)b;
893 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
897 output_widget_args (FILE *fp, GType object_type)
900 const gchar *object_class_name;
902 gchar flags[16], *pos;
903 GParamSpec **properties;
908 if (G_TYPE_IS_CLASSED (object_type))
910 class = g_type_class_peek (object_type);
914 properties = g_object_class_list_properties (class, &n_properties);
916 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
917 else if (G_TYPE_IS_INTERFACE (object_type))
919 class = g_type_default_interface_ref (object_type);
924 properties = g_object_interface_list_properties (class, &n_properties);
930 object_class_name = g_type_name (object_type);
936 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
937 for (arg = 0; arg < n_properties; arg++)
939 GParamSpec *spec = properties[arg];
940 const gchar *nick, *blurb, *dot;
942 if (spec->owner_type != object_type)
946 /* We use one-character flags for simplicity. */
947 if (child_prop && !style_prop)
951 if (spec->flags & G_PARAM_READABLE)
953 if (spec->flags & G_PARAM_WRITABLE)
955 if (spec->flags & G_PARAM_CONSTRUCT)
957 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
961 nick = g_param_spec_get_nick (spec);
962 blurb = g_param_spec_get_blurb (spec);
966 int str_len = strlen (blurb);
967 if (str_len > 0 && blurb[str_len - 1] != '.')
971 fprintf (fp, "<ARG>\\n<NAME>%s::%s</NAME>\\n<TYPE>%s</TYPE>\\n<FLAGS>%s</FLAGS>\\n<NICK>%s</NICK>\\n<BLURB>%s%s</BLURB>\\n</ARG>\\n\\n",
972 object_class_name, g_param_spec_get_name (spec), g_type_name (spec->value_type), flags, nick ? nick : "(null)", blurb ? blurb : "(null)", dot);
977 #ifdef GTK_IS_CONTAINER_CLASS
978 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
979 properties = gtk_container_class_list_child_properties (class, &n_properties);
985 #ifdef GTK_IS_WIDGET_CLASS
986 #if GTK_CHECK_VERSION(2,1,0)
987 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
988 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1002 # Compile and run our file
1004 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
1005 $LD = $ENV{LD} ? $ENV{LD} : $CC;
1006 $CFLAGS = $ENV{CFLAGS} ? $ENV{CFLAGS} : "";
1007 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
1010 if ($CC =~ /libtool/) {
1011 $o_file = "$MODULE-scan.lo"
1013 $o_file = "$MODULE-scan.o"
1016 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c && $LD -o $MODULE-scan $o_file $LDFLAGS";
1018 system($command) == 0 or die "Compilation of scanner failed\n";
1020 system("./$MODULE-scan") == 0 or die "Scan failed\n";
1022 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
1024 &UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
1025 &UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
1026 &UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
1027 &UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
1028 &UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);