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, '/usr/share/gtk-doc/data';
34 require "gtkdoc-common.pl";
38 # name of documentation module
44 my $TYPE_INIT_FUNC="g_type_init ()";
46 # --nogtkinit is deprecated, as it is the default now anyway.
47 %optctl = (module => \$MODULE,
49 types => \$TYPES_FILE,
50 nogtkinit => \$NO_GTK_INIT,
51 'type-init-func' => \$TYPE_INIT_FUNC,
52 'output-dir' => \$OUTPUT_DIR,
53 'inspect-dir' => \$INSPECT_DIR,
54 'version' => \$PRINT_VERSION,
55 'help' => \$PRINT_HELP);
57 GetOptions(\%optctl, "module=s", "source=s", "types:s", "output-dir:s", "inspect-dir:s", "nogtkinit", "type-init-func:s", "version", "help");
60 # Do nothing. This just avoids a warning.
73 print "gstdoc-scangobj version 1.5\n";
74 print "\n--module=MODULE_NAME Name of the doc module being parsed";
75 print "\n--source=SOURCE_NAME Name of the source module for plugins";
76 print "\n--types=FILE The name of the file to store the types in";
77 print "\n--type-init-func=FUNC The init function to call instead of g_type_init ()";
78 print "\n--output-dir=DIRNAME The directory where the results are stored";
79 print "\n--inspect-dir=DIRNAME The directory where the plugin inspect data is stored";
80 print "\n--version Print the version of this program";
81 print "\n--help Print this help\n";
85 $OUTPUT_DIR = $OUTPUT_DIR ? $OUTPUT_DIR : ".";
87 $TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$OUTPUT_DIR/$MODULE.types";
89 open (TYPES, $TYPES_FILE) || die "Cannot open $TYPES_FILE: $!\n";
90 open (OUTPUT, ">$MODULE-scan.c") || die "Cannot open $MODULE-scan.c: $!\n";
92 my $old_signals_filename = "$OUTPUT_DIR/$MODULE.signals";
93 my $new_signals_filename = "$OUTPUT_DIR/$MODULE.signals.new";
94 my $old_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy";
95 my $new_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy.new";
96 my $old_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces";
97 my $new_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces.new";
98 my $old_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites";
99 my $new_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites.new";
100 my $old_args_filename = "$OUTPUT_DIR/$MODULE.args";
101 my $new_args_filename = "$OUTPUT_DIR/$MODULE.args.new";
103 # write a C program to scan the types
116 } elsif (/^type:(.*)$/) {
119 push @impl_types, $t;
126 $ntypes = @types + @impl_types;
136 #ifdef GTK_IS_WIDGET_CLASS
137 #include <gtk/gtkversion.h>
139 GType *object_types = NULL;
142 xmlprint (gint indent, const gchar *tag, const gchar *data)
145 gchar indent_str[] = " ";
146 /* these need to be quite big */
147 static gchar str[50000];
152 const gchar *s1 = data;
182 sprintf(str, "%s<%s>%s</%s>\\n", &indent_str[20-indent], tag, conv, tag);
187 gst_feature_sort_compare (gconstpointer a, gconstpointer b)
189 return strcmp (((GstPluginFeature *)a)->name, ((GstPluginFeature *)b)->name);
193 get_object_types (void)
195 GList *plugins = NULL;
196 GList *factories = NULL;
198 GstElementFactory *factory = NULL;
203 /* get a list of features from plugins in our source module */
204 plugins = gst_registry_get_plugin_list (gst_registry_get_default());
207 GList *features, *pads;
210 FILE *inspect = NULL;
213 plugin = (GstPlugin *) (plugins->data);
214 plugins = g_list_next (plugins);
215 source = gst_plugin_get_source (plugin);
216 /*g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);*/
217 if (!source || strcmp (source, "$SOURCE") != 0) {
220 g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);
222 inspect_name = g_strdup_printf ("$INSPECT_DIR" G_DIR_SEPARATOR_S "plugin-%s.xml",
224 inspect = fopen (inspect_name, "w");
225 g_free (inspect_name);
227 /* output plugin data */
228 fputs ("<plugin>\\n",inspect);
229 fputs (xmlprint(2, "name", plugin->desc.name),inspect);
230 fputs (xmlprint(2, "description", plugin->desc.description),inspect);
231 fputs (xmlprint(2, "filename", plugin->filename),inspect);
232 fputs (xmlprint(2, "basename", plugin->basename),inspect);
233 fputs (xmlprint(2, "version", plugin->desc.version),inspect);
234 fputs (xmlprint(2, "license", plugin->desc.license),inspect);
235 fputs (xmlprint(2, "source", plugin->desc.source),inspect);
236 fputs (xmlprint(2, "package", plugin->desc.package),inspect);
237 fputs (xmlprint(2, "origin", plugin->desc.origin),inspect);
238 fputs (" <elements>\\n", inspect);
241 gst_registry_get_feature_list_by_plugin (gst_registry_get_default (),
244 /* sort factories by feature->name */
245 features = g_list_sort (features, gst_feature_sort_compare);
248 GstPluginFeature *feature;
249 feature = GST_PLUGIN_FEATURE (features->data);
250 feature = gst_plugin_feature_load (feature);
252 g_warning ("Could not load plugin feature %s",
253 gst_plugin_feature_get_name (feature));
256 if (GST_IS_ELEMENT_FACTORY (feature)) {
257 GstStaticPadTemplate *pt;
258 const gchar *pad_dir[] = { "unknown","source","sink" };
259 const gchar *pad_pres[] = { "always","sometimes","request" };
261 /*g_print (" feature: %s\\n", feature->name);*/
263 factory = GST_ELEMENT_FACTORY (feature);
264 factories = g_list_prepend (factories, factory);
266 /* output element data */
267 fputs (" <element>\\n", inspect);
268 fputs (xmlprint(6, "name", feature->name),inspect);
269 fputs (xmlprint(6, "longname", factory->details.longname),inspect);
270 fputs (xmlprint(6, "class", factory->details.klass),inspect);
271 fputs (xmlprint(6, "description", factory->details.description),inspect);
272 fputs (xmlprint(6, "author", factory->details.author),inspect);
273 fputs (" <pads>\\n", inspect);
275 /* output pad-template data */
276 pads =(GList *) gst_element_factory_get_static_pad_templates (factory);
278 pt = (GstStaticPadTemplate *)pads->data;
280 fputs (" <caps>\\n", inspect);
281 fputs (xmlprint(10, "name", pt->name_template),inspect);
282 fputs (xmlprint(10, "direction", pad_dir[pt->direction]),inspect);
283 fputs (xmlprint(10, "presence", pad_pres[pt->presence]),inspect);
284 fputs (xmlprint(10, "details", pt->static_caps.string),inspect);
285 fputs (" </caps>\\n", inspect);
287 pads = g_list_next (pads);
289 fputs (" </pads>\\n </element>\\n", inspect);
291 features = g_list_next (features);
294 fputs (" </elements>\\n</plugin>\\n", inspect);
298 g_message ("number of element factories: %d", g_list_length (factories));
300 /* allocate the object_types array to hold them */
301 object_types = g_new0 (GType, g_list_length (factories)+$ntypes+1);
308 factory = GST_ELEMENT_FACTORY (l->data);
309 type = gst_element_factory_get_element_type (factory);
311 g_message ("adding type %p for factory %s", (void *) type, gst_element_factory_get_longname (factory));
312 object_types[i++] = type;
314 g_message ("type info for factory %s not found",
315 gst_element_factory_get_longname (factory));
322 # get_type functions:
327 g_message ("$_ () didn't return a valid type");
330 object_types[i++] = type;
335 # Implicit types retrieved from GLib:
338 type = g_type_from_name ("$_");
340 g_message ("Implicit type $_ not found");
343 object_types[i++] = type;
352 /* Need to make sure all the types are loaded in and initialize
353 * their signals and properties.
355 for (i=0; object_types[i]; i++) {
356 if (G_TYPE_IS_CLASSED (object_types[i]))
357 g_type_class_ref (object_types[i]);
359 g_warning ("not reffing type: %s", g_type_name (object_types[i]));
367 * This uses GObject type functions to output signal prototypes and the object
371 /* The output files */
372 const gchar *signals_filename = "$new_signals_filename";
373 const gchar *hierarchy_filename = "$new_hierarchy_filename";
374 const gchar *interfaces_filename = "$new_interfaces_filename";
375 const gchar *prerequisites_filename = "$new_prerequisites_filename";
376 const gchar *args_filename = "$new_args_filename";
379 static void output_signals (void);
380 static void output_object_signals (FILE *fp,
382 static void output_object_signal (FILE *fp,
383 const gchar *object_class_name,
385 static const gchar * get_type_name (GType type,
386 gboolean * is_pointer);
387 static const gchar * get_gdk_event (const gchar * signal_name);
388 static const gchar ** lookup_signal_arg_names (const gchar * type,
389 const gchar * signal_name);
391 static void output_object_hierarchy (void);
392 static void output_hierarchy (FILE *fp,
396 static void output_object_interfaces (void);
397 static void output_interfaces (FILE *fp,
400 static void output_interface_prerequisites (void);
401 static void output_prerequisites (FILE *fp,
404 static void output_args (void);
405 static void output_object_args (FILE *fp, GType object_type);
408 main (int argc, char *argv[])
410 /* Silence the compiler: */
411 if (argv != argv) argc = argc;
418 output_object_hierarchy ();
419 output_object_interfaces ();
420 output_interface_prerequisites ();
428 output_signals (void)
433 fp = fopen (signals_filename, "w");
436 g_warning ("Couldn't open output file: %s : %s", signals_filename, strerror(errno));
440 for (i = 0; object_types[i]; i++)
441 output_object_signals (fp, object_types[i]);
447 compare_signals (const void *a, const void *b)
449 const guint *signal_a = a;
450 const guint *signal_b = b;
452 return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b));
455 /* This outputs all the signals of one object. */
457 output_object_signals (FILE *fp, GType object_type)
459 const gchar *object_class_name;
460 guint *signals, n_signals;
463 if (G_TYPE_IS_INSTANTIATABLE (object_type) ||
464 G_TYPE_IS_INTERFACE (object_type))
467 object_class_name = g_type_name (object_type);
469 signals = g_signal_list_ids (object_type, &n_signals);
470 qsort (signals, n_signals, sizeof (guint), compare_signals);
472 for (sig = 0; sig < n_signals; sig++)
474 output_object_signal (fp, object_class_name, signals[sig]);
481 /* This outputs one signal. */
483 output_object_signal (FILE *fp,
484 const gchar *object_name,
487 GSignalQuery query_info;
488 const gchar *type_name, *ret_type, *object_arg, *arg_name;
489 gchar *pos, *object_arg_lower;
491 gchar ret_type_buffer[1024], buffer[1024];
493 const gchar **arg_names;
494 gint param_num, widget_num, event_num, callback_num;
496 gchar signal_name[128];
499 /* g_print ("Object: %s Signal: %u\\n", object_name, signal_id);*/
502 widget_num = event_num = callback_num = 0;
504 g_signal_query (signal_id, &query_info);
506 /* Output the return type and function name. */
507 ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
508 sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
510 /* Output the signal object type and the argument name. We assume the
511 type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
512 convert to lower case for the argument name. */
514 sprintf (pos, "%s ", object_name);
517 if (!strncmp (object_name, "Gtk", 3))
518 object_arg = object_name + 3;
519 else if (!strncmp (object_name, "Gnome", 5))
520 object_arg = object_name + 5;
522 object_arg = object_name;
524 object_arg_lower = g_ascii_strdown (object_arg, -1);
525 sprintf (pos, "*%s\\n", object_arg_lower);
527 if (!strncmp (object_arg_lower, "widget", 6))
529 g_free(object_arg_lower);
531 /* Convert signal name to use underscores rather than dashes '-'. */
532 strcpy (signal_name, query_info.signal_name);
533 for (i = 0; signal_name[i]; i++)
535 if (signal_name[i] == '-')
536 signal_name[i] = '_';
539 /* Output the signal parameters. */
540 arg_names = lookup_signal_arg_names (object_name, signal_name);
542 for (param = 0; param < query_info.n_params; param++)
546 sprintf (pos, "%s\\n", arg_names[param]);
551 type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
553 /* Most arguments to the callback are called "arg1", "arg2", etc.
554 GdkWidgets are called "widget", "widget2", ...
555 GdkEvents are called "event", "event2", ...
556 GtkCallbacks are called "callback", "callback2", ... */
557 if (!strcmp (type_name, "GtkWidget"))
560 arg_num = &widget_num;
562 else if (!strcmp (type_name, "GdkEvent"))
564 type_name = get_gdk_event (signal_name);
566 arg_num = &event_num;
569 else if (!strcmp (type_name, "GtkCallback")
570 || !strcmp (type_name, "GtkCCallback"))
572 arg_name = "callback";
573 arg_num = &callback_num;
578 arg_num = ¶m_num;
580 sprintf (pos, "%s ", type_name);
583 if (!arg_num || *arg_num == 0)
584 sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
586 sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
601 /* We use one-character flags for simplicity. */
602 if (query_info.signal_flags & G_SIGNAL_RUN_FIRST)
604 if (query_info.signal_flags & G_SIGNAL_RUN_LAST)
606 if (query_info.signal_flags & G_SIGNAL_RUN_CLEANUP)
608 if (query_info.signal_flags & G_SIGNAL_NO_RECURSE)
610 if (query_info.signal_flags & G_SIGNAL_DETAILED)
612 if (query_info.signal_flags & G_SIGNAL_ACTION)
614 if (query_info.signal_flags & G_SIGNAL_NO_HOOKS)
619 "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n<FLAGS>%s</FLAGS>\\n%s</SIGNAL>\\n\\n",
620 object_name, query_info.signal_name, ret_type_buffer, flags, buffer);
624 /* Returns the type name to use for a signal argument or return value, given
625 the GtkType from the signal info. It also sets is_pointer to TRUE if the
626 argument needs a '*' since it is a pointer. */
628 get_type_name (GType type, gboolean * is_pointer)
630 const gchar *type_name;
633 type_name = g_type_name (type);
647 /* These all have normal C type names so they are OK. */
651 /* A GtkString is really a gchar*. */
657 /* We use a gint for both of these. Hopefully a subtype with a decent
658 name will be registered and used instead, as GTK+ does itself. */
662 /* The boxed type shouldn't be used itself, only subtypes. Though we
663 return 'gpointer' just in case. */
667 /* A GParam is really a GParamSpec*. */
675 /* For all GObject subclasses we can use the class name with a "*",
676 e.g. 'GtkWidget *'. */
677 if (g_type_is_a (type, G_TYPE_OBJECT))
680 if (G_TYPE_IS_CLASSED (type))
683 /* All boxed subtypes will be pointers as well. */
684 if (g_type_is_a (type, G_TYPE_BOXED))
687 /* All pointer subtypes will be pointers as well. */
688 if (g_type_is_a (type, G_TYPE_POINTER))
691 /* But enums are not */
692 if (g_type_is_a (type, G_TYPE_ENUM) ||
693 g_type_is_a (type, G_TYPE_FLAGS))
701 get_gdk_event (const gchar * signal_name)
703 static const gchar *GbGDKEvents[] =
705 "button_press_event", "GdkEventButton",
706 "button_release_event", "GdkEventButton",
707 "motion_notify_event", "GdkEventMotion",
708 "delete_event", "GdkEvent",
709 "destroy_event", "GdkEvent",
710 "expose_event", "GdkEventExpose",
711 "key_press_event", "GdkEventKey",
712 "key_release_event", "GdkEventKey",
713 "enter_notify_event", "GdkEventCrossing",
714 "leave_notify_event", "GdkEventCrossing",
715 "configure_event", "GdkEventConfigure",
716 "focus_in_event", "GdkEventFocus",
717 "focus_out_event", "GdkEventFocus",
718 "map_event", "GdkEvent",
719 "unmap_event", "GdkEvent",
720 "property_notify_event", "GdkEventProperty",
721 "selection_clear_event", "GdkEventSelection",
722 "selection_request_event", "GdkEventSelection",
723 "selection_notify_event", "GdkEventSelection",
724 "proximity_in_event", "GdkEventProximity",
725 "proximity_out_event", "GdkEventProximity",
726 "drag_begin_event", "GdkEventDragBegin",
727 "drag_request_event", "GdkEventDragRequest",
728 "drag_end_event", "GdkEventDragRequest",
729 "drop_enter_event", "GdkEventDropEnter",
730 "drop_leave_event", "GdkEventDropLeave",
731 "drop_data_available_event", "GdkEventDropDataAvailable",
732 "other_event", "GdkEventOther",
733 "client_event", "GdkEventClient",
734 "no_expose_event", "GdkEventNoExpose",
735 "visibility_notify_event", "GdkEventVisibility",
736 "window_state_event", "GdkEventWindowState",
737 "scroll_event", "GdkEventScroll",
743 for (i = 0; GbGDKEvents[i]; i += 2)
745 if (!strcmp (signal_name, GbGDKEvents[i]))
746 return GbGDKEvents[i + 1];
752 /* This returns argument names to use for some known GTK signals.
753 It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
754 'select_row' and it returns a pointer to an array of argument types and
756 static const gchar **
757 lookup_signal_arg_names (const gchar * type, const gchar * signal_name)
759 /* Each arg array starts with the object type name and the signal name,
760 and then signal arguments follow. */
761 static const gchar *GbArgTable[][16] =
763 {"GtkCList", "select_row",
766 "GdkEventButton *event"},
767 {"GtkCList", "unselect_row",
770 "GdkEventButton *event"},
771 {"GtkCList", "click_column",
774 {"GtkCList", "resize_column",
778 {"GtkCList", "extend_selection",
779 "GtkScrollType scroll_type",
781 "gboolean auto_start_selection"},
782 {"GtkCList", "scroll_vertical",
783 "GtkScrollType scroll_type",
785 {"GtkCList", "scroll_horizontal",
786 "GtkScrollType scroll_type",
789 {"GtkCTree", "tree_select_row",
790 "GtkCTreeNode *node",
792 {"GtkCTree", "tree_unselect_row",
793 "GtkCTreeNode *node",
795 {"GtkCTree", "tree_expand",
796 "GtkCTreeNode *node"},
797 {"GtkCTree", "tree_collapse",
798 "GtkCTreeNode *node"},
799 {"GtkCTree", "tree_move",
800 "GtkCTreeNode *node",
801 "GtkCTreeNode *new_parent",
802 "GtkCTreeNode *new_sibling"},
803 {"GtkCTree", "change_focus_row_expansion",
804 "GtkCTreeExpansionType expansion"},
806 {"GtkEditable", "insert_text",
808 "gint new_text_length",
810 {"GtkEditable", "delete_text",
813 {"GtkEditable", "set_editable",
814 "gboolean is_editable"},
815 {"GtkEditable", "move_cursor",
818 {"GtkEditable", "move_word",
820 {"GtkEditable", "move_page",
823 {"GtkEditable", "move_to_row",
825 {"GtkEditable", "move_to_column",
828 {"GtkEditable", "kill_char",
830 {"GtkEditable", "kill_word",
832 {"GtkEditable", "kill_line",
836 {"GtkInputDialog", "enable_device",
837 "GdkDevice *deviceid"},
838 {"GtkInputDialog", "disable_device",
839 "GdkDevice *deviceid"},
841 {"GtkListItem", "extend_selection",
842 "GtkScrollType scroll_type",
844 "gboolean auto_start_selection"},
845 {"GtkListItem", "scroll_vertical",
846 "GtkScrollType scroll_type",
848 {"GtkListItem", "scroll_horizontal",
849 "GtkScrollType scroll_type",
852 {"GtkMenuShell", "move_current",
853 "GtkMenuDirectionType direction"},
854 {"GtkMenuShell", "activate_current",
855 "gboolean force_hide"},
858 {"GtkNotebook", "switch_page",
859 "GtkNotebookPage *page",
861 {"GtkStatusbar", "text_pushed",
864 {"GtkStatusbar", "text_popped",
867 {"GtkTipsQuery", "widget_entered",
870 "gchar *tip_private"},
871 {"GtkTipsQuery", "widget_selected",
874 "gchar *tip_private",
875 "GdkEventButton *event"},
876 {"GtkToolbar", "orientation_changed",
877 "GtkOrientation orientation"},
878 {"GtkToolbar", "style_changed",
879 "GtkToolbarStyle style"},
880 {"GtkWidget", "draw",
881 "GdkRectangle *area"},
882 {"GtkWidget", "size_request",
883 "GtkRequisition *requisition"},
884 {"GtkWidget", "size_allocate",
885 "GtkAllocation *allocation"},
886 {"GtkWidget", "state_changed",
887 "GtkStateType state"},
888 {"GtkWidget", "style_set",
889 "GtkStyle *previous_style"},
891 {"GtkWidget", "install_accelerator",
892 "gchar *signal_name",
896 {"GtkWidget", "add_accelerator",
897 "guint accel_signal_id",
898 "GtkAccelGroup *accel_group",
900 "GdkModifierType accel_mods",
901 "GtkAccelFlags accel_flags"},
903 {"GtkWidget", "parent_set",
904 "GtkObject *old_parent"},
906 {"GtkWidget", "remove_accelerator",
907 "GtkAccelGroup *accel_group",
909 "GdkModifierType accel_mods"},
910 {"GtkWidget", "debug_msg",
912 {"GtkWindow", "move_resize",
917 {"GtkWindow", "set_focus",
918 "GtkWidget *widget"},
920 {"GtkWidget", "selection_get",
921 "GtkSelectionData *data",
924 {"GtkWidget", "selection_received",
925 "GtkSelectionData *data",
928 {"GtkWidget", "drag_begin",
929 "GdkDragContext *drag_context"},
930 {"GtkWidget", "drag_end",
931 "GdkDragContext *drag_context"},
932 {"GtkWidget", "drag_data_delete",
933 "GdkDragContext *drag_context"},
934 {"GtkWidget", "drag_leave",
935 "GdkDragContext *drag_context",
937 {"GtkWidget", "drag_motion",
938 "GdkDragContext *drag_context",
942 {"GtkWidget", "drag_drop",
943 "GdkDragContext *drag_context",
947 {"GtkWidget", "drag_data_get",
948 "GdkDragContext *drag_context",
949 "GtkSelectionData *data",
952 {"GtkWidget", "drag_data_received",
953 "GdkDragContext *drag_context",
956 "GtkSelectionData *data",
965 for (i = 0; GbArgTable[i][0]; i++)
968 if (!strcmp (type, GbArgTable[i][0])
969 && !strcmp (signal_name, GbArgTable[i][1]))
970 return &GbArgTable[i][2];
976 /* This outputs the hierarchy of all objects which have been initialized,
977 i.e. by calling their XXX_get_type() initialization function. */
979 output_object_hierarchy (void)
984 fp = fopen (hierarchy_filename, "w");
987 g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, strerror(errno));
990 output_hierarchy (fp, G_TYPE_OBJECT, 0);
991 output_hierarchy (fp, G_TYPE_INTERFACE, 0);
993 for (i=0; object_types[i]; i++) {
994 if (!g_type_parent (object_types[i]) &&
995 (object_types[i] != G_TYPE_NONE) &&
996 (object_types[i] != G_TYPE_OBJECT) &&
997 (object_types[i] != G_TYPE_INTERFACE)
999 g_warning ("printing hierarchy for root type: %s",
1000 g_type_name (object_types[i]));
1001 output_hierarchy (fp, object_types[i], 0);
1005 for (i=0; object_types[i]; i++) {
1006 if(object_types[i] != G_TYPE_NONE) {
1007 g_print ("type has not been added to hierarchy: %s\\n",
1008 g_type_name (object_types[i]));
1016 /* This is called recursively to output the hierarchy of a widget. */
1018 output_hierarchy (FILE *fp,
1030 for (i=0; object_types[i]; i++) {
1031 if(object_types[i] == type) {
1032 g_print ("added type to hierarchy (level %d): %s\\n",
1033 level, g_type_name (type));
1034 object_types[i] = G_TYPE_NONE;
1040 for (i = 0; i < level; i++)
1042 fprintf (fp, "%s", g_type_name (type));
1043 fprintf (fp, "\\n");
1045 children = g_type_children (type, &n_children);
1047 for (i=0; i < n_children; i++) {
1048 output_hierarchy (fp, children[i], level + 1);
1054 static void output_object_interfaces (void)
1059 fp = fopen (interfaces_filename, "w");
1062 g_warning ("Couldn't open output file: %s : %s", interfaces_filename, strerror(errno));
1065 output_interfaces (fp, G_TYPE_OBJECT);
1067 for (i = 0; object_types[i]; i++)
1069 if (!g_type_parent (object_types[i]) &&
1070 (object_types[i] != G_TYPE_OBJECT) &&
1071 G_TYPE_IS_INSTANTIATABLE (object_types[i]))
1073 output_interfaces (fp, object_types[i]);
1080 output_interfaces (FILE *fp,
1084 GType *children, *interfaces;
1085 guint n_children, n_interfaces;
1090 interfaces = g_type_interfaces (type, &n_interfaces);
1092 if (n_interfaces > 0)
1094 fprintf (fp, "%s", g_type_name (type));
1095 for (i=0; i < n_interfaces; i++)
1096 fprintf (fp, " %s", g_type_name (interfaces[i]));
1097 fprintf (fp, "\\n");
1099 g_free (interfaces);
1101 children = g_type_children (type, &n_children);
1103 for (i=0; i < n_children; i++)
1104 output_interfaces (fp, children[i]);
1109 static void output_interface_prerequisites (void)
1113 fp = fopen (prerequisites_filename, "w");
1116 g_warning ("Couldn't open output file: %s : %s", prerequisites_filename, strerror(errno));
1119 output_prerequisites (fp, G_TYPE_INTERFACE);
1124 output_prerequisites (FILE *fp,
1127 #if GLIB_CHECK_VERSION(2,1,0)
1129 GType *children, *prerequisites;
1130 guint n_children, n_prerequisites;
1135 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
1137 if (n_prerequisites > 0)
1139 fprintf (fp, "%s", g_type_name (type));
1140 for (i=0; i < n_prerequisites; i++)
1141 fprintf (fp, " %s", g_type_name (prerequisites[i]));
1142 fprintf (fp, "\\n");
1144 g_free (prerequisites);
1146 children = g_type_children (type, &n_children);
1148 for (i=0; i < n_children; i++)
1149 output_prerequisites (fp, children[i]);
1161 fp = fopen (args_filename, "w");
1164 g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno));
1168 for (i = 0; object_types[i]; i++) {
1169 output_object_args (fp, object_types[i]);
1176 compare_param_specs (const void *a, const void *b)
1178 GParamSpec *spec_a = *(GParamSpec **)a;
1179 GParamSpec *spec_b = *(GParamSpec **)b;
1181 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
1184 /* Its common to have unsigned properties restricted
1185 * to the signed range. Therefore we make this look
1186 * a bit nicer by spelling out the max constants.
1189 /* Don't use "==" with floats, it might trigger a gcc warning. */
1190 #define GTKDOC_COMPARE_FLOAT(x, y) (x <= y && x >= y)
1193 describe_double_constant (gdouble value)
1197 if (GTKDOC_COMPARE_FLOAT (value, G_MAXDOUBLE))
1198 desc = g_strdup ("G_MAXDOUBLE");
1199 else if (GTKDOC_COMPARE_FLOAT (value, G_MINDOUBLE))
1200 desc = g_strdup ("G_MINDOUBLE");
1201 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXDOUBLE))
1202 desc = g_strdup ("-G_MAXDOUBLE");
1203 else if (GTKDOC_COMPARE_FLOAT (value, G_MAXFLOAT))
1204 desc = g_strdup ("G_MAXFLOAT");
1205 else if (GTKDOC_COMPARE_FLOAT (value, G_MINFLOAT))
1206 desc = g_strdup ("G_MINFLOAT");
1207 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXFLOAT))
1208 desc = g_strdup ("-G_MAXFLOAT");
1210 desc = g_strdup_printf ("%lg", value);
1216 describe_signed_constant (gint64 value)
1220 if (value == G_MAXINT)
1221 desc = g_strdup ("G_MAXINT");
1222 else if (value == G_MININT)
1223 desc = g_strdup ("G_MININT");
1224 else if (value == G_MAXUINT)
1225 desc = g_strdup ("G_MAXUINT");
1226 else if (value == G_MAXLONG)
1227 desc = g_strdup ("G_MAXLONG");
1228 else if (value == G_MINLONG)
1229 desc = g_strdup ("G_MINLONG");
1230 else if (value == G_MAXULONG)
1231 desc = g_strdup ("G_MAXULONG");
1232 else if (value == G_MAXINT64)
1233 desc = g_strdup ("G_MAXINT64");
1234 else if (value == G_MININT64)
1235 desc = g_strdup ("G_MININT64");
1237 desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
1243 describe_unsigned_constant (guint64 value)
1247 if (value == G_MAXINT)
1248 desc = g_strdup ("G_MAXINT");
1249 else if (value == G_MININT)
1250 desc = g_strdup ("G_MININT");
1251 else if (value == G_MAXUINT)
1252 desc = g_strdup ("G_MAXUINT");
1253 else if (value == G_MAXLONG)
1254 desc = g_strdup ("G_MAXLONG");
1255 else if (value == G_MINLONG)
1256 desc = g_strdup ("G_MINLONG");
1257 else if (value == G_MAXULONG)
1258 desc = g_strdup ("G_MAXULONG");
1259 else if (value == G_MAXINT64)
1260 desc = g_strdup ("G_MAXINT64");
1261 else if (value == G_MININT64)
1262 desc = g_strdup ("G_MININT64");
1263 else if (value == G_MAXUINT64)
1264 desc = g_strdup ("G_MAXUINT64");
1266 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
1272 describe_type (GParamSpec *spec)
1278 if (G_IS_PARAM_SPEC_CHAR (spec))
1280 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1282 lower = describe_signed_constant (pspec->minimum);
1283 upper = describe_signed_constant (pspec->maximum);
1284 if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
1285 desc = g_strdup ("");
1286 else if (pspec->minimum == G_MININT8)
1287 desc = g_strdup_printf ("<= %s", upper);
1288 else if (pspec->maximum == G_MAXINT8)
1289 desc = g_strdup_printf (">= %s", lower);
1291 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1295 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1297 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1299 lower = describe_unsigned_constant (pspec->minimum);
1300 upper = describe_unsigned_constant (pspec->maximum);
1301 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
1302 desc = g_strdup ("");
1303 else if (pspec->minimum == 0)
1304 desc = g_strdup_printf ("<= %s", upper);
1305 else if (pspec->maximum == G_MAXUINT8)
1306 desc = g_strdup_printf (">= %s", lower);
1308 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1312 else if (G_IS_PARAM_SPEC_INT (spec))
1314 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1316 lower = describe_signed_constant (pspec->minimum);
1317 upper = describe_signed_constant (pspec->maximum);
1318 if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
1319 desc = g_strdup ("");
1320 else if (pspec->minimum == G_MININT)
1321 desc = g_strdup_printf ("<= %s", upper);
1322 else if (pspec->maximum == G_MAXINT)
1323 desc = g_strdup_printf (">= %s", lower);
1325 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1329 else if (G_IS_PARAM_SPEC_UINT (spec))
1331 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1333 lower = describe_unsigned_constant (pspec->minimum);
1334 upper = describe_unsigned_constant (pspec->maximum);
1335 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
1336 desc = g_strdup ("");
1337 else if (pspec->minimum == 0)
1338 desc = g_strdup_printf ("<= %s", upper);
1339 else if (pspec->maximum == G_MAXUINT)
1340 desc = g_strdup_printf (">= %s", lower);
1342 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1346 else if (G_IS_PARAM_SPEC_LONG (spec))
1348 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1350 lower = describe_signed_constant (pspec->minimum);
1351 upper = describe_signed_constant (pspec->maximum);
1352 if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
1353 desc = g_strdup ("");
1354 else if (pspec->minimum == G_MINLONG)
1355 desc = g_strdup_printf ("<= %s", upper);
1356 else if (pspec->maximum == G_MAXLONG)
1357 desc = g_strdup_printf (">= %s", lower);
1359 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1363 else if (G_IS_PARAM_SPEC_ULONG (spec))
1365 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1368 lower = describe_unsigned_constant (pspec->minimum);
1369 upper = describe_unsigned_constant (pspec->maximum);
1370 if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
1371 desc = g_strdup ("");
1372 else if (pspec->minimum == 0)
1373 desc = g_strdup_printf ("<= %s", upper);
1374 else if (pspec->maximum == G_MAXULONG)
1375 desc = g_strdup_printf (">= %s", lower);
1377 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1381 else if (G_IS_PARAM_SPEC_INT64 (spec))
1383 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1385 lower = describe_signed_constant (pspec->minimum);
1386 upper = describe_signed_constant (pspec->maximum);
1387 if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
1388 desc = g_strdup ("");
1389 else if (pspec->minimum == G_MININT64)
1390 desc = g_strdup_printf ("<= %s", upper);
1391 else if (pspec->maximum == G_MAXINT64)
1392 desc = g_strdup_printf (">= %s", lower);
1394 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1398 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1400 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1402 lower = describe_unsigned_constant (pspec->minimum);
1403 upper = describe_unsigned_constant (pspec->maximum);
1404 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
1405 desc = g_strdup ("");
1406 else if (pspec->minimum == 0)
1407 desc = g_strdup_printf ("<= %s", upper);
1408 else if (pspec->maximum == G_MAXUINT64)
1409 desc = g_strdup_printf (">= %s", lower);
1411 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1415 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1417 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1419 lower = describe_double_constant (pspec->minimum);
1420 upper = describe_double_constant (pspec->maximum);
1421 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXFLOAT))
1423 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1424 desc = g_strdup ("");
1426 desc = g_strdup_printf ("<= %s", upper);
1428 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1429 desc = g_strdup_printf (">= %s", lower);
1431 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1435 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1437 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1439 lower = describe_double_constant (pspec->minimum);
1440 upper = describe_double_constant (pspec->maximum);
1441 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXDOUBLE))
1443 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1444 desc = g_strdup ("");
1446 desc = g_strdup_printf ("<= %s", upper);
1448 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1449 desc = g_strdup_printf (">= %s", lower);
1451 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1457 desc = g_strdup ("");
1464 describe_default (GParamSpec *spec)
1468 if (G_IS_PARAM_SPEC_CHAR (spec))
1470 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1472 desc = g_strdup_printf ("%d", pspec->default_value);
1474 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1476 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1478 desc = g_strdup_printf ("%u", pspec->default_value);
1480 else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
1482 GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
1484 desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
1486 else if (G_IS_PARAM_SPEC_INT (spec))
1488 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1490 desc = g_strdup_printf ("%d", pspec->default_value);
1492 else if (G_IS_PARAM_SPEC_UINT (spec))
1494 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1496 desc = g_strdup_printf ("%u", pspec->default_value);
1498 else if (G_IS_PARAM_SPEC_LONG (spec))
1500 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1502 desc = g_strdup_printf ("%ld", pspec->default_value);
1504 else if (G_IS_PARAM_SPEC_LONG (spec))
1506 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1508 desc = g_strdup_printf ("%lu", pspec->default_value);
1510 else if (G_IS_PARAM_SPEC_INT64 (spec))
1512 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1514 desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
1516 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1518 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1520 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
1522 else if (G_IS_PARAM_SPEC_UNICHAR (spec))
1524 GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
1526 if (g_unichar_isprint (pspec->default_value))
1527 desc = g_strdup_printf ("'%c'", pspec->default_value);
1529 desc = g_strdup_printf ("%u", pspec->default_value);
1531 else if (G_IS_PARAM_SPEC_ENUM (spec))
1533 GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
1535 GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
1537 desc = g_strdup_printf ("%s", value->value_name);
1539 desc = g_strdup_printf ("%d", pspec->default_value);
1541 else if (G_IS_PARAM_SPEC_FLAGS (spec))
1543 GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
1544 guint default_value;
1547 default_value = pspec->default_value;
1548 acc = g_string_new ("");
1550 while (default_value)
1552 GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
1558 g_string_append (acc, "|");
1559 g_string_append (acc, value->value_name);
1561 default_value &= ~value->value;
1564 if (default_value == 0)
1565 desc = g_string_free (acc, FALSE);
1568 desc = g_strdup_printf ("%d", pspec->default_value);
1569 g_string_free (acc, TRUE);
1572 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1574 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1576 desc = g_strdup_printf ("%g", pspec->default_value);
1578 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1580 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1582 desc = g_strdup_printf ("%lg", pspec->default_value);
1584 else if (G_IS_PARAM_SPEC_STRING (spec))
1586 GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
1588 if (pspec->default_value)
1590 gchar *esc = g_strescape (pspec->default_value, NULL);
1592 desc = g_strdup_printf ("\\"%s\\"", esc);
1597 desc = g_strdup_printf ("NULL");
1601 desc = g_strdup ("");
1609 output_object_args (FILE *fp, GType object_type)
1612 const gchar *object_class_name;
1614 gchar flags[16], *pos;
1615 GParamSpec **properties;
1617 gboolean child_prop;
1618 gboolean style_prop;
1619 gboolean is_pointer;
1620 const gchar *type_name;
1622 gchar *default_value;
1624 if (G_TYPE_IS_OBJECT (object_type))
1626 class = g_type_class_peek (object_type);
1630 properties = g_object_class_list_properties (class, &n_properties);
1632 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
1633 else if (G_TYPE_IS_INTERFACE (object_type))
1635 class = g_type_default_interface_ref (object_type);
1640 properties = g_object_interface_list_properties (class, &n_properties);
1646 object_class_name = g_type_name (object_type);
1652 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
1653 for (arg = 0; arg < n_properties; arg++)
1655 GParamSpec *spec = properties[arg];
1656 const gchar *nick, *blurb, *dot;
1658 if (spec->owner_type != object_type)
1662 /* We use one-character flags for simplicity. */
1663 if (child_prop && !style_prop)
1667 if (spec->flags & G_PARAM_READABLE)
1669 if (spec->flags & G_PARAM_WRITABLE)
1671 if (spec->flags & G_PARAM_CONSTRUCT)
1673 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
1677 nick = g_param_spec_get_nick (spec);
1678 blurb = g_param_spec_get_blurb (spec);
1682 int str_len = strlen (blurb);
1683 if (str_len > 0 && blurb[str_len - 1] != '.')
1687 type_desc = describe_type (spec);
1688 default_value = describe_default (spec);
1689 type_name = get_type_name (spec->value_type, &is_pointer);
1690 fprintf (fp, "<ARG>\\n<NAME>%s::%s</NAME>\\n<TYPE>%s%s</TYPE>\\n<RANGE>%s</RANGE>\\n<FLAGS>%s</FLAGS>\\n<NICK>%s</NICK>\\n<BLURB>%s%s</BLURB>\\n<DEFAULT>%s</DEFAULT>\\n</ARG>\\n\\n",
1691 object_class_name, g_param_spec_get_name (spec), type_name, is_pointer ? "*" : "", type_desc, flags, nick ? nick : "(null)", blurb ? blurb : "(null)", dot, default_value);
1693 g_free (default_value);
1696 g_free (properties);
1698 #ifdef GTK_IS_CONTAINER_CLASS
1699 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
1700 properties = gtk_container_class_list_child_properties (class, &n_properties);
1706 #ifdef GTK_IS_WIDGET_CLASS
1707 #if GTK_CHECK_VERSION(2,1,0)
1708 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
1709 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1723 # Compile and run our file
1725 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
1726 $LD = $ENV{LD} ? $ENV{LD} : $CC;
1727 $CFLAGS = $ENV{CFLAGS} ? "$ENV{CFLAGS} -Wall -g" : "-Wall -g";
1728 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
1731 if ($CC =~ /libtool/) {
1732 $o_file = "$MODULE-scan.lo"
1734 $o_file = "$MODULE-scan.o"
1737 print "gtk-doc: Compiling scanner\n";
1738 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c";
1739 system($command) == 0 or die "Compilation of scanner failed: $!\n";
1741 print "gtk-doc: Linking scanner\n";
1742 $command = "$LD -o $MODULE-scan $o_file $LDFLAGS";
1743 system($command) == 0 or die "Linking of scanner failed: $!\n";
1745 print "gtk-doc: Running scanner $MODULE-scan\n";
1746 system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n";
1748 if (!defined($ENV{"GTK_DOC_KEEP_INTERMEDIATE"})) {
1749 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
1752 #&UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
1753 &UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
1754 &UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
1755 &UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
1756 #&UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);