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
43 my $TYPE_INIT_FUNC="g_type_init ()";
45 # --nogtkinit is deprecated, as it is the default now anyway.
46 %optctl = (module => \$MODULE,
48 types => \$TYPES_FILE,
49 nogtkinit => \$NO_GTK_INIT,
50 'type-init-func' => \$TYPE_INIT_FUNC,
51 'output-dir' => \$OUTPUT_DIR,
52 'version' => \$PRINT_VERSION,
53 'help' => \$PRINT_HELP);
55 GetOptions(\%optctl, "module=s", "source=s", "types:s", "output-dir:s", "nogtkinit", "type-init-func:s", "version", "help");
58 # Do nothing. This just avoids a warning.
71 print "gstdoc-scangobj version 1.5\n";
72 print "\n--module=MODULE_NAME Name of the doc module being parsed";
73 print "\n--source=SOURCE_NAME Name of the source module for plugins";
74 print "\n--types=FILE The name of the file to store the types in";
75 print "\n--type-init-func=FUNC The init function to call instead of g_type_init ()";
76 print "\n--output-dir=DIRNAME The directory where the results are stored";
77 print "\n--version Print the version of this program";
78 print "\n--help Print this help\n";
82 $OUTPUT_DIR = $OUTPUT_DIR ? $OUTPUT_DIR : ".";
84 # THOMAS: dynamic types; only use types file for headers
85 $TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$OUTPUT_DIR/$MODULE.types";
87 open (TYPES, $TYPES_FILE) || die "Cannot open $TYPES_FILE: $!\n";
88 open (OUTPUT, ">$MODULE-scan.c") || die "Cannot open $MODULE-scan.c: $!\n";
90 my $old_signals_filename = "$OUTPUT_DIR/$MODULE.signals";
91 my $new_signals_filename = "$OUTPUT_DIR/$MODULE.signals.new";
92 my $old_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy";
93 my $new_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy.new";
94 my $old_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces";
95 my $new_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces.new";
96 my $old_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites";
97 my $new_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites.new";
98 my $old_args_filename = "$OUTPUT_DIR/$MODULE.args";
99 my $new_args_filename = "$OUTPUT_DIR/$MODULE.args.new";
101 # write a C program to scan the types
111 # } elsif (/^\s*$/) {
119 #$ntypes = @types + 1;
128 #ifdef GTK_IS_WIDGET_CLASS
129 #include <gtk/gtkversion.h>
131 GType *object_types = NULL;
134 get_object_types (void)
136 GList *plugins = NULL;
137 GList *factories = NULL;
139 GstElementFactory *factory = NULL;
143 /* get a list of features from plugins in our source module */
144 plugins = gst_registry_get_plugin_list (gst_registry_get_default());
151 plugin = (GstPlugin *) (plugins->data);
152 plugins = g_list_next (plugins);
153 source = gst_plugin_get_source (plugin);
154 g_print ("source: %s\\n", source);
155 if (!source || strcmp (gst_plugin_get_source (plugin), "$SOURCE") != 0) {
160 gst_registry_get_feature_list_by_plugin (gst_registry_get_default (),
163 GstPluginFeature *feature;
164 feature = GST_PLUGIN_FEATURE (features->data);
165 feature = gst_plugin_feature_load (feature);
167 g_warning ("Could not load plugin feature %s",
168 gst_plugin_feature_get_name (feature));
171 if (GST_IS_ELEMENT_FACTORY (feature)) {
172 factory = GST_ELEMENT_FACTORY (feature);
173 factories = g_list_append (factories, factory);
175 features = g_list_next (features);
179 g_message ("number of element factories: %d", g_list_length (factories));
181 /* allocate the object_types array to hold them */
182 object_types = g_new0 (GType, g_list_length (factories)+1);
190 factory = GST_ELEMENT_FACTORY (l->data);
191 g_message ("adding type for factory %s", gst_element_factory_get_longname (factory));
192 type = gst_element_factory_get_element_type (factory);
193 g_message ("adding type %p", (void *) type);
194 object_types[i] = type;
203 /* Need to make sure all the types are loaded in and initialize
204 * their signals and properties.
206 for (i=0; object_types[i]; i++) {
207 if (G_TYPE_IS_CLASSED (object_types[i]))
208 g_type_class_ref (object_types[i]);
215 * This uses GObject type functions to output signal prototypes and the object
219 /* The output files */
220 const gchar *signals_filename = "$new_signals_filename";
221 const gchar *hierarchy_filename = "$new_hierarchy_filename";
222 const gchar *interfaces_filename = "$new_interfaces_filename";
223 const gchar *prerequisites_filename = "$new_prerequisites_filename";
224 const gchar *args_filename = "$new_args_filename";
227 static void output_signals (void);
228 static void output_object_signals (FILE *fp,
230 static void output_object_signal (FILE *fp,
231 const gchar *object_class_name,
233 static const gchar * get_type_name (GType type,
234 gboolean * is_pointer);
235 static const gchar * get_gdk_event (const gchar * signal_name);
236 static const gchar ** lookup_signal_arg_names (const gchar * type,
237 const gchar * signal_name);
239 static void output_object_hierarchy (void);
240 static void output_hierarchy (FILE *fp,
244 static void output_object_interfaces (void);
245 static void output_interfaces (FILE *fp,
248 static void output_interface_prerequisites (void);
249 static void output_prerequisites (FILE *fp,
252 static void output_args (void);
253 static void output_object_args (FILE *fp, GType object_type);
256 main (int argc, char *argv[])
258 /* Silence the compiler: */
259 if (argv != argv) argc = argc;
266 output_object_hierarchy ();
267 output_object_interfaces ();
268 output_interface_prerequisites ();
276 output_signals (void)
281 fp = fopen (signals_filename, "w");
284 g_warning ("Couldn't open output file: %s : %s", signals_filename, strerror(errno));
288 for (i = 0; object_types[i]; i++)
289 output_object_signals (fp, object_types[i]);
295 compare_signals (const void *a, const void *b)
297 const guint *signal_a = a;
298 const guint *signal_b = b;
300 return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b));
303 /* This outputs all the signals of one object. */
305 output_object_signals (FILE *fp, GType object_type)
307 const gchar *object_class_name;
308 guint *signals, n_signals;
311 if (G_TYPE_IS_INSTANTIATABLE (object_type) ||
312 G_TYPE_IS_INTERFACE (object_type))
315 object_class_name = g_type_name (object_type);
317 signals = g_signal_list_ids (object_type, &n_signals);
318 qsort (signals, n_signals, sizeof (guint), compare_signals);
320 for (sig = 0; sig < n_signals; sig++)
322 output_object_signal (fp, object_class_name, signals[sig]);
329 /* This outputs one signal. */
331 output_object_signal (FILE *fp,
332 const gchar *object_name,
335 GSignalQuery query_info;
336 const gchar *type_name, *ret_type, *object_arg, *arg_name;
337 gchar *pos, *object_arg_lower;
339 gchar ret_type_buffer[1024], buffer[1024];
341 const gchar **arg_names;
342 gint param_num, widget_num, event_num, callback_num;
344 gchar signal_name[128];
347 /* g_print ("Object: %s Signal: %u\\n", object_name, signal_id);*/
350 widget_num = event_num = callback_num = 0;
352 g_signal_query (signal_id, &query_info);
354 /* Output the return type and function name. */
355 ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
356 sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
358 /* Output the signal object type and the argument name. We assume the
359 type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
360 convert to lower case for the argument name. */
362 sprintf (pos, "%s ", object_name);
365 if (!strncmp (object_name, "Gtk", 3))
366 object_arg = object_name + 3;
367 else if (!strncmp (object_name, "Gnome", 5))
368 object_arg = object_name + 5;
370 object_arg = object_name;
372 object_arg_lower = g_ascii_strdown (object_arg, -1);
373 sprintf (pos, "*%s\\n", object_arg_lower);
375 if (!strncmp (object_arg_lower, "widget", 6))
377 g_free(object_arg_lower);
379 /* Convert signal name to use underscores rather than dashes '-'. */
380 strcpy (signal_name, query_info.signal_name);
381 for (i = 0; signal_name[i]; i++)
383 if (signal_name[i] == '-')
384 signal_name[i] = '_';
387 /* Output the signal parameters. */
388 arg_names = lookup_signal_arg_names (object_name, signal_name);
390 for (param = 0; param < query_info.n_params; param++)
394 sprintf (pos, "%s\\n", arg_names[param]);
399 type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
401 /* Most arguments to the callback are called "arg1", "arg2", etc.
402 GdkWidgets are called "widget", "widget2", ...
403 GdkEvents are called "event", "event2", ...
404 GtkCallbacks are called "callback", "callback2", ... */
405 if (!strcmp (type_name, "GtkWidget"))
408 arg_num = &widget_num;
410 else if (!strcmp (type_name, "GdkEvent"))
412 type_name = get_gdk_event (signal_name);
414 arg_num = &event_num;
417 else if (!strcmp (type_name, "GtkCallback")
418 || !strcmp (type_name, "GtkCCallback"))
420 arg_name = "callback";
421 arg_num = &callback_num;
426 arg_num = ¶m_num;
428 sprintf (pos, "%s ", type_name);
431 if (!arg_num || *arg_num == 0)
432 sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
434 sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
449 /* We use one-character flags for simplicity. */
450 if (query_info.signal_flags & G_SIGNAL_RUN_FIRST)
452 if (query_info.signal_flags & G_SIGNAL_RUN_LAST)
454 if (query_info.signal_flags & G_SIGNAL_RUN_CLEANUP)
456 if (query_info.signal_flags & G_SIGNAL_NO_RECURSE)
458 if (query_info.signal_flags & G_SIGNAL_DETAILED)
460 if (query_info.signal_flags & G_SIGNAL_ACTION)
462 if (query_info.signal_flags & G_SIGNAL_NO_HOOKS)
467 "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n<FLAGS>%s</FLAGS>\\n%s</SIGNAL>\\n\\n",
468 object_name, query_info.signal_name, ret_type_buffer, flags, buffer);
472 /* Returns the type name to use for a signal argument or return value, given
473 the GtkType from the signal info. It also sets is_pointer to TRUE if the
474 argument needs a '*' since it is a pointer. */
476 get_type_name (GType type, gboolean * is_pointer)
478 const gchar *type_name;
481 type_name = g_type_name (type);
495 /* These all have normal C type names so they are OK. */
499 /* A GtkString is really a gchar*. */
505 /* We use a gint for both of these. Hopefully a subtype with a decent
506 name will be registered and used instead, as GTK+ does itself. */
510 /* The boxed type shouldn't be used itself, only subtypes. Though we
511 return 'gpointer' just in case. */
515 /* A GParam is really a GParamSpec*. */
523 /* For all GObject subclasses we can use the class name with a "*",
524 e.g. 'GtkWidget *'. */
525 if (g_type_is_a (type, G_TYPE_OBJECT))
528 if (G_TYPE_IS_CLASSED (type))
531 /* All boxed subtypes will be pointers as well. */
532 if (g_type_is_a (type, G_TYPE_BOXED))
535 /* All pointer subtypes will be pointers as well. */
536 if (g_type_is_a (type, G_TYPE_POINTER))
544 get_gdk_event (const gchar * signal_name)
546 static const gchar *GbGDKEvents[] =
548 "button_press_event", "GdkEventButton",
549 "button_release_event", "GdkEventButton",
550 "motion_notify_event", "GdkEventMotion",
551 "delete_event", "GdkEvent",
552 "destroy_event", "GdkEvent",
553 "expose_event", "GdkEventExpose",
554 "key_press_event", "GdkEventKey",
555 "key_release_event", "GdkEventKey",
556 "enter_notify_event", "GdkEventCrossing",
557 "leave_notify_event", "GdkEventCrossing",
558 "configure_event", "GdkEventConfigure",
559 "focus_in_event", "GdkEventFocus",
560 "focus_out_event", "GdkEventFocus",
561 "map_event", "GdkEvent",
562 "unmap_event", "GdkEvent",
563 "property_notify_event", "GdkEventProperty",
564 "selection_clear_event", "GdkEventSelection",
565 "selection_request_event", "GdkEventSelection",
566 "selection_notify_event", "GdkEventSelection",
567 "proximity_in_event", "GdkEventProximity",
568 "proximity_out_event", "GdkEventProximity",
569 "drag_begin_event", "GdkEventDragBegin",
570 "drag_request_event", "GdkEventDragRequest",
571 "drag_end_event", "GdkEventDragRequest",
572 "drop_enter_event", "GdkEventDropEnter",
573 "drop_leave_event", "GdkEventDropLeave",
574 "drop_data_available_event", "GdkEventDropDataAvailable",
575 "other_event", "GdkEventOther",
576 "client_event", "GdkEventClient",
577 "no_expose_event", "GdkEventNoExpose",
578 "visibility_notify_event", "GdkEventVisibility",
579 "window_state_event", "GdkEventWindowState",
580 "scroll_event", "GdkEventScroll",
586 for (i = 0; GbGDKEvents[i]; i += 2)
588 if (!strcmp (signal_name, GbGDKEvents[i]))
589 return GbGDKEvents[i + 1];
595 /* This returns argument names to use for some known GTK signals.
596 It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
597 'select_row' and it returns a pointer to an array of argument types and
599 static const gchar **
600 lookup_signal_arg_names (const gchar * type, const gchar * signal_name)
602 /* Each arg array starts with the object type name and the signal name,
603 and then signal arguments follow. */
604 static const gchar *GbArgTable[][16] =
606 {"GtkCList", "select_row",
609 "GdkEventButton *event"},
610 {"GtkCList", "unselect_row",
613 "GdkEventButton *event"},
614 {"GtkCList", "click_column",
617 {"GtkCList", "resize_column",
621 {"GtkCList", "extend_selection",
622 "GtkScrollType scroll_type",
624 "gboolean auto_start_selection"},
625 {"GtkCList", "scroll_vertical",
626 "GtkScrollType scroll_type",
628 {"GtkCList", "scroll_horizontal",
629 "GtkScrollType scroll_type",
632 {"GtkCTree", "tree_select_row",
633 "GtkCTreeNode *node",
635 {"GtkCTree", "tree_unselect_row",
636 "GtkCTreeNode *node",
638 {"GtkCTree", "tree_expand",
639 "GtkCTreeNode *node"},
640 {"GtkCTree", "tree_collapse",
641 "GtkCTreeNode *node"},
642 {"GtkCTree", "tree_move",
643 "GtkCTreeNode *node",
644 "GtkCTreeNode *new_parent",
645 "GtkCTreeNode *new_sibling"},
646 {"GtkCTree", "change_focus_row_expansion",
647 "GtkCTreeExpansionType expansion"},
649 {"GtkEditable", "insert_text",
651 "gint new_text_length",
653 {"GtkEditable", "delete_text",
656 {"GtkEditable", "set_editable",
657 "gboolean is_editable"},
658 {"GtkEditable", "move_cursor",
661 {"GtkEditable", "move_word",
663 {"GtkEditable", "move_page",
666 {"GtkEditable", "move_to_row",
668 {"GtkEditable", "move_to_column",
671 {"GtkEditable", "kill_char",
673 {"GtkEditable", "kill_word",
675 {"GtkEditable", "kill_line",
679 {"GtkInputDialog", "enable_device",
680 "GdkDevice *deviceid"},
681 {"GtkInputDialog", "disable_device",
682 "GdkDevice *deviceid"},
684 {"GtkListItem", "extend_selection",
685 "GtkScrollType scroll_type",
687 "gboolean auto_start_selection"},
688 {"GtkListItem", "scroll_vertical",
689 "GtkScrollType scroll_type",
691 {"GtkListItem", "scroll_horizontal",
692 "GtkScrollType scroll_type",
695 {"GtkMenuShell", "move_current",
696 "GtkMenuDirectionType direction"},
697 {"GtkMenuShell", "activate_current",
698 "gboolean force_hide"},
701 {"GtkNotebook", "switch_page",
702 "GtkNotebookPage *page",
704 {"GtkStatusbar", "text_pushed",
707 {"GtkStatusbar", "text_popped",
710 {"GtkTipsQuery", "widget_entered",
713 "gchar *tip_private"},
714 {"GtkTipsQuery", "widget_selected",
717 "gchar *tip_private",
718 "GdkEventButton *event"},
719 {"GtkToolbar", "orientation_changed",
720 "GtkOrientation orientation"},
721 {"GtkToolbar", "style_changed",
722 "GtkToolbarStyle style"},
723 {"GtkWidget", "draw",
724 "GdkRectangle *area"},
725 {"GtkWidget", "size_request",
726 "GtkRequisition *requisition"},
727 {"GtkWidget", "size_allocate",
728 "GtkAllocation *allocation"},
729 {"GtkWidget", "state_changed",
730 "GtkStateType state"},
731 {"GtkWidget", "style_set",
732 "GtkStyle *previous_style"},
734 {"GtkWidget", "install_accelerator",
735 "gchar *signal_name",
739 {"GtkWidget", "add_accelerator",
740 "guint accel_signal_id",
741 "GtkAccelGroup *accel_group",
743 "GdkModifierType accel_mods",
744 "GtkAccelFlags accel_flags"},
746 {"GtkWidget", "parent_set",
747 "GtkObject *old_parent"},
749 {"GtkWidget", "remove_accelerator",
750 "GtkAccelGroup *accel_group",
752 "GdkModifierType accel_mods"},
753 {"GtkWidget", "debug_msg",
755 {"GtkWindow", "move_resize",
760 {"GtkWindow", "set_focus",
761 "GtkWidget *widget"},
763 {"GtkWidget", "selection_get",
764 "GtkSelectionData *data",
767 {"GtkWidget", "selection_received",
768 "GtkSelectionData *data",
771 {"GtkWidget", "drag_begin",
772 "GdkDragContext *drag_context"},
773 {"GtkWidget", "drag_end",
774 "GdkDragContext *drag_context"},
775 {"GtkWidget", "drag_data_delete",
776 "GdkDragContext *drag_context"},
777 {"GtkWidget", "drag_leave",
778 "GdkDragContext *drag_context",
780 {"GtkWidget", "drag_motion",
781 "GdkDragContext *drag_context",
785 {"GtkWidget", "drag_drop",
786 "GdkDragContext *drag_context",
790 {"GtkWidget", "drag_data_get",
791 "GdkDragContext *drag_context",
792 "GtkSelectionData *data",
795 {"GtkWidget", "drag_data_received",
796 "GdkDragContext *drag_context",
799 "GtkSelectionData *data",
808 for (i = 0; GbArgTable[i][0]; i++)
811 if (!strcmp (type, GbArgTable[i][0])
812 && !strcmp (signal_name, GbArgTable[i][1]))
813 return &GbArgTable[i][2];
819 /* This outputs the hierarchy of all objects which have been initialized,
820 i.e. by calling their XXX_get_type() initialization function. */
822 output_object_hierarchy (void)
827 fp = fopen (hierarchy_filename, "w");
830 g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, strerror(errno));
833 output_hierarchy (fp, G_TYPE_OBJECT, 0);
834 output_hierarchy (fp, G_TYPE_INTERFACE, 0);
836 for (i=0; object_types[i]; i++) {
837 if (!g_type_parent (object_types[i]) &&
838 (object_types[i] != G_TYPE_OBJECT) &&
839 (object_types[i] != G_TYPE_INTERFACE)
841 output_hierarchy (fp, object_types[i], 0);
848 /* This is called recursively to output the hierarchy of a widget. */
850 output_hierarchy (FILE *fp,
861 for (i = 0; i < level; i++)
863 fprintf (fp, g_type_name (type));
866 children = g_type_children (type, &n_children);
868 for (i=0; i < n_children; i++)
869 output_hierarchy (fp, children[i], level + 1);
874 static void output_object_interfaces (void)
878 fp = fopen (interfaces_filename, "w");
881 g_warning ("Couldn't open output file: %s : %s", interfaces_filename, strerror(errno));
884 output_interfaces (fp, G_TYPE_OBJECT);
889 output_interfaces (FILE *fp,
893 GType *children, *interfaces;
894 guint n_children, n_interfaces;
899 interfaces = g_type_interfaces (type, &n_interfaces);
901 if (n_interfaces > 0)
903 fprintf (fp, g_type_name (type));
904 for (i=0; i < n_interfaces; i++)
905 fprintf (fp, " %s", g_type_name (interfaces[i]));
910 children = g_type_children (type, &n_children);
912 for (i=0; i < n_children; i++)
913 output_interfaces (fp, children[i]);
918 static void output_interface_prerequisites (void)
922 fp = fopen (prerequisites_filename, "w");
925 g_warning ("Couldn't open output file: %s : %s", prerequisites_filename, strerror(errno));
928 output_prerequisites (fp, G_TYPE_INTERFACE);
933 output_prerequisites (FILE *fp,
936 #if GLIB_CHECK_VERSION(2,1,0)
938 GType *children, *prerequisites;
939 guint n_children, n_prerequisites;
944 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
946 if (n_prerequisites > 0)
948 fprintf (fp, g_type_name (type));
949 for (i=0; i < n_prerequisites; i++)
950 fprintf (fp, " %s", g_type_name (prerequisites[i]));
953 g_free (prerequisites);
955 children = g_type_children (type, &n_children);
957 for (i=0; i < n_children; i++)
958 output_prerequisites (fp, children[i]);
970 fp = fopen (args_filename, "w");
973 g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno));
977 for (i = 0; object_types[i]; i++) {
978 output_object_args (fp, object_types[i]);
985 compare_param_specs (const void *a, const void *b)
987 GParamSpec *spec_a = *(GParamSpec **)a;
988 GParamSpec *spec_b = *(GParamSpec **)b;
990 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
993 /* Its common to have unsigned properties restricted
994 * to the signed range. Therefore we make this look
995 * a bit nicer by spelling out the max constants.
998 /* Don't use "==" with floats, it might trigger a gcc warning. */
999 #define GTKDOC_COMPARE_FLOAT(x, y) (x <= y && x >= y)
1002 describe_double_constant (gdouble value)
1006 if (GTKDOC_COMPARE_FLOAT (value, G_MAXDOUBLE))
1007 desc = g_strdup ("G_MAXDOUBLE");
1008 else if (GTKDOC_COMPARE_FLOAT (value, G_MINDOUBLE))
1009 desc = g_strdup ("G_MINDOUBLE");
1010 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXDOUBLE))
1011 desc = g_strdup ("-G_MAXDOUBLE");
1012 else if (GTKDOC_COMPARE_FLOAT (value, G_MAXFLOAT))
1013 desc = g_strdup ("G_MAXFLOAT");
1014 else if (GTKDOC_COMPARE_FLOAT (value, G_MINFLOAT))
1015 desc = g_strdup ("G_MINFLOAT");
1016 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXFLOAT))
1017 desc = g_strdup ("-G_MAXFLOAT");
1019 desc = g_strdup_printf ("%lg", value);
1025 describe_signed_constant (gint64 value)
1029 if (value == G_MAXINT)
1030 desc = g_strdup ("G_MAXINT");
1031 else if (value == G_MININT)
1032 desc = g_strdup ("G_MININT");
1033 else if (value == G_MAXUINT)
1034 desc = g_strdup ("G_MAXUINT");
1035 else if (value == G_MAXLONG)
1036 desc = g_strdup ("G_MAXLONG");
1037 else if (value == G_MINLONG)
1038 desc = g_strdup ("G_MINLONG");
1039 else if (value == G_MAXULONG)
1040 desc = g_strdup ("G_MAXULONG");
1041 else if (value == G_MAXINT64)
1042 desc = g_strdup ("G_MAXINT64");
1043 else if (value == G_MININT64)
1044 desc = g_strdup ("G_MININT64");
1046 desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
1052 describe_unsigned_constant (guint64 value)
1056 if (value == G_MAXINT)
1057 desc = g_strdup ("G_MAXINT");
1058 else if (value == G_MININT)
1059 desc = g_strdup ("G_MININT");
1060 else if (value == G_MAXUINT)
1061 desc = g_strdup ("G_MAXUINT");
1062 else if (value == G_MAXLONG)
1063 desc = g_strdup ("G_MAXLONG");
1064 else if (value == G_MINLONG)
1065 desc = g_strdup ("G_MINLONG");
1066 else if (value == G_MAXULONG)
1067 desc = g_strdup ("G_MAXULONG");
1068 else if (value == G_MAXINT64)
1069 desc = g_strdup ("G_MAXINT64");
1070 else if (value == G_MININT64)
1071 desc = g_strdup ("G_MININT64");
1072 else if (value == G_MAXUINT64)
1073 desc = g_strdup ("G_MAXUINT64");
1075 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
1081 describe_type (GParamSpec *spec)
1087 if (G_IS_PARAM_SPEC_CHAR (spec))
1089 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1091 lower = describe_signed_constant (pspec->minimum);
1092 upper = describe_signed_constant (pspec->maximum);
1093 if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
1094 desc = g_strdup ("");
1095 else if (pspec->minimum == G_MININT8)
1096 desc = g_strdup_printf ("<= %s", upper);
1097 else if (pspec->maximum == G_MAXINT8)
1098 desc = g_strdup_printf (">= %s", lower);
1100 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1104 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1106 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1108 lower = describe_unsigned_constant (pspec->minimum);
1109 upper = describe_unsigned_constant (pspec->maximum);
1110 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
1111 desc = g_strdup ("");
1112 else if (pspec->minimum == 0)
1113 desc = g_strdup_printf ("<= %s", upper);
1114 else if (pspec->maximum == G_MAXUINT8)
1115 desc = g_strdup_printf (">= %s", lower);
1117 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1121 else if (G_IS_PARAM_SPEC_INT (spec))
1123 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1125 lower = describe_signed_constant (pspec->minimum);
1126 upper = describe_signed_constant (pspec->maximum);
1127 if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
1128 desc = g_strdup ("");
1129 else if (pspec->minimum == G_MININT)
1130 desc = g_strdup_printf ("<= %s", upper);
1131 else if (pspec->maximum == G_MAXINT)
1132 desc = g_strdup_printf (">= %s", lower);
1134 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1138 else if (G_IS_PARAM_SPEC_UINT (spec))
1140 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1142 lower = describe_unsigned_constant (pspec->minimum);
1143 upper = describe_unsigned_constant (pspec->maximum);
1144 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
1145 desc = g_strdup ("");
1146 else if (pspec->minimum == 0)
1147 desc = g_strdup_printf ("<= %s", upper);
1148 else if (pspec->maximum == G_MAXUINT)
1149 desc = g_strdup_printf (">= %s", lower);
1151 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1155 else if (G_IS_PARAM_SPEC_LONG (spec))
1157 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1159 lower = describe_signed_constant (pspec->minimum);
1160 upper = describe_signed_constant (pspec->maximum);
1161 if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
1162 desc = g_strdup ("");
1163 else if (pspec->minimum == G_MINLONG)
1164 desc = g_strdup_printf ("<= %s", upper);
1165 else if (pspec->maximum == G_MAXLONG)
1166 desc = g_strdup_printf (">= %s", lower);
1168 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1172 else if (G_IS_PARAM_SPEC_ULONG (spec))
1174 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1177 lower = describe_unsigned_constant (pspec->minimum);
1178 upper = describe_unsigned_constant (pspec->maximum);
1179 if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
1180 desc = g_strdup ("");
1181 else if (pspec->minimum == 0)
1182 desc = g_strdup_printf ("<= %s", upper);
1183 else if (pspec->maximum == G_MAXULONG)
1184 desc = g_strdup_printf (">= %s", lower);
1186 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1190 else if (G_IS_PARAM_SPEC_INT64 (spec))
1192 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1194 lower = describe_signed_constant (pspec->minimum);
1195 upper = describe_signed_constant (pspec->maximum);
1196 if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
1197 desc = g_strdup ("");
1198 else if (pspec->minimum == G_MININT64)
1199 desc = g_strdup_printf ("<= %s", upper);
1200 else if (pspec->maximum == G_MAXINT64)
1201 desc = g_strdup_printf (">= %s", lower);
1203 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1207 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1209 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1211 lower = describe_unsigned_constant (pspec->minimum);
1212 upper = describe_unsigned_constant (pspec->maximum);
1213 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
1214 desc = g_strdup ("");
1215 else if (pspec->minimum == 0)
1216 desc = g_strdup_printf ("<= %s", upper);
1217 else if (pspec->maximum == G_MAXUINT64)
1218 desc = g_strdup_printf (">= %s", lower);
1220 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1224 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1226 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1228 lower = describe_double_constant (pspec->minimum);
1229 upper = describe_double_constant (pspec->maximum);
1230 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXFLOAT))
1232 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1233 desc = g_strdup ("");
1235 desc = g_strdup_printf ("<= %s", upper);
1237 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1238 desc = g_strdup_printf (">= %s", lower);
1240 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1244 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1246 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1248 lower = describe_double_constant (pspec->minimum);
1249 upper = describe_double_constant (pspec->maximum);
1250 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXDOUBLE))
1252 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1253 desc = g_strdup ("");
1255 desc = g_strdup_printf ("<= %s", upper);
1257 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1258 desc = g_strdup_printf (">= %s", lower);
1260 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1266 desc = g_strdup ("");
1273 describe_default (GParamSpec *spec)
1277 if (G_IS_PARAM_SPEC_CHAR (spec))
1279 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1281 desc = g_strdup_printf ("%d", pspec->default_value);
1283 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1285 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1287 desc = g_strdup_printf ("%u", pspec->default_value);
1289 else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
1291 GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
1293 desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
1295 else if (G_IS_PARAM_SPEC_INT (spec))
1297 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1299 desc = g_strdup_printf ("%d", pspec->default_value);
1301 else if (G_IS_PARAM_SPEC_UINT (spec))
1303 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1305 desc = g_strdup_printf ("%u", pspec->default_value);
1307 else if (G_IS_PARAM_SPEC_LONG (spec))
1309 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1311 desc = g_strdup_printf ("%ld", pspec->default_value);
1313 else if (G_IS_PARAM_SPEC_LONG (spec))
1315 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1317 desc = g_strdup_printf ("%lu", pspec->default_value);
1319 else if (G_IS_PARAM_SPEC_INT64 (spec))
1321 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1323 desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
1325 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1327 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1329 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
1331 else if (G_IS_PARAM_SPEC_UNICHAR (spec))
1333 GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
1335 if (g_unichar_isprint (pspec->default_value))
1336 desc = g_strdup_printf ("'%c'", pspec->default_value);
1338 desc = g_strdup_printf ("%u", pspec->default_value);
1340 else if (G_IS_PARAM_SPEC_ENUM (spec))
1342 GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
1344 GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
1346 desc = g_strdup_printf ("%s", value->value_name);
1348 desc = g_strdup_printf ("%d", pspec->default_value);
1350 else if (G_IS_PARAM_SPEC_FLAGS (spec))
1352 GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
1353 guint default_value;
1356 default_value = pspec->default_value;
1357 acc = g_string_new ("");
1359 while (default_value)
1361 GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
1367 g_string_append (acc, "|");
1368 g_string_append (acc, value->value_name);
1370 default_value &= ~value->value;
1373 if (default_value == 0)
1374 desc = g_string_free (acc, FALSE);
1377 desc = g_strdup_printf ("%d", pspec->default_value);
1378 g_string_free (acc, TRUE);
1381 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1383 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1385 desc = g_strdup_printf ("%g", pspec->default_value);
1387 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1389 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1391 desc = g_strdup_printf ("%lg", pspec->default_value);
1393 else if (G_IS_PARAM_SPEC_STRING (spec))
1395 GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
1397 if (pspec->default_value)
1399 gchar *esc = g_strescape (pspec->default_value, NULL);
1401 desc = g_strdup_printf ("\\"%s\\"", esc);
1406 desc = g_strdup_printf ("NULL");
1410 desc = g_strdup ("");
1418 output_object_args (FILE *fp, GType object_type)
1421 const gchar *object_class_name;
1423 gchar flags[16], *pos;
1424 GParamSpec **properties;
1426 gboolean child_prop;
1427 gboolean style_prop;
1429 gchar *default_value;
1431 if (G_TYPE_IS_CLASSED (object_type))
1433 class = g_type_class_peek (object_type);
1437 properties = g_object_class_list_properties (class, &n_properties);
1439 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
1440 else if (G_TYPE_IS_INTERFACE (object_type))
1442 class = g_type_default_interface_ref (object_type);
1447 properties = g_object_interface_list_properties (class, &n_properties);
1453 object_class_name = g_type_name (object_type);
1459 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
1460 for (arg = 0; arg < n_properties; arg++)
1462 GParamSpec *spec = properties[arg];
1463 const gchar *nick, *blurb, *dot;
1465 if (spec->owner_type != object_type)
1469 /* We use one-character flags for simplicity. */
1470 if (child_prop && !style_prop)
1474 if (spec->flags & G_PARAM_READABLE)
1476 if (spec->flags & G_PARAM_WRITABLE)
1478 if (spec->flags & G_PARAM_CONSTRUCT)
1480 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
1484 nick = g_param_spec_get_nick (spec);
1485 blurb = g_param_spec_get_blurb (spec);
1489 int str_len = strlen (blurb);
1490 if (str_len > 0 && blurb[str_len - 1] != '.')
1494 type_desc = describe_type (spec);
1495 default_value = describe_default (spec);
1496 fprintf (fp, "<ARG>\\n<NAME>%s::%s</NAME>\\n<TYPE>%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",
1497 object_class_name, g_param_spec_get_name (spec), g_type_name (spec->value_type), type_desc, flags, nick ? nick : "(null)", blurb ? blurb : "(null)", dot, default_value);
1499 g_free (default_value);
1502 g_free (properties);
1504 #ifdef GTK_IS_CONTAINER_CLASS
1505 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
1506 properties = gtk_container_class_list_child_properties (class, &n_properties);
1512 #ifdef GTK_IS_WIDGET_CLASS
1513 #if GTK_CHECK_VERSION(2,1,0)
1514 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
1515 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1529 # Compile and run our file
1531 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
1532 $LD = $ENV{LD} ? $ENV{LD} : $CC;
1533 $CFLAGS = $ENV{CFLAGS} ? "$ENV{CFLAGS} -Wall -g" : "-Wall -g";
1534 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
1537 if ($CC =~ /libtool/) {
1538 $o_file = "$MODULE-scan.lo"
1540 $o_file = "$MODULE-scan.o"
1543 print "gtk-doc: Compiling scanner\n";
1544 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c";
1545 system($command) == 0 or die "Compilation of scanner failed: $!\n";
1547 print "gtk-doc: Linking scanner\n";
1548 $command = "$LD -o $MODULE-scan $o_file $LDFLAGS";
1549 system($command) == 0 or die "Linking of scanner failed: $!\n";
1551 print "gtk-doc: Running scanner $MODULE-scan\n";
1552 system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n";
1554 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
1556 #&UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
1557 #&UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
1558 #&UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
1559 #&UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
1560 #&UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);