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 my $GTK_DOC_PREFIX=`pkg-config --variable prefix gtk-doc`;
34 if ($GTK_DOC_PREFIX) {
35 chomp $GTK_DOC_PREFIX;
36 #print "Adding $GTK_DOC_PREFIX/share/gtk-doc/data to \@INC\n";
37 unshift @INC, "$GTK_DOC_PREFIX/share/gtk-doc/data";
39 unshift @INC, '/usr/share/gtk-doc/data';
41 require "gtkdoc-common.pl";
45 # name of documentation module
51 my $TYPE_INIT_FUNC="g_type_init ()";
53 # --nogtkinit is deprecated, as it is the default now anyway.
54 %optctl = (module => \$MODULE,
56 types => \$TYPES_FILE,
57 nogtkinit => \$NO_GTK_INIT,
58 'type-init-func' => \$TYPE_INIT_FUNC,
59 'output-dir' => \$OUTPUT_DIR,
60 'inspect-dir' => \$INSPECT_DIR,
61 'version' => \$PRINT_VERSION,
62 'help' => \$PRINT_HELP);
64 GetOptions(\%optctl, "module=s", "source=s", "types:s", "output-dir:s", "inspect-dir:s", "nogtkinit", "type-init-func:s", "version", "help");
67 # Do nothing. This just avoids a warning.
80 print "gstdoc-scangobj version 1.5\n";
81 print "\n--module=MODULE_NAME Name of the doc module being parsed";
82 print "\n--source=SOURCE_NAME Name of the source module for plugins";
83 print "\n--types=FILE The name of the file to store the types in";
84 print "\n--type-init-func=FUNC The init function to call instead of g_type_init ()";
85 print "\n--output-dir=DIRNAME The directory where the results are stored";
86 print "\n--inspect-dir=DIRNAME The directory where the plugin inspect data is stored";
87 print "\n--version Print the version of this program";
88 print "\n--help Print this help\n";
92 $OUTPUT_DIR = $OUTPUT_DIR ? $OUTPUT_DIR : ".";
94 $TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$OUTPUT_DIR/$MODULE.types";
96 open (TYPES, $TYPES_FILE) || die "Cannot open $TYPES_FILE: $!\n";
97 open (OUTPUT, ">$MODULE-scan.c") || die "Cannot open $MODULE-scan.c: $!\n";
99 my $old_signals_filename = "$OUTPUT_DIR/$MODULE.signals";
100 my $new_signals_filename = "$OUTPUT_DIR/$MODULE.signals.new";
101 my $old_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy";
102 my $new_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy.new";
103 my $old_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces";
104 my $new_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces.new";
105 my $old_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites";
106 my $new_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites.new";
107 my $old_args_filename = "$OUTPUT_DIR/$MODULE.args";
108 my $new_args_filename = "$OUTPUT_DIR/$MODULE.args.new";
110 # write a C program to scan the types
123 } elsif (/^type:(.*)$/) {
126 push @impl_types, $t;
133 $ntypes = @types + @impl_types;
143 #ifdef GTK_IS_WIDGET_CLASS
144 #include <gtk/gtkversion.h>
147 static GType *object_types = NULL;
149 static GString *xmlstr = NULL;
152 xmlprint (gint indent, const gchar *tag, const gchar *data)
154 const gchar indent_str[] = " ";
157 g_string_truncate (xmlstr, 0);
158 g_string_append_len (xmlstr, indent_str, MIN (indent, strlen (indent_str)));
159 g_string_append_printf (xmlstr, "<%s>", tag);
164 s = g_markup_escape_text (data, -1);
165 g_string_append (xmlstr, s);
169 g_string_append_printf (xmlstr, "</%s>\\n", tag);
174 gst_feature_sort_compare (gconstpointer a, gconstpointer b)
176 return strcmp (((GstPluginFeature *)a)->name, ((GstPluginFeature *)b)->name);
180 static_pad_template_compare (gconstpointer a, gconstpointer b)
182 GstStaticPadTemplate *spt_a = (GstStaticPadTemplate *) a;
183 GstStaticPadTemplate *spt_b = (GstStaticPadTemplate *) b;
185 /* we want SINK before SRC (enum is UNKNOWN, SRC, SINK) */
186 if (spt_a->direction != spt_b->direction)
187 return spt_b->direction - spt_a->direction;
189 /* we want ALWAYS first, SOMETIMES second, REQUEST last
190 * (enum is ALWAYS, SOMETIMES, REQUEST) */
191 if (spt_a->presence != spt_b->presence)
192 return spt_a->presence - spt_b->presence;
194 return strcmp (spt_a->name_template, spt_b->name_template);
198 get_object_types (void)
200 GList *plugins = NULL;
201 GList *factories = NULL;
203 GstElementFactory *factory = NULL;
208 /* get a list of features from plugins in our source module */
209 plugins = gst_registry_get_plugin_list (gst_registry_get_default());
211 xmlstr = g_string_new ("");
213 reinspect = !g_file_test ("scanobj-build.stamp", G_FILE_TEST_EXISTS);
219 FILE *inspect = NULL;
222 plugin = (GstPlugin *) (plugins->data);
223 plugins = g_list_next (plugins);
224 source = gst_plugin_get_source (plugin);
225 /*g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);*/
226 if (!source || strcmp (source, "$SOURCE") != 0) {
230 /* skip static coreelements plugin with pipeline and bin element factory */
231 if (gst_plugin_get_filename (plugin) == NULL)
234 g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);
237 inspect_name = g_strdup_printf ("$INSPECT_DIR" G_DIR_SEPARATOR_S "plugin-%s.xml",
239 inspect = fopen (inspect_name, "w");
240 if (inspect == NULL) {
241 g_error ("Could not open %s for writing: %s\\n", inspect_name,
244 g_free (inspect_name);
246 /* output plugin data */
247 fputs ("<plugin>\\n",inspect);
248 fputs (xmlprint(2, "name", plugin->desc.name),inspect);
249 fputs (xmlprint(2, "description", plugin->desc.description),inspect);
250 fputs (xmlprint(2, "filename", plugin->filename),inspect);
251 fputs (xmlprint(2, "basename", plugin->basename),inspect);
252 fputs (xmlprint(2, "version", plugin->desc.version),inspect);
253 fputs (xmlprint(2, "license", plugin->desc.license),inspect);
254 fputs (xmlprint(2, "source", plugin->desc.source),inspect);
255 fputs (xmlprint(2, "package", plugin->desc.package),inspect);
256 fputs (xmlprint(2, "origin", plugin->desc.origin),inspect);
257 fputs (" <elements>\\n", inspect);
261 gst_registry_get_feature_list_by_plugin (gst_registry_get_default (),
264 /* sort factories by feature->name */
265 features = g_list_sort (features, gst_feature_sort_compare);
268 GstPluginFeature *feature;
269 feature = GST_PLUGIN_FEATURE (features->data);
270 feature = gst_plugin_feature_load (feature);
272 g_warning ("Could not load plugin feature %s",
273 gst_plugin_feature_get_name (feature));
276 if (GST_IS_ELEMENT_FACTORY (feature)) {
277 const gchar *pad_dir[] = { "unknown","source","sink" };
278 const gchar *pad_pres[] = { "always","sometimes","request" };
281 /*g_print (" feature: %s\\n", feature->name);*/
283 factory = GST_ELEMENT_FACTORY (feature);
284 factories = g_list_prepend (factories, factory);
287 /* output element data */
288 fputs (" <element>\\n", inspect);
289 fputs (xmlprint(6, "name", feature->name),inspect);
290 fputs (xmlprint(6, "longname", gst_element_factory_get_longname (factory)),inspect);
291 fputs (xmlprint(6, "class", gst_element_factory_get_klass (factory)),inspect);
292 fputs (xmlprint(6, "description", gst_element_factory_get_description (factory)),inspect);
293 fputs (xmlprint(6, "author", gst_element_factory_get_author (factory)),inspect);
294 fputs (" <pads>\\n", inspect);
296 /* output pad-template data */
297 pads = g_list_copy ((GList *) gst_element_factory_get_static_pad_templates (factory));
298 pads = g_list_sort (pads, static_pad_template_compare);
299 for (pad = pads; pad != NULL; pad = pad->next) {
300 GstStaticPadTemplate *pt = pad->data;
302 fputs (" <caps>\\n", inspect);
303 fputs (xmlprint(10, "name", pt->name_template),inspect);
304 fputs (xmlprint(10, "direction", pad_dir[pt->direction]),inspect);
305 fputs (xmlprint(10, "presence", pad_pres[pt->presence]),inspect);
306 fputs (xmlprint(10, "details", pt->static_caps.string),inspect);
307 fputs (" </caps>\\n", inspect);
310 fputs (" </pads>\\n </element>\\n", inspect);
313 features = g_list_next (features);
317 fputs (" </elements>\\n</plugin>", inspect);
322 g_string_free (xmlstr, TRUE);
324 g_message ("number of element factories: %d", g_list_length (factories));
326 /* allocate the object_types array to hold them */
327 object_types = g_new0 (GType, g_list_length (factories)+$ntypes+1);
334 factory = GST_ELEMENT_FACTORY (l->data);
335 type = gst_element_factory_get_element_type (factory);
337 g_message ("adding type %p for factory %s", (void *) type, gst_element_factory_get_longname (factory));
338 object_types[i++] = type;
340 g_message ("type info for factory %s not found",
341 gst_element_factory_get_longname (factory));
348 # get_type functions:
353 g_message ("$_ () didn't return a valid type");
356 object_types[i++] = type;
361 # Implicit types retrieved from GLib:
364 type = g_type_from_name ("$_");
366 g_message ("Implicit type $_ not found");
369 object_types[i++] = type;
378 /* Need to make sure all the types are loaded in and initialize
379 * their signals and properties.
381 for (i=0; object_types[i]; i++) {
382 if (G_TYPE_IS_CLASSED (object_types[i]))
383 g_type_class_ref (object_types[i]);
385 g_warning ("not reffing type: %s", g_type_name (object_types[i]));
393 * This uses GObject type functions to output signal prototypes and the object
397 /* The output files */
398 const gchar *signals_filename = "$new_signals_filename";
399 const gchar *hierarchy_filename = "$new_hierarchy_filename";
400 const gchar *interfaces_filename = "$new_interfaces_filename";
401 const gchar *prerequisites_filename = "$new_prerequisites_filename";
402 const gchar *args_filename = "$new_args_filename";
405 static void output_signals (void);
406 static void output_object_signals (FILE *fp,
408 static void output_object_signal (FILE *fp,
409 const gchar *object_class_name,
411 static const gchar * get_type_name (GType type,
412 gboolean * is_pointer);
413 static const gchar * get_gdk_event (const gchar * signal_name);
414 static const gchar ** lookup_signal_arg_names (const gchar * type,
415 const gchar * signal_name);
417 static void output_object_hierarchy (void);
418 static void output_hierarchy (FILE *fp,
422 static void output_object_interfaces (void);
423 static void output_interfaces (FILE *fp,
426 static void output_interface_prerequisites (void);
427 static void output_prerequisites (FILE *fp,
430 static void output_args (void);
431 static void output_object_args (FILE *fp, GType object_type);
434 main (int argc, char *argv[])
436 /* Silence the compiler: */
437 if (argv != argv) argc = argc;
444 output_object_hierarchy ();
445 output_object_interfaces ();
446 output_interface_prerequisites ();
454 output_signals (void)
459 fp = fopen (signals_filename, "w");
462 g_warning ("Couldn't open output file: %s : %s", signals_filename, strerror(errno));
466 for (i = 0; object_types[i]; i++)
467 output_object_signals (fp, object_types[i]);
473 compare_signals (const void *a, const void *b)
475 const guint *signal_a = a;
476 const guint *signal_b = b;
478 return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b));
481 /* This outputs all the signals of one object. */
483 output_object_signals (FILE *fp, GType object_type)
485 const gchar *object_class_name;
486 guint *signals, n_signals;
489 if (G_TYPE_IS_INSTANTIATABLE (object_type) ||
490 G_TYPE_IS_INTERFACE (object_type))
493 object_class_name = g_type_name (object_type);
495 signals = g_signal_list_ids (object_type, &n_signals);
496 qsort (signals, n_signals, sizeof (guint), compare_signals);
498 for (sig = 0; sig < n_signals; sig++)
500 output_object_signal (fp, object_class_name, signals[sig]);
507 /* This outputs one signal. */
509 output_object_signal (FILE *fp,
510 const gchar *object_name,
513 GSignalQuery query_info;
514 const gchar *type_name, *ret_type, *object_arg, *arg_name;
515 gchar *pos, *object_arg_lower;
517 gchar ret_type_buffer[1024], buffer[1024];
519 const gchar **arg_names;
520 gint param_num, widget_num, event_num, callback_num;
522 gchar signal_name[128];
525 /* g_print ("Object: %s Signal: %u\\n", object_name, signal_id);*/
528 widget_num = event_num = callback_num = 0;
530 g_signal_query (signal_id, &query_info);
532 /* Output the return type and function name. */
533 ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
534 sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
536 /* Output the signal object type and the argument name. We assume the
537 type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
538 convert to lower case for the argument name. */
540 sprintf (pos, "%s ", object_name);
543 if (!strncmp (object_name, "Gtk", 3))
544 object_arg = object_name + 3;
545 else if (!strncmp (object_name, "Gnome", 5))
546 object_arg = object_name + 5;
548 object_arg = object_name;
550 object_arg_lower = g_ascii_strdown (object_arg, -1);
551 sprintf (pos, "*%s\\n", object_arg_lower);
553 if (!strncmp (object_arg_lower, "widget", 6))
555 g_free(object_arg_lower);
557 /* Convert signal name to use underscores rather than dashes '-'. */
558 strcpy (signal_name, query_info.signal_name);
559 for (i = 0; signal_name[i]; i++)
561 if (signal_name[i] == '-')
562 signal_name[i] = '_';
565 /* Output the signal parameters. */
566 arg_names = lookup_signal_arg_names (object_name, signal_name);
568 for (param = 0; param < query_info.n_params; param++)
572 sprintf (pos, "%s\\n", arg_names[param]);
577 type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
579 /* Most arguments to the callback are called "arg1", "arg2", etc.
580 GdkWidgets are called "widget", "widget2", ...
581 GdkEvents are called "event", "event2", ...
582 GtkCallbacks are called "callback", "callback2", ... */
583 if (!strcmp (type_name, "GtkWidget"))
586 arg_num = &widget_num;
588 else if (!strcmp (type_name, "GdkEvent"))
590 type_name = get_gdk_event (signal_name);
592 arg_num = &event_num;
595 else if (!strcmp (type_name, "GtkCallback")
596 || !strcmp (type_name, "GtkCCallback"))
598 arg_name = "callback";
599 arg_num = &callback_num;
604 arg_num = ¶m_num;
606 sprintf (pos, "%s ", type_name);
609 if (!arg_num || *arg_num == 0)
610 sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
612 sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
627 /* We use one-character flags for simplicity. */
628 if (query_info.signal_flags & G_SIGNAL_RUN_FIRST)
630 if (query_info.signal_flags & G_SIGNAL_RUN_LAST)
632 if (query_info.signal_flags & G_SIGNAL_RUN_CLEANUP)
634 if (query_info.signal_flags & G_SIGNAL_NO_RECURSE)
636 if (query_info.signal_flags & G_SIGNAL_DETAILED)
638 if (query_info.signal_flags & G_SIGNAL_ACTION)
640 if (query_info.signal_flags & G_SIGNAL_NO_HOOKS)
645 "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n<FLAGS>%s</FLAGS>\\n%s</SIGNAL>\\n\\n",
646 object_name, query_info.signal_name, ret_type_buffer, flags, buffer);
650 /* Returns the type name to use for a signal argument or return value, given
651 the GtkType from the signal info. It also sets is_pointer to TRUE if the
652 argument needs a '*' since it is a pointer. */
654 get_type_name (GType type, gboolean * is_pointer)
656 const gchar *type_name;
659 type_name = g_type_name (type);
673 /* These all have normal C type names so they are OK. */
677 /* A GtkString is really a gchar*. */
683 /* We use a gint for both of these. Hopefully a subtype with a decent
684 name will be registered and used instead, as GTK+ does itself. */
688 /* The boxed type shouldn't be used itself, only subtypes. Though we
689 return 'gpointer' just in case. */
693 /* A GParam is really a GParamSpec*. */
701 /* For all GObject subclasses we can use the class name with a "*",
702 e.g. 'GtkWidget *'. */
703 if (g_type_is_a (type, G_TYPE_OBJECT))
706 if (G_TYPE_IS_CLASSED (type))
709 /* All boxed subtypes will be pointers as well. */
710 if (g_type_is_a (type, G_TYPE_BOXED))
713 /* All pointer subtypes will be pointers as well. */
714 if (g_type_is_a (type, G_TYPE_POINTER))
717 /* But enums are not */
718 if (g_type_is_a (type, G_TYPE_ENUM) ||
719 g_type_is_a (type, G_TYPE_FLAGS))
727 get_gdk_event (const gchar * signal_name)
729 static const gchar *GbGDKEvents[] =
731 "button_press_event", "GdkEventButton",
732 "button_release_event", "GdkEventButton",
733 "motion_notify_event", "GdkEventMotion",
734 "delete_event", "GdkEvent",
735 "destroy_event", "GdkEvent",
736 "expose_event", "GdkEventExpose",
737 "key_press_event", "GdkEventKey",
738 "key_release_event", "GdkEventKey",
739 "enter_notify_event", "GdkEventCrossing",
740 "leave_notify_event", "GdkEventCrossing",
741 "configure_event", "GdkEventConfigure",
742 "focus_in_event", "GdkEventFocus",
743 "focus_out_event", "GdkEventFocus",
744 "map_event", "GdkEvent",
745 "unmap_event", "GdkEvent",
746 "property_notify_event", "GdkEventProperty",
747 "selection_clear_event", "GdkEventSelection",
748 "selection_request_event", "GdkEventSelection",
749 "selection_notify_event", "GdkEventSelection",
750 "proximity_in_event", "GdkEventProximity",
751 "proximity_out_event", "GdkEventProximity",
752 "drag_begin_event", "GdkEventDragBegin",
753 "drag_request_event", "GdkEventDragRequest",
754 "drag_end_event", "GdkEventDragRequest",
755 "drop_enter_event", "GdkEventDropEnter",
756 "drop_leave_event", "GdkEventDropLeave",
757 "drop_data_available_event", "GdkEventDropDataAvailable",
758 "other_event", "GdkEventOther",
759 "client_event", "GdkEventClient",
760 "no_expose_event", "GdkEventNoExpose",
761 "visibility_notify_event", "GdkEventVisibility",
762 "window_state_event", "GdkEventWindowState",
763 "scroll_event", "GdkEventScroll",
769 for (i = 0; GbGDKEvents[i]; i += 2)
771 if (!strcmp (signal_name, GbGDKEvents[i]))
772 return GbGDKEvents[i + 1];
778 /* This returns argument names to use for some known GTK signals.
779 It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
780 'select_row' and it returns a pointer to an array of argument types and
782 static const gchar **
783 lookup_signal_arg_names (const gchar * type, const gchar * signal_name)
785 /* Each arg array starts with the object type name and the signal name,
786 and then signal arguments follow. */
787 static const gchar *GbArgTable[][16] =
789 {"GtkCList", "select_row",
792 "GdkEventButton *event"},
793 {"GtkCList", "unselect_row",
796 "GdkEventButton *event"},
797 {"GtkCList", "click_column",
800 {"GtkCList", "resize_column",
804 {"GtkCList", "extend_selection",
805 "GtkScrollType scroll_type",
807 "gboolean auto_start_selection"},
808 {"GtkCList", "scroll_vertical",
809 "GtkScrollType scroll_type",
811 {"GtkCList", "scroll_horizontal",
812 "GtkScrollType scroll_type",
815 {"GtkCTree", "tree_select_row",
816 "GtkCTreeNode *node",
818 {"GtkCTree", "tree_unselect_row",
819 "GtkCTreeNode *node",
821 {"GtkCTree", "tree_expand",
822 "GtkCTreeNode *node"},
823 {"GtkCTree", "tree_collapse",
824 "GtkCTreeNode *node"},
825 {"GtkCTree", "tree_move",
826 "GtkCTreeNode *node",
827 "GtkCTreeNode *new_parent",
828 "GtkCTreeNode *new_sibling"},
829 {"GtkCTree", "change_focus_row_expansion",
830 "GtkCTreeExpansionType expansion"},
832 {"GtkEditable", "insert_text",
834 "gint new_text_length",
836 {"GtkEditable", "delete_text",
839 {"GtkEditable", "set_editable",
840 "gboolean is_editable"},
841 {"GtkEditable", "move_cursor",
844 {"GtkEditable", "move_word",
846 {"GtkEditable", "move_page",
849 {"GtkEditable", "move_to_row",
851 {"GtkEditable", "move_to_column",
854 {"GtkEditable", "kill_char",
856 {"GtkEditable", "kill_word",
858 {"GtkEditable", "kill_line",
862 {"GtkInputDialog", "enable_device",
863 "GdkDevice *deviceid"},
864 {"GtkInputDialog", "disable_device",
865 "GdkDevice *deviceid"},
867 {"GtkListItem", "extend_selection",
868 "GtkScrollType scroll_type",
870 "gboolean auto_start_selection"},
871 {"GtkListItem", "scroll_vertical",
872 "GtkScrollType scroll_type",
874 {"GtkListItem", "scroll_horizontal",
875 "GtkScrollType scroll_type",
878 {"GtkMenuShell", "move_current",
879 "GtkMenuDirectionType direction"},
880 {"GtkMenuShell", "activate_current",
881 "gboolean force_hide"},
884 {"GtkNotebook", "switch_page",
885 "GtkNotebookPage *page",
887 {"GtkStatusbar", "text_pushed",
890 {"GtkStatusbar", "text_popped",
893 {"GtkTipsQuery", "widget_entered",
896 "gchar *tip_private"},
897 {"GtkTipsQuery", "widget_selected",
900 "gchar *tip_private",
901 "GdkEventButton *event"},
902 {"GtkToolbar", "orientation_changed",
903 "GtkOrientation orientation"},
904 {"GtkToolbar", "style_changed",
905 "GtkToolbarStyle style"},
906 {"GtkWidget", "draw",
907 "GdkRectangle *area"},
908 {"GtkWidget", "size_request",
909 "GtkRequisition *requisition"},
910 {"GtkWidget", "size_allocate",
911 "GtkAllocation *allocation"},
912 {"GtkWidget", "state_changed",
913 "GtkStateType state"},
914 {"GtkWidget", "style_set",
915 "GtkStyle *previous_style"},
917 {"GtkWidget", "install_accelerator",
918 "gchar *signal_name",
922 {"GtkWidget", "add_accelerator",
923 "guint accel_signal_id",
924 "GtkAccelGroup *accel_group",
926 "GdkModifierType accel_mods",
927 "GtkAccelFlags accel_flags"},
929 {"GtkWidget", "parent_set",
930 "GtkObject *old_parent"},
932 {"GtkWidget", "remove_accelerator",
933 "GtkAccelGroup *accel_group",
935 "GdkModifierType accel_mods"},
936 {"GtkWidget", "debug_msg",
938 {"GtkWindow", "move_resize",
943 {"GtkWindow", "set_focus",
944 "GtkWidget *widget"},
946 {"GtkWidget", "selection_get",
947 "GtkSelectionData *data",
950 {"GtkWidget", "selection_received",
951 "GtkSelectionData *data",
954 {"GtkWidget", "drag_begin",
955 "GdkDragContext *drag_context"},
956 {"GtkWidget", "drag_end",
957 "GdkDragContext *drag_context"},
958 {"GtkWidget", "drag_data_delete",
959 "GdkDragContext *drag_context"},
960 {"GtkWidget", "drag_leave",
961 "GdkDragContext *drag_context",
963 {"GtkWidget", "drag_motion",
964 "GdkDragContext *drag_context",
968 {"GtkWidget", "drag_drop",
969 "GdkDragContext *drag_context",
973 {"GtkWidget", "drag_data_get",
974 "GdkDragContext *drag_context",
975 "GtkSelectionData *data",
978 {"GtkWidget", "drag_data_received",
979 "GdkDragContext *drag_context",
982 "GtkSelectionData *data",
991 for (i = 0; GbArgTable[i][0]; i++)
994 if (!strcmp (type, GbArgTable[i][0])
995 && !strcmp (signal_name, GbArgTable[i][1]))
996 return &GbArgTable[i][2];
1002 /* This outputs the hierarchy of all objects which have been initialized,
1003 i.e. by calling their XXX_get_type() initialization function. */
1005 output_object_hierarchy (void)
1010 fp = fopen (hierarchy_filename, "w");
1013 g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, strerror(errno));
1016 output_hierarchy (fp, G_TYPE_OBJECT, 0);
1017 output_hierarchy (fp, G_TYPE_INTERFACE, 0);
1019 for (i=0; object_types[i]; i++) {
1020 if (!g_type_parent (object_types[i]) &&
1021 (object_types[i] != G_TYPE_NONE) &&
1022 (object_types[i] != G_TYPE_OBJECT) &&
1023 (object_types[i] != G_TYPE_INTERFACE)
1025 g_warning ("printing hierarchy for root type: %s",
1026 g_type_name (object_types[i]));
1027 output_hierarchy (fp, object_types[i], 0);
1031 for (i=0; object_types[i]; i++) {
1032 if(object_types[i] != G_TYPE_NONE) {
1033 g_print ("type has not been added to hierarchy: %s\\n",
1034 g_type_name (object_types[i]));
1043 type_cmp (const void * p1, const void * p2)
1045 return strcmp (g_type_name (*((GType *) p1)), g_type_name (*((GType *) p2)));
1048 /* This is called recursively to output the hierarchy of a widget. */
1050 output_hierarchy (FILE *fp,
1062 for (i=0; object_types[i]; i++) {
1063 if(object_types[i] == type) {
1064 g_print ("added type to hierarchy (level %d): %s\\n",
1065 level, g_type_name (type));
1066 object_types[i] = G_TYPE_NONE;
1072 for (i = 0; i < level; i++)
1074 fprintf (fp, "%s", g_type_name (type));
1075 fprintf (fp, "\\n");
1077 children = g_type_children (type, &n_children);
1079 qsort (&children[0], n_children, sizeof (GType), type_cmp);
1081 for (i=0; i < n_children; i++) {
1082 output_hierarchy (fp, children[i], level + 1);
1088 static void output_object_interfaces (void)
1093 fp = fopen (interfaces_filename, "w");
1096 g_warning ("Couldn't open output file: %s : %s", interfaces_filename, strerror(errno));
1099 output_interfaces (fp, G_TYPE_OBJECT);
1101 for (i = 0; object_types[i]; i++)
1103 if (!g_type_parent (object_types[i]) &&
1104 (object_types[i] != G_TYPE_OBJECT) &&
1105 G_TYPE_IS_INSTANTIATABLE (object_types[i]))
1107 output_interfaces (fp, object_types[i]);
1114 output_interfaces (FILE *fp,
1118 GType *children, *interfaces;
1119 guint n_children, n_interfaces;
1124 interfaces = g_type_interfaces (type, &n_interfaces);
1126 if (n_interfaces > 0)
1128 fprintf (fp, "%s", g_type_name (type));
1129 for (i=0; i < n_interfaces; i++)
1130 fprintf (fp, " %s", g_type_name (interfaces[i]));
1131 fprintf (fp, "\\n");
1133 g_free (interfaces);
1135 children = g_type_children (type, &n_children);
1137 for (i=0; i < n_children; i++)
1138 output_interfaces (fp, children[i]);
1143 static void output_interface_prerequisites (void)
1147 fp = fopen (prerequisites_filename, "w");
1150 g_warning ("Couldn't open output file: %s : %s", prerequisites_filename, strerror(errno));
1153 output_prerequisites (fp, G_TYPE_INTERFACE);
1158 output_prerequisites (FILE *fp,
1161 #if GLIB_CHECK_VERSION(2,1,0)
1163 GType *children, *prerequisites;
1164 guint n_children, n_prerequisites;
1169 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
1171 if (n_prerequisites > 0)
1173 fprintf (fp, "%s", g_type_name (type));
1174 for (i=0; i < n_prerequisites; i++)
1175 fprintf (fp, " %s", g_type_name (prerequisites[i]));
1176 fprintf (fp, "\\n");
1178 g_free (prerequisites);
1180 children = g_type_children (type, &n_children);
1182 for (i=0; i < n_children; i++)
1183 output_prerequisites (fp, children[i]);
1195 fp = fopen (args_filename, "w");
1198 g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno));
1202 for (i = 0; object_types[i]; i++) {
1203 output_object_args (fp, object_types[i]);
1210 compare_param_specs (const void *a, const void *b)
1212 GParamSpec *spec_a = *(GParamSpec **)a;
1213 GParamSpec *spec_b = *(GParamSpec **)b;
1215 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
1218 /* Its common to have unsigned properties restricted
1219 * to the signed range. Therefore we make this look
1220 * a bit nicer by spelling out the max constants.
1223 /* Don't use "==" with floats, it might trigger a gcc warning. */
1224 #define GTKDOC_COMPARE_FLOAT(x, y) (x <= y && x >= y)
1227 describe_double_constant (gdouble value)
1231 if (GTKDOC_COMPARE_FLOAT (value, G_MAXDOUBLE))
1232 desc = g_strdup ("G_MAXDOUBLE");
1233 else if (GTKDOC_COMPARE_FLOAT (value, G_MINDOUBLE))
1234 desc = g_strdup ("G_MINDOUBLE");
1235 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXDOUBLE))
1236 desc = g_strdup ("-G_MAXDOUBLE");
1237 else if (GTKDOC_COMPARE_FLOAT (value, G_MAXFLOAT))
1238 desc = g_strdup ("G_MAXFLOAT");
1239 else if (GTKDOC_COMPARE_FLOAT (value, G_MINFLOAT))
1240 desc = g_strdup ("G_MINFLOAT");
1241 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXFLOAT))
1242 desc = g_strdup ("-G_MAXFLOAT");
1244 /* make sure floats are output with a decimal dot irrespective of
1245 * current locale. Use formatd since we want human-readable numbers
1246 * and do not need the exact same bit representation when deserialising */
1247 desc = g_malloc0 (G_ASCII_DTOSTR_BUF_SIZE);
1248 g_ascii_formatd (desc, G_ASCII_DTOSTR_BUF_SIZE, "%g", value);
1255 describe_signed_constant (gint64 value)
1259 if (value == G_MAXINT)
1260 desc = g_strdup ("G_MAXINT");
1261 else if (value == G_MININT)
1262 desc = g_strdup ("G_MININT");
1263 else if (value == G_MAXUINT)
1264 desc = g_strdup ("G_MAXUINT");
1265 else if (value == G_MAXLONG)
1266 desc = g_strdup ("G_MAXLONG");
1267 else if (value == G_MINLONG)
1268 desc = g_strdup ("G_MINLONG");
1269 else if (value == G_MAXULONG)
1270 desc = g_strdup ("G_MAXULONG");
1271 else if (value == G_MAXINT64)
1272 desc = g_strdup ("G_MAXINT64");
1273 else if (value == G_MININT64)
1274 desc = g_strdup ("G_MININT64");
1276 desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
1282 describe_unsigned_constant (guint64 value)
1286 if (value == G_MAXINT)
1287 desc = g_strdup ("G_MAXINT");
1288 else if (value == G_MININT)
1289 desc = g_strdup ("G_MININT");
1290 else if (value == G_MAXUINT)
1291 desc = g_strdup ("G_MAXUINT");
1292 else if (value == G_MAXLONG)
1293 desc = g_strdup ("G_MAXLONG");
1294 else if (value == G_MINLONG)
1295 desc = g_strdup ("G_MINLONG");
1296 else if (value == G_MAXULONG)
1297 desc = g_strdup ("G_MAXULONG");
1298 else if (value == G_MAXINT64)
1299 desc = g_strdup ("G_MAXINT64");
1300 else if (value == G_MININT64)
1301 desc = g_strdup ("G_MININT64");
1302 else if (value == G_MAXUINT64)
1303 desc = g_strdup ("G_MAXUINT64");
1305 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
1311 describe_type (GParamSpec *spec)
1317 if (G_IS_PARAM_SPEC_CHAR (spec))
1319 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1321 lower = describe_signed_constant (pspec->minimum);
1322 upper = describe_signed_constant (pspec->maximum);
1323 if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
1324 desc = g_strdup ("");
1325 else if (pspec->minimum == G_MININT8)
1326 desc = g_strdup_printf ("<= %s", upper);
1327 else if (pspec->maximum == G_MAXINT8)
1328 desc = g_strdup_printf (">= %s", lower);
1330 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1334 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1336 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1338 lower = describe_unsigned_constant (pspec->minimum);
1339 upper = describe_unsigned_constant (pspec->maximum);
1340 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
1341 desc = g_strdup ("");
1342 else if (pspec->minimum == 0)
1343 desc = g_strdup_printf ("<= %s", upper);
1344 else if (pspec->maximum == G_MAXUINT8)
1345 desc = g_strdup_printf (">= %s", lower);
1347 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1351 else if (G_IS_PARAM_SPEC_INT (spec))
1353 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1355 lower = describe_signed_constant (pspec->minimum);
1356 upper = describe_signed_constant (pspec->maximum);
1357 if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
1358 desc = g_strdup ("");
1359 else if (pspec->minimum == G_MININT)
1360 desc = g_strdup_printf ("<= %s", upper);
1361 else if (pspec->maximum == G_MAXINT)
1362 desc = g_strdup_printf (">= %s", lower);
1364 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1368 else if (G_IS_PARAM_SPEC_UINT (spec))
1370 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1372 lower = describe_unsigned_constant (pspec->minimum);
1373 upper = describe_unsigned_constant (pspec->maximum);
1374 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
1375 desc = g_strdup ("");
1376 else if (pspec->minimum == 0)
1377 desc = g_strdup_printf ("<= %s", upper);
1378 else if (pspec->maximum == G_MAXUINT)
1379 desc = g_strdup_printf (">= %s", lower);
1381 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1385 else if (G_IS_PARAM_SPEC_LONG (spec))
1387 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1389 lower = describe_signed_constant (pspec->minimum);
1390 upper = describe_signed_constant (pspec->maximum);
1391 if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
1392 desc = g_strdup ("");
1393 else if (pspec->minimum == G_MINLONG)
1394 desc = g_strdup_printf ("<= %s", upper);
1395 else if (pspec->maximum == G_MAXLONG)
1396 desc = g_strdup_printf (">= %s", lower);
1398 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1402 else if (G_IS_PARAM_SPEC_ULONG (spec))
1404 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1407 lower = describe_unsigned_constant (pspec->minimum);
1408 upper = describe_unsigned_constant (pspec->maximum);
1409 if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
1410 desc = g_strdup ("");
1411 else if (pspec->minimum == 0)
1412 desc = g_strdup_printf ("<= %s", upper);
1413 else if (pspec->maximum == G_MAXULONG)
1414 desc = g_strdup_printf (">= %s", lower);
1416 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1420 else if (G_IS_PARAM_SPEC_INT64 (spec))
1422 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1424 lower = describe_signed_constant (pspec->minimum);
1425 upper = describe_signed_constant (pspec->maximum);
1426 if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
1427 desc = g_strdup ("");
1428 else if (pspec->minimum == G_MININT64)
1429 desc = g_strdup_printf ("<= %s", upper);
1430 else if (pspec->maximum == G_MAXINT64)
1431 desc = g_strdup_printf (">= %s", lower);
1433 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1437 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1439 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1441 lower = describe_unsigned_constant (pspec->minimum);
1442 upper = describe_unsigned_constant (pspec->maximum);
1443 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
1444 desc = g_strdup ("");
1445 else if (pspec->minimum == 0)
1446 desc = g_strdup_printf ("<= %s", upper);
1447 else if (pspec->maximum == G_MAXUINT64)
1448 desc = g_strdup_printf (">= %s", lower);
1450 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1454 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1456 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1458 lower = describe_double_constant (pspec->minimum);
1459 upper = describe_double_constant (pspec->maximum);
1460 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXFLOAT))
1462 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1463 desc = g_strdup ("");
1465 desc = g_strdup_printf ("<= %s", upper);
1467 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1468 desc = g_strdup_printf (">= %s", lower);
1470 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1474 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1476 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1478 lower = describe_double_constant (pspec->minimum);
1479 upper = describe_double_constant (pspec->maximum);
1480 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXDOUBLE))
1482 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1483 desc = g_strdup ("");
1485 desc = g_strdup_printf ("<= %s", upper);
1487 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1488 desc = g_strdup_printf (">= %s", lower);
1490 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1496 desc = g_strdup ("");
1503 describe_default (GParamSpec *spec)
1507 if (G_IS_PARAM_SPEC_CHAR (spec))
1509 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1511 desc = g_strdup_printf ("%d", pspec->default_value);
1513 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1515 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1517 desc = g_strdup_printf ("%u", pspec->default_value);
1519 else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
1521 GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
1523 desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
1525 else if (G_IS_PARAM_SPEC_INT (spec))
1527 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1529 desc = g_strdup_printf ("%d", pspec->default_value);
1531 else if (G_IS_PARAM_SPEC_UINT (spec))
1533 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1535 desc = g_strdup_printf ("%u", pspec->default_value);
1537 else if (G_IS_PARAM_SPEC_LONG (spec))
1539 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1541 desc = g_strdup_printf ("%ld", pspec->default_value);
1543 else if (G_IS_PARAM_SPEC_LONG (spec))
1545 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1547 desc = g_strdup_printf ("%lu", pspec->default_value);
1549 else if (G_IS_PARAM_SPEC_INT64 (spec))
1551 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1553 desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
1555 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1557 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1559 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
1561 else if (G_IS_PARAM_SPEC_UNICHAR (spec))
1563 GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
1565 if (g_unichar_isprint (pspec->default_value))
1566 desc = g_strdup_printf ("'%c'", pspec->default_value);
1568 desc = g_strdup_printf ("%u", pspec->default_value);
1570 else if (G_IS_PARAM_SPEC_ENUM (spec))
1572 GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
1574 GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
1576 desc = g_strdup_printf ("%s", value->value_name);
1578 desc = g_strdup_printf ("%d", pspec->default_value);
1580 else if (G_IS_PARAM_SPEC_FLAGS (spec))
1582 GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
1583 guint default_value;
1586 default_value = pspec->default_value;
1587 acc = g_string_new ("");
1589 while (default_value)
1591 GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
1597 g_string_append (acc, "|");
1598 g_string_append (acc, value->value_name);
1600 default_value &= ~value->value;
1603 if (default_value == 0)
1604 desc = g_string_free (acc, FALSE);
1607 desc = g_strdup_printf ("%d", pspec->default_value);
1608 g_string_free (acc, TRUE);
1611 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1613 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1615 /* make sure floats are output with a decimal dot irrespective of
1616 * current locale. Use formatd since we want human-readable numbers
1617 * and do not need the exact same bit representation when deserialising */
1618 desc = g_malloc0 (G_ASCII_DTOSTR_BUF_SIZE);
1619 g_ascii_formatd (desc, G_ASCII_DTOSTR_BUF_SIZE, "%g",
1620 pspec->default_value);
1622 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1624 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1626 /* make sure floats are output with a decimal dot irrespective of
1627 * current locale. Use formatd since we want human-readable numbers
1628 * and do not need the exact same bit representation when deserialising */
1629 desc = g_malloc0 (G_ASCII_DTOSTR_BUF_SIZE);
1630 g_ascii_formatd (desc, G_ASCII_DTOSTR_BUF_SIZE, "%g",
1631 pspec->default_value);
1633 else if (G_IS_PARAM_SPEC_STRING (spec))
1635 GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
1637 if (pspec->default_value)
1639 gchar *esc = g_strescape (pspec->default_value, NULL);
1641 desc = g_strdup_printf ("\\"%s\\"", esc);
1646 desc = g_strdup_printf ("NULL");
1650 desc = g_strdup ("");
1658 output_object_args (FILE *fp, GType object_type)
1661 const gchar *object_class_name;
1663 gchar flags[16], *pos;
1664 GParamSpec **properties;
1666 gboolean child_prop;
1667 gboolean style_prop;
1668 gboolean is_pointer;
1669 const gchar *type_name;
1671 gchar *default_value;
1673 if (G_TYPE_IS_OBJECT (object_type))
1675 class = g_type_class_peek (object_type);
1679 properties = g_object_class_list_properties (class, &n_properties);
1681 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
1682 else if (G_TYPE_IS_INTERFACE (object_type))
1684 class = g_type_default_interface_ref (object_type);
1689 properties = g_object_interface_list_properties (class, &n_properties);
1695 object_class_name = g_type_name (object_type);
1701 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
1702 for (arg = 0; arg < n_properties; arg++)
1704 GParamSpec *spec = properties[arg];
1705 const gchar *nick, *blurb, *dot;
1707 if (spec->owner_type != object_type)
1711 /* We use one-character flags for simplicity. */
1712 if (child_prop && !style_prop)
1716 if (spec->flags & G_PARAM_READABLE)
1718 if (spec->flags & G_PARAM_WRITABLE)
1720 if (spec->flags & G_PARAM_CONSTRUCT)
1722 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
1726 nick = g_param_spec_get_nick (spec);
1727 blurb = g_param_spec_get_blurb (spec);
1731 int str_len = strlen (blurb);
1732 if (str_len > 0 && blurb[str_len - 1] != '.')
1736 type_desc = describe_type (spec);
1737 default_value = describe_default (spec);
1738 type_name = get_type_name (spec->value_type, &is_pointer);
1739 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",
1740 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);
1742 g_free (default_value);
1745 g_free (properties);
1747 #ifdef GTK_IS_CONTAINER_CLASS
1748 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
1749 properties = gtk_container_class_list_child_properties (class, &n_properties);
1755 #ifdef GTK_IS_WIDGET_CLASS
1756 #if GTK_CHECK_VERSION(2,1,0)
1757 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
1758 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1772 # Compile and run our file
1774 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
1775 $LD = $ENV{LD} ? $ENV{LD} : $CC;
1776 $CFLAGS = $ENV{CFLAGS} ? "$ENV{CFLAGS}" : "";
1777 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
1780 if ($CC =~ /libtool/) {
1781 $o_file = "$MODULE-scan.lo"
1783 $o_file = "$MODULE-scan.o"
1786 print "gtk-doc: Compiling scanner\n";
1787 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c";
1788 system($command) == 0 or die "Compilation of scanner failed: $!\n";
1790 print "gtk-doc: Linking scanner\n";
1791 $command = "$LD -o $MODULE-scan $o_file $LDFLAGS";
1792 system($command) == 0 or die "Linking of scanner failed: $!\n";
1794 print "gtk-doc: Running scanner $MODULE-scan\n";
1795 system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n";
1797 if (!defined($ENV{"GTK_DOC_KEEP_INTERMEDIATE"})) {
1798 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
1801 #&UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
1802 &UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
1803 &UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
1804 &UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
1805 #&UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);