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 static gchar str[1000];
151 const gchar *s1 = data;
181 sprintf(str, "%s<%s>%s</%s>\\n", &indent_str[20-indent], tag, conv, tag);
186 gst_feature_sort_compare (gconstpointer a, gconstpointer b)
188 return strcmp (((GstPluginFeature *)a)->name, ((GstPluginFeature *)b)->name);
192 get_object_types (void)
194 GList *plugins = NULL;
195 GList *factories = NULL;
197 GstElementFactory *factory = NULL;
202 /* get a list of features from plugins in our source module */
203 plugins = gst_registry_get_plugin_list (gst_registry_get_default());
206 GList *features, *pads;
209 FILE *inspect = NULL;
212 plugin = (GstPlugin *) (plugins->data);
213 plugins = g_list_next (plugins);
214 source = gst_plugin_get_source (plugin);
215 /*g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);*/
216 if (!source || strcmp (source, "$SOURCE") != 0) {
219 g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);
221 inspect_name = g_strdup_printf ("$INSPECT_DIR" G_DIR_SEPARATOR_S "plugin-%s.xml",
223 inspect = fopen (inspect_name, "w");
224 g_free (inspect_name);
226 /* output plugin data */
227 fputs ("<plugin>\\n",inspect);
228 fputs (xmlprint(2, "name", plugin->desc.name),inspect);
229 fputs (xmlprint(2, "description", plugin->desc.description),inspect);
230 fputs (xmlprint(2, "filename", plugin->filename),inspect);
231 fputs (xmlprint(2, "basename", plugin->basename),inspect);
232 fputs (xmlprint(2, "version", plugin->desc.version),inspect);
233 fputs (xmlprint(2, "license", plugin->desc.license),inspect);
234 fputs (xmlprint(2, "source", plugin->desc.source),inspect);
235 fputs (xmlprint(2, "package", plugin->desc.package),inspect);
236 fputs (xmlprint(2, "origin", plugin->desc.origin),inspect);
237 fputs (" <elements>\\n", inspect);
240 gst_registry_get_feature_list_by_plugin (gst_registry_get_default (),
243 /* sort factories by feature->name */
244 features = g_list_sort (features, gst_feature_sort_compare);
247 GstPluginFeature *feature;
248 feature = GST_PLUGIN_FEATURE (features->data);
249 feature = gst_plugin_feature_load (feature);
251 g_warning ("Could not load plugin feature %s",
252 gst_plugin_feature_get_name (feature));
255 if (GST_IS_ELEMENT_FACTORY (feature)) {
256 GstStaticPadTemplate *pt;
257 const gchar *pad_dir[] = { "unknown","source","sink" };
258 const gchar *pad_pres[] = { "always","sometimes","request" };
260 factory = GST_ELEMENT_FACTORY (feature);
261 factories = g_list_prepend (factories, factory);
263 /* output element data */
264 fputs (" <element>\\n", inspect);
265 fputs (xmlprint(6, "name", feature->name),inspect);
266 fputs (xmlprint(6, "longname", factory->details.longname),inspect);
267 fputs (xmlprint(6, "class", factory->details.klass),inspect);
268 fputs (xmlprint(6, "description", factory->details.description),inspect);
269 fputs (xmlprint(6, "author", factory->details.author),inspect);
270 fputs (" <pads>\\n", inspect);
272 /* output pad-template data */
273 pads =(GList *) gst_element_factory_get_static_pad_templates (factory);
275 pt = (GstStaticPadTemplate *)pads->data;
277 fputs (" <caps>\\n", inspect);
278 fputs (xmlprint(10, "name", pt->name_template),inspect);
279 fputs (xmlprint(10, "direction", pad_dir[pt->direction]),inspect);
280 fputs (xmlprint(10, "presence", pad_pres[pt->presence]),inspect);
281 fputs (xmlprint(10, "details", pt->static_caps.string),inspect);
282 fputs (" </caps>\\n", inspect);
284 pads = g_list_next (pads);
286 fputs (" </pads>\\n </element>\\n", inspect);
288 features = g_list_next (features);
291 fputs (" </elements>\\n</plugin>\\n", inspect);
295 g_message ("number of element factories: %d", g_list_length (factories));
297 /* allocate the object_types array to hold them */
298 object_types = g_new0 (GType, g_list_length (factories)+$ntypes+1);
305 factory = GST_ELEMENT_FACTORY (l->data);
306 type = gst_element_factory_get_element_type (factory);
308 g_message ("adding type %p for factory %s", (void *) type, gst_element_factory_get_longname (factory));
309 object_types[i++] = type;
311 g_message ("type info for factory %s not found",
312 gst_element_factory_get_longname (factory));
319 # get_type functions:
324 g_message ("$_ () didn't return a valid type");
327 object_types[i++] = type;
332 # Implicit types retrieved from GLib:
335 type = g_type_from_name ("$_");
337 g_message ("Implicit type $_ not found");
340 object_types[i++] = type;
349 /* Need to make sure all the types are loaded in and initialize
350 * their signals and properties.
352 for (i=0; object_types[i]; i++) {
353 if (G_TYPE_IS_CLASSED (object_types[i]))
354 g_type_class_ref (object_types[i]);
356 g_warning ("not reffing type: %s", g_type_name (object_types[i]));
364 * This uses GObject type functions to output signal prototypes and the object
368 /* The output files */
369 const gchar *signals_filename = "$new_signals_filename";
370 const gchar *hierarchy_filename = "$new_hierarchy_filename";
371 const gchar *interfaces_filename = "$new_interfaces_filename";
372 const gchar *prerequisites_filename = "$new_prerequisites_filename";
373 const gchar *args_filename = "$new_args_filename";
376 static void output_signals (void);
377 static void output_object_signals (FILE *fp,
379 static void output_object_signal (FILE *fp,
380 const gchar *object_class_name,
382 static const gchar * get_type_name (GType type,
383 gboolean * is_pointer);
384 static const gchar * get_gdk_event (const gchar * signal_name);
385 static const gchar ** lookup_signal_arg_names (const gchar * type,
386 const gchar * signal_name);
388 static void output_object_hierarchy (void);
389 static void output_hierarchy (FILE *fp,
393 static void output_object_interfaces (void);
394 static void output_interfaces (FILE *fp,
397 static void output_interface_prerequisites (void);
398 static void output_prerequisites (FILE *fp,
401 static void output_args (void);
402 static void output_object_args (FILE *fp, GType object_type);
405 main (int argc, char *argv[])
407 /* Silence the compiler: */
408 if (argv != argv) argc = argc;
415 output_object_hierarchy ();
416 output_object_interfaces ();
417 output_interface_prerequisites ();
425 output_signals (void)
430 fp = fopen (signals_filename, "w");
433 g_warning ("Couldn't open output file: %s : %s", signals_filename, strerror(errno));
437 for (i = 0; object_types[i]; i++)
438 output_object_signals (fp, object_types[i]);
444 compare_signals (const void *a, const void *b)
446 const guint *signal_a = a;
447 const guint *signal_b = b;
449 return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b));
452 /* This outputs all the signals of one object. */
454 output_object_signals (FILE *fp, GType object_type)
456 const gchar *object_class_name;
457 guint *signals, n_signals;
460 if (G_TYPE_IS_INSTANTIATABLE (object_type) ||
461 G_TYPE_IS_INTERFACE (object_type))
464 object_class_name = g_type_name (object_type);
466 signals = g_signal_list_ids (object_type, &n_signals);
467 qsort (signals, n_signals, sizeof (guint), compare_signals);
469 for (sig = 0; sig < n_signals; sig++)
471 output_object_signal (fp, object_class_name, signals[sig]);
478 /* This outputs one signal. */
480 output_object_signal (FILE *fp,
481 const gchar *object_name,
484 GSignalQuery query_info;
485 const gchar *type_name, *ret_type, *object_arg, *arg_name;
486 gchar *pos, *object_arg_lower;
488 gchar ret_type_buffer[1024], buffer[1024];
490 const gchar **arg_names;
491 gint param_num, widget_num, event_num, callback_num;
493 gchar signal_name[128];
496 /* g_print ("Object: %s Signal: %u\\n", object_name, signal_id);*/
499 widget_num = event_num = callback_num = 0;
501 g_signal_query (signal_id, &query_info);
503 /* Output the return type and function name. */
504 ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
505 sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
507 /* Output the signal object type and the argument name. We assume the
508 type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
509 convert to lower case for the argument name. */
511 sprintf (pos, "%s ", object_name);
514 if (!strncmp (object_name, "Gtk", 3))
515 object_arg = object_name + 3;
516 else if (!strncmp (object_name, "Gnome", 5))
517 object_arg = object_name + 5;
519 object_arg = object_name;
521 object_arg_lower = g_ascii_strdown (object_arg, -1);
522 sprintf (pos, "*%s\\n", object_arg_lower);
524 if (!strncmp (object_arg_lower, "widget", 6))
526 g_free(object_arg_lower);
528 /* Convert signal name to use underscores rather than dashes '-'. */
529 strcpy (signal_name, query_info.signal_name);
530 for (i = 0; signal_name[i]; i++)
532 if (signal_name[i] == '-')
533 signal_name[i] = '_';
536 /* Output the signal parameters. */
537 arg_names = lookup_signal_arg_names (object_name, signal_name);
539 for (param = 0; param < query_info.n_params; param++)
543 sprintf (pos, "%s\\n", arg_names[param]);
548 type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
550 /* Most arguments to the callback are called "arg1", "arg2", etc.
551 GdkWidgets are called "widget", "widget2", ...
552 GdkEvents are called "event", "event2", ...
553 GtkCallbacks are called "callback", "callback2", ... */
554 if (!strcmp (type_name, "GtkWidget"))
557 arg_num = &widget_num;
559 else if (!strcmp (type_name, "GdkEvent"))
561 type_name = get_gdk_event (signal_name);
563 arg_num = &event_num;
566 else if (!strcmp (type_name, "GtkCallback")
567 || !strcmp (type_name, "GtkCCallback"))
569 arg_name = "callback";
570 arg_num = &callback_num;
575 arg_num = ¶m_num;
577 sprintf (pos, "%s ", type_name);
580 if (!arg_num || *arg_num == 0)
581 sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
583 sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
598 /* We use one-character flags for simplicity. */
599 if (query_info.signal_flags & G_SIGNAL_RUN_FIRST)
601 if (query_info.signal_flags & G_SIGNAL_RUN_LAST)
603 if (query_info.signal_flags & G_SIGNAL_RUN_CLEANUP)
605 if (query_info.signal_flags & G_SIGNAL_NO_RECURSE)
607 if (query_info.signal_flags & G_SIGNAL_DETAILED)
609 if (query_info.signal_flags & G_SIGNAL_ACTION)
611 if (query_info.signal_flags & G_SIGNAL_NO_HOOKS)
616 "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n<FLAGS>%s</FLAGS>\\n%s</SIGNAL>\\n\\n",
617 object_name, query_info.signal_name, ret_type_buffer, flags, buffer);
621 /* Returns the type name to use for a signal argument or return value, given
622 the GtkType from the signal info. It also sets is_pointer to TRUE if the
623 argument needs a '*' since it is a pointer. */
625 get_type_name (GType type, gboolean * is_pointer)
627 const gchar *type_name;
630 type_name = g_type_name (type);
644 /* These all have normal C type names so they are OK. */
648 /* A GtkString is really a gchar*. */
654 /* We use a gint for both of these. Hopefully a subtype with a decent
655 name will be registered and used instead, as GTK+ does itself. */
659 /* The boxed type shouldn't be used itself, only subtypes. Though we
660 return 'gpointer' just in case. */
664 /* A GParam is really a GParamSpec*. */
672 /* For all GObject subclasses we can use the class name with a "*",
673 e.g. 'GtkWidget *'. */
674 if (g_type_is_a (type, G_TYPE_OBJECT))
677 if (G_TYPE_IS_CLASSED (type))
680 /* All boxed subtypes will be pointers as well. */
681 if (g_type_is_a (type, G_TYPE_BOXED))
684 /* All pointer subtypes will be pointers as well. */
685 if (g_type_is_a (type, G_TYPE_POINTER))
688 /* But enums are not */
689 if (g_type_is_a (type, G_TYPE_ENUM) ||
690 g_type_is_a (type, G_TYPE_FLAGS))
698 get_gdk_event (const gchar * signal_name)
700 static const gchar *GbGDKEvents[] =
702 "button_press_event", "GdkEventButton",
703 "button_release_event", "GdkEventButton",
704 "motion_notify_event", "GdkEventMotion",
705 "delete_event", "GdkEvent",
706 "destroy_event", "GdkEvent",
707 "expose_event", "GdkEventExpose",
708 "key_press_event", "GdkEventKey",
709 "key_release_event", "GdkEventKey",
710 "enter_notify_event", "GdkEventCrossing",
711 "leave_notify_event", "GdkEventCrossing",
712 "configure_event", "GdkEventConfigure",
713 "focus_in_event", "GdkEventFocus",
714 "focus_out_event", "GdkEventFocus",
715 "map_event", "GdkEvent",
716 "unmap_event", "GdkEvent",
717 "property_notify_event", "GdkEventProperty",
718 "selection_clear_event", "GdkEventSelection",
719 "selection_request_event", "GdkEventSelection",
720 "selection_notify_event", "GdkEventSelection",
721 "proximity_in_event", "GdkEventProximity",
722 "proximity_out_event", "GdkEventProximity",
723 "drag_begin_event", "GdkEventDragBegin",
724 "drag_request_event", "GdkEventDragRequest",
725 "drag_end_event", "GdkEventDragRequest",
726 "drop_enter_event", "GdkEventDropEnter",
727 "drop_leave_event", "GdkEventDropLeave",
728 "drop_data_available_event", "GdkEventDropDataAvailable",
729 "other_event", "GdkEventOther",
730 "client_event", "GdkEventClient",
731 "no_expose_event", "GdkEventNoExpose",
732 "visibility_notify_event", "GdkEventVisibility",
733 "window_state_event", "GdkEventWindowState",
734 "scroll_event", "GdkEventScroll",
740 for (i = 0; GbGDKEvents[i]; i += 2)
742 if (!strcmp (signal_name, GbGDKEvents[i]))
743 return GbGDKEvents[i + 1];
749 /* This returns argument names to use for some known GTK signals.
750 It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
751 'select_row' and it returns a pointer to an array of argument types and
753 static const gchar **
754 lookup_signal_arg_names (const gchar * type, const gchar * signal_name)
756 /* Each arg array starts with the object type name and the signal name,
757 and then signal arguments follow. */
758 static const gchar *GbArgTable[][16] =
760 {"GtkCList", "select_row",
763 "GdkEventButton *event"},
764 {"GtkCList", "unselect_row",
767 "GdkEventButton *event"},
768 {"GtkCList", "click_column",
771 {"GtkCList", "resize_column",
775 {"GtkCList", "extend_selection",
776 "GtkScrollType scroll_type",
778 "gboolean auto_start_selection"},
779 {"GtkCList", "scroll_vertical",
780 "GtkScrollType scroll_type",
782 {"GtkCList", "scroll_horizontal",
783 "GtkScrollType scroll_type",
786 {"GtkCTree", "tree_select_row",
787 "GtkCTreeNode *node",
789 {"GtkCTree", "tree_unselect_row",
790 "GtkCTreeNode *node",
792 {"GtkCTree", "tree_expand",
793 "GtkCTreeNode *node"},
794 {"GtkCTree", "tree_collapse",
795 "GtkCTreeNode *node"},
796 {"GtkCTree", "tree_move",
797 "GtkCTreeNode *node",
798 "GtkCTreeNode *new_parent",
799 "GtkCTreeNode *new_sibling"},
800 {"GtkCTree", "change_focus_row_expansion",
801 "GtkCTreeExpansionType expansion"},
803 {"GtkEditable", "insert_text",
805 "gint new_text_length",
807 {"GtkEditable", "delete_text",
810 {"GtkEditable", "set_editable",
811 "gboolean is_editable"},
812 {"GtkEditable", "move_cursor",
815 {"GtkEditable", "move_word",
817 {"GtkEditable", "move_page",
820 {"GtkEditable", "move_to_row",
822 {"GtkEditable", "move_to_column",
825 {"GtkEditable", "kill_char",
827 {"GtkEditable", "kill_word",
829 {"GtkEditable", "kill_line",
833 {"GtkInputDialog", "enable_device",
834 "GdkDevice *deviceid"},
835 {"GtkInputDialog", "disable_device",
836 "GdkDevice *deviceid"},
838 {"GtkListItem", "extend_selection",
839 "GtkScrollType scroll_type",
841 "gboolean auto_start_selection"},
842 {"GtkListItem", "scroll_vertical",
843 "GtkScrollType scroll_type",
845 {"GtkListItem", "scroll_horizontal",
846 "GtkScrollType scroll_type",
849 {"GtkMenuShell", "move_current",
850 "GtkMenuDirectionType direction"},
851 {"GtkMenuShell", "activate_current",
852 "gboolean force_hide"},
855 {"GtkNotebook", "switch_page",
856 "GtkNotebookPage *page",
858 {"GtkStatusbar", "text_pushed",
861 {"GtkStatusbar", "text_popped",
864 {"GtkTipsQuery", "widget_entered",
867 "gchar *tip_private"},
868 {"GtkTipsQuery", "widget_selected",
871 "gchar *tip_private",
872 "GdkEventButton *event"},
873 {"GtkToolbar", "orientation_changed",
874 "GtkOrientation orientation"},
875 {"GtkToolbar", "style_changed",
876 "GtkToolbarStyle style"},
877 {"GtkWidget", "draw",
878 "GdkRectangle *area"},
879 {"GtkWidget", "size_request",
880 "GtkRequisition *requisition"},
881 {"GtkWidget", "size_allocate",
882 "GtkAllocation *allocation"},
883 {"GtkWidget", "state_changed",
884 "GtkStateType state"},
885 {"GtkWidget", "style_set",
886 "GtkStyle *previous_style"},
888 {"GtkWidget", "install_accelerator",
889 "gchar *signal_name",
893 {"GtkWidget", "add_accelerator",
894 "guint accel_signal_id",
895 "GtkAccelGroup *accel_group",
897 "GdkModifierType accel_mods",
898 "GtkAccelFlags accel_flags"},
900 {"GtkWidget", "parent_set",
901 "GtkObject *old_parent"},
903 {"GtkWidget", "remove_accelerator",
904 "GtkAccelGroup *accel_group",
906 "GdkModifierType accel_mods"},
907 {"GtkWidget", "debug_msg",
909 {"GtkWindow", "move_resize",
914 {"GtkWindow", "set_focus",
915 "GtkWidget *widget"},
917 {"GtkWidget", "selection_get",
918 "GtkSelectionData *data",
921 {"GtkWidget", "selection_received",
922 "GtkSelectionData *data",
925 {"GtkWidget", "drag_begin",
926 "GdkDragContext *drag_context"},
927 {"GtkWidget", "drag_end",
928 "GdkDragContext *drag_context"},
929 {"GtkWidget", "drag_data_delete",
930 "GdkDragContext *drag_context"},
931 {"GtkWidget", "drag_leave",
932 "GdkDragContext *drag_context",
934 {"GtkWidget", "drag_motion",
935 "GdkDragContext *drag_context",
939 {"GtkWidget", "drag_drop",
940 "GdkDragContext *drag_context",
944 {"GtkWidget", "drag_data_get",
945 "GdkDragContext *drag_context",
946 "GtkSelectionData *data",
949 {"GtkWidget", "drag_data_received",
950 "GdkDragContext *drag_context",
953 "GtkSelectionData *data",
962 for (i = 0; GbArgTable[i][0]; i++)
965 if (!strcmp (type, GbArgTable[i][0])
966 && !strcmp (signal_name, GbArgTable[i][1]))
967 return &GbArgTable[i][2];
973 /* This outputs the hierarchy of all objects which have been initialized,
974 i.e. by calling their XXX_get_type() initialization function. */
976 output_object_hierarchy (void)
981 fp = fopen (hierarchy_filename, "w");
984 g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, strerror(errno));
987 output_hierarchy (fp, G_TYPE_OBJECT, 0);
988 output_hierarchy (fp, G_TYPE_INTERFACE, 0);
990 for (i=0; object_types[i]; i++) {
991 if (!g_type_parent (object_types[i]) &&
992 (object_types[i] != G_TYPE_NONE) &&
993 (object_types[i] != G_TYPE_OBJECT) &&
994 (object_types[i] != G_TYPE_INTERFACE)
996 g_warning ("printing hierarchy for root type: %s",
997 g_type_name (object_types[i]));
998 output_hierarchy (fp, object_types[i], 0);
1002 for (i=0; object_types[i]; i++) {
1003 if(object_types[i] != G_TYPE_NONE) {
1004 g_print ("type has not been added to hierarchy: %s\\n",
1005 g_type_name (object_types[i]));
1013 /* This is called recursively to output the hierarchy of a widget. */
1015 output_hierarchy (FILE *fp,
1027 for (i=0; object_types[i]; i++) {
1028 if(object_types[i] == type) {
1029 g_print ("added type to hierarchy (level %d): %s\\n",
1030 level, g_type_name (type));
1031 object_types[i] = G_TYPE_NONE;
1037 for (i = 0; i < level; i++)
1039 fprintf (fp, "%s", g_type_name (type));
1040 fprintf (fp, "\\n");
1042 children = g_type_children (type, &n_children);
1044 for (i=0; i < n_children; i++) {
1045 output_hierarchy (fp, children[i], level + 1);
1051 static void output_object_interfaces (void)
1056 fp = fopen (interfaces_filename, "w");
1059 g_warning ("Couldn't open output file: %s : %s", interfaces_filename, strerror(errno));
1062 output_interfaces (fp, G_TYPE_OBJECT);
1064 for (i = 0; object_types[i]; i++)
1066 if (!g_type_parent (object_types[i]) &&
1067 (object_types[i] != G_TYPE_OBJECT) &&
1068 G_TYPE_IS_INSTANTIATABLE (object_types[i]))
1070 output_interfaces (fp, object_types[i]);
1077 output_interfaces (FILE *fp,
1081 GType *children, *interfaces;
1082 guint n_children, n_interfaces;
1087 interfaces = g_type_interfaces (type, &n_interfaces);
1089 if (n_interfaces > 0)
1091 fprintf (fp, "%s", g_type_name (type));
1092 for (i=0; i < n_interfaces; i++)
1093 fprintf (fp, " %s", g_type_name (interfaces[i]));
1094 fprintf (fp, "\\n");
1096 g_free (interfaces);
1098 children = g_type_children (type, &n_children);
1100 for (i=0; i < n_children; i++)
1101 output_interfaces (fp, children[i]);
1106 static void output_interface_prerequisites (void)
1110 fp = fopen (prerequisites_filename, "w");
1113 g_warning ("Couldn't open output file: %s : %s", prerequisites_filename, strerror(errno));
1116 output_prerequisites (fp, G_TYPE_INTERFACE);
1121 output_prerequisites (FILE *fp,
1124 #if GLIB_CHECK_VERSION(2,1,0)
1126 GType *children, *prerequisites;
1127 guint n_children, n_prerequisites;
1132 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
1134 if (n_prerequisites > 0)
1136 fprintf (fp, "%s", g_type_name (type));
1137 for (i=0; i < n_prerequisites; i++)
1138 fprintf (fp, " %s", g_type_name (prerequisites[i]));
1139 fprintf (fp, "\\n");
1141 g_free (prerequisites);
1143 children = g_type_children (type, &n_children);
1145 for (i=0; i < n_children; i++)
1146 output_prerequisites (fp, children[i]);
1158 fp = fopen (args_filename, "w");
1161 g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno));
1165 for (i = 0; object_types[i]; i++) {
1166 output_object_args (fp, object_types[i]);
1173 compare_param_specs (const void *a, const void *b)
1175 GParamSpec *spec_a = *(GParamSpec **)a;
1176 GParamSpec *spec_b = *(GParamSpec **)b;
1178 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
1181 /* Its common to have unsigned properties restricted
1182 * to the signed range. Therefore we make this look
1183 * a bit nicer by spelling out the max constants.
1186 /* Don't use "==" with floats, it might trigger a gcc warning. */
1187 #define GTKDOC_COMPARE_FLOAT(x, y) (x <= y && x >= y)
1190 describe_double_constant (gdouble value)
1194 if (GTKDOC_COMPARE_FLOAT (value, G_MAXDOUBLE))
1195 desc = g_strdup ("G_MAXDOUBLE");
1196 else if (GTKDOC_COMPARE_FLOAT (value, G_MINDOUBLE))
1197 desc = g_strdup ("G_MINDOUBLE");
1198 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXDOUBLE))
1199 desc = g_strdup ("-G_MAXDOUBLE");
1200 else if (GTKDOC_COMPARE_FLOAT (value, G_MAXFLOAT))
1201 desc = g_strdup ("G_MAXFLOAT");
1202 else if (GTKDOC_COMPARE_FLOAT (value, G_MINFLOAT))
1203 desc = g_strdup ("G_MINFLOAT");
1204 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXFLOAT))
1205 desc = g_strdup ("-G_MAXFLOAT");
1207 desc = g_strdup_printf ("%lg", value);
1213 describe_signed_constant (gint64 value)
1217 if (value == G_MAXINT)
1218 desc = g_strdup ("G_MAXINT");
1219 else if (value == G_MININT)
1220 desc = g_strdup ("G_MININT");
1221 else if (value == G_MAXUINT)
1222 desc = g_strdup ("G_MAXUINT");
1223 else if (value == G_MAXLONG)
1224 desc = g_strdup ("G_MAXLONG");
1225 else if (value == G_MINLONG)
1226 desc = g_strdup ("G_MINLONG");
1227 else if (value == G_MAXULONG)
1228 desc = g_strdup ("G_MAXULONG");
1229 else if (value == G_MAXINT64)
1230 desc = g_strdup ("G_MAXINT64");
1231 else if (value == G_MININT64)
1232 desc = g_strdup ("G_MININT64");
1234 desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
1240 describe_unsigned_constant (guint64 value)
1244 if (value == G_MAXINT)
1245 desc = g_strdup ("G_MAXINT");
1246 else if (value == G_MININT)
1247 desc = g_strdup ("G_MININT");
1248 else if (value == G_MAXUINT)
1249 desc = g_strdup ("G_MAXUINT");
1250 else if (value == G_MAXLONG)
1251 desc = g_strdup ("G_MAXLONG");
1252 else if (value == G_MINLONG)
1253 desc = g_strdup ("G_MINLONG");
1254 else if (value == G_MAXULONG)
1255 desc = g_strdup ("G_MAXULONG");
1256 else if (value == G_MAXINT64)
1257 desc = g_strdup ("G_MAXINT64");
1258 else if (value == G_MININT64)
1259 desc = g_strdup ("G_MININT64");
1260 else if (value == G_MAXUINT64)
1261 desc = g_strdup ("G_MAXUINT64");
1263 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
1269 describe_type (GParamSpec *spec)
1275 if (G_IS_PARAM_SPEC_CHAR (spec))
1277 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1279 lower = describe_signed_constant (pspec->minimum);
1280 upper = describe_signed_constant (pspec->maximum);
1281 if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
1282 desc = g_strdup ("");
1283 else if (pspec->minimum == G_MININT8)
1284 desc = g_strdup_printf ("<= %s", upper);
1285 else if (pspec->maximum == G_MAXINT8)
1286 desc = g_strdup_printf (">= %s", lower);
1288 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1292 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1294 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1296 lower = describe_unsigned_constant (pspec->minimum);
1297 upper = describe_unsigned_constant (pspec->maximum);
1298 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
1299 desc = g_strdup ("");
1300 else if (pspec->minimum == 0)
1301 desc = g_strdup_printf ("<= %s", upper);
1302 else if (pspec->maximum == G_MAXUINT8)
1303 desc = g_strdup_printf (">= %s", lower);
1305 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1309 else if (G_IS_PARAM_SPEC_INT (spec))
1311 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1313 lower = describe_signed_constant (pspec->minimum);
1314 upper = describe_signed_constant (pspec->maximum);
1315 if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
1316 desc = g_strdup ("");
1317 else if (pspec->minimum == G_MININT)
1318 desc = g_strdup_printf ("<= %s", upper);
1319 else if (pspec->maximum == G_MAXINT)
1320 desc = g_strdup_printf (">= %s", lower);
1322 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1326 else if (G_IS_PARAM_SPEC_UINT (spec))
1328 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1330 lower = describe_unsigned_constant (pspec->minimum);
1331 upper = describe_unsigned_constant (pspec->maximum);
1332 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
1333 desc = g_strdup ("");
1334 else if (pspec->minimum == 0)
1335 desc = g_strdup_printf ("<= %s", upper);
1336 else if (pspec->maximum == G_MAXUINT)
1337 desc = g_strdup_printf (">= %s", lower);
1339 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1343 else if (G_IS_PARAM_SPEC_LONG (spec))
1345 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1347 lower = describe_signed_constant (pspec->minimum);
1348 upper = describe_signed_constant (pspec->maximum);
1349 if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
1350 desc = g_strdup ("");
1351 else if (pspec->minimum == G_MINLONG)
1352 desc = g_strdup_printf ("<= %s", upper);
1353 else if (pspec->maximum == G_MAXLONG)
1354 desc = g_strdup_printf (">= %s", lower);
1356 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1360 else if (G_IS_PARAM_SPEC_ULONG (spec))
1362 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1365 lower = describe_unsigned_constant (pspec->minimum);
1366 upper = describe_unsigned_constant (pspec->maximum);
1367 if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
1368 desc = g_strdup ("");
1369 else if (pspec->minimum == 0)
1370 desc = g_strdup_printf ("<= %s", upper);
1371 else if (pspec->maximum == G_MAXULONG)
1372 desc = g_strdup_printf (">= %s", lower);
1374 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1378 else if (G_IS_PARAM_SPEC_INT64 (spec))
1380 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1382 lower = describe_signed_constant (pspec->minimum);
1383 upper = describe_signed_constant (pspec->maximum);
1384 if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
1385 desc = g_strdup ("");
1386 else if (pspec->minimum == G_MININT64)
1387 desc = g_strdup_printf ("<= %s", upper);
1388 else if (pspec->maximum == G_MAXINT64)
1389 desc = g_strdup_printf (">= %s", lower);
1391 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1395 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1397 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1399 lower = describe_unsigned_constant (pspec->minimum);
1400 upper = describe_unsigned_constant (pspec->maximum);
1401 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
1402 desc = g_strdup ("");
1403 else if (pspec->minimum == 0)
1404 desc = g_strdup_printf ("<= %s", upper);
1405 else if (pspec->maximum == G_MAXUINT64)
1406 desc = g_strdup_printf (">= %s", lower);
1408 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1412 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1414 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1416 lower = describe_double_constant (pspec->minimum);
1417 upper = describe_double_constant (pspec->maximum);
1418 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXFLOAT))
1420 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1421 desc = g_strdup ("");
1423 desc = g_strdup_printf ("<= %s", upper);
1425 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1426 desc = g_strdup_printf (">= %s", lower);
1428 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1432 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1434 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1436 lower = describe_double_constant (pspec->minimum);
1437 upper = describe_double_constant (pspec->maximum);
1438 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXDOUBLE))
1440 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1441 desc = g_strdup ("");
1443 desc = g_strdup_printf ("<= %s", upper);
1445 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1446 desc = g_strdup_printf (">= %s", lower);
1448 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1454 desc = g_strdup ("");
1461 describe_default (GParamSpec *spec)
1465 if (G_IS_PARAM_SPEC_CHAR (spec))
1467 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1469 desc = g_strdup_printf ("%d", pspec->default_value);
1471 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1473 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1475 desc = g_strdup_printf ("%u", pspec->default_value);
1477 else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
1479 GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
1481 desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
1483 else if (G_IS_PARAM_SPEC_INT (spec))
1485 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1487 desc = g_strdup_printf ("%d", pspec->default_value);
1489 else if (G_IS_PARAM_SPEC_UINT (spec))
1491 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1493 desc = g_strdup_printf ("%u", pspec->default_value);
1495 else if (G_IS_PARAM_SPEC_LONG (spec))
1497 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1499 desc = g_strdup_printf ("%ld", pspec->default_value);
1501 else if (G_IS_PARAM_SPEC_LONG (spec))
1503 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1505 desc = g_strdup_printf ("%lu", pspec->default_value);
1507 else if (G_IS_PARAM_SPEC_INT64 (spec))
1509 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1511 desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
1513 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1515 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1517 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
1519 else if (G_IS_PARAM_SPEC_UNICHAR (spec))
1521 GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
1523 if (g_unichar_isprint (pspec->default_value))
1524 desc = g_strdup_printf ("'%c'", pspec->default_value);
1526 desc = g_strdup_printf ("%u", pspec->default_value);
1528 else if (G_IS_PARAM_SPEC_ENUM (spec))
1530 GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
1532 GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
1534 desc = g_strdup_printf ("%s", value->value_name);
1536 desc = g_strdup_printf ("%d", pspec->default_value);
1538 else if (G_IS_PARAM_SPEC_FLAGS (spec))
1540 GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
1541 guint default_value;
1544 default_value = pspec->default_value;
1545 acc = g_string_new ("");
1547 while (default_value)
1549 GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
1555 g_string_append (acc, "|");
1556 g_string_append (acc, value->value_name);
1558 default_value &= ~value->value;
1561 if (default_value == 0)
1562 desc = g_string_free (acc, FALSE);
1565 desc = g_strdup_printf ("%d", pspec->default_value);
1566 g_string_free (acc, TRUE);
1569 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1571 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1573 desc = g_strdup_printf ("%g", pspec->default_value);
1575 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1577 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1579 desc = g_strdup_printf ("%lg", pspec->default_value);
1581 else if (G_IS_PARAM_SPEC_STRING (spec))
1583 GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
1585 if (pspec->default_value)
1587 gchar *esc = g_strescape (pspec->default_value, NULL);
1589 desc = g_strdup_printf ("\\"%s\\"", esc);
1594 desc = g_strdup_printf ("NULL");
1598 desc = g_strdup ("");
1606 output_object_args (FILE *fp, GType object_type)
1609 const gchar *object_class_name;
1611 gchar flags[16], *pos;
1612 GParamSpec **properties;
1614 gboolean child_prop;
1615 gboolean style_prop;
1616 gboolean is_pointer;
1617 const gchar *type_name;
1619 gchar *default_value;
1621 if (G_TYPE_IS_OBJECT (object_type))
1623 class = g_type_class_peek (object_type);
1627 properties = g_object_class_list_properties (class, &n_properties);
1629 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
1630 else if (G_TYPE_IS_INTERFACE (object_type))
1632 class = g_type_default_interface_ref (object_type);
1637 properties = g_object_interface_list_properties (class, &n_properties);
1643 object_class_name = g_type_name (object_type);
1649 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
1650 for (arg = 0; arg < n_properties; arg++)
1652 GParamSpec *spec = properties[arg];
1653 const gchar *nick, *blurb, *dot;
1655 if (spec->owner_type != object_type)
1659 /* We use one-character flags for simplicity. */
1660 if (child_prop && !style_prop)
1664 if (spec->flags & G_PARAM_READABLE)
1666 if (spec->flags & G_PARAM_WRITABLE)
1668 if (spec->flags & G_PARAM_CONSTRUCT)
1670 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
1674 nick = g_param_spec_get_nick (spec);
1675 blurb = g_param_spec_get_blurb (spec);
1679 int str_len = strlen (blurb);
1680 if (str_len > 0 && blurb[str_len - 1] != '.')
1684 type_desc = describe_type (spec);
1685 default_value = describe_default (spec);
1686 type_name = get_type_name (spec->value_type, &is_pointer);
1687 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",
1688 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);
1690 g_free (default_value);
1693 g_free (properties);
1695 #ifdef GTK_IS_CONTAINER_CLASS
1696 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
1697 properties = gtk_container_class_list_child_properties (class, &n_properties);
1703 #ifdef GTK_IS_WIDGET_CLASS
1704 #if GTK_CHECK_VERSION(2,1,0)
1705 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
1706 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1720 # Compile and run our file
1722 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
1723 $LD = $ENV{LD} ? $ENV{LD} : $CC;
1724 $CFLAGS = $ENV{CFLAGS} ? "$ENV{CFLAGS} -Wall -g" : "-Wall -g";
1725 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
1728 if ($CC =~ /libtool/) {
1729 $o_file = "$MODULE-scan.lo"
1731 $o_file = "$MODULE-scan.o"
1734 print "gtk-doc: Compiling scanner\n";
1735 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c";
1736 system($command) == 0 or die "Compilation of scanner failed: $!\n";
1738 print "gtk-doc: Linking scanner\n";
1739 $command = "$LD -o $MODULE-scan $o_file $LDFLAGS";
1740 system($command) == 0 or die "Linking of scanner failed: $!\n";
1742 print "gtk-doc: Running scanner $MODULE-scan\n";
1743 system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n";
1745 if (!defined($ENV{"GTK_DOC_KEEP_INTERMEDIATE"})) {
1746 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
1749 #&UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
1750 &UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
1751 &UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
1752 &UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
1753 #&UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);