4 # gtk-doc - GTK DocBook documentation generator.
5 # Copyright (C) 1998 Damon Chaplin
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 # This gets information about object heirarchies and signals
24 # by compiling a small C program. CFLAGS and LDFLAGS must be
25 # set appropriately before running this script.
27 # NOTE: the lookup_signal_arg_names() function contains the argument names of
28 # standard GTK signal handlers. This may need to be updated for new
29 # GTK signals or Gnome widget signals.
33 unshift @INC, '@PACKAGE_DATA_DIR@';
34 require "gtkdoc-common.pl";
38 # name of documentation module
43 my $TYPE_INIT_FUNC="g_type_init(); g_type_class_ref(G_TYPE_OBJECT)";
44 my $QUERY_CHILD_PROPERTIES;
46 # --nogtkinit is deprecated, as it is the default now anyway.
47 %optctl = (module => \$MODULE,
48 types => \$TYPES_FILE,
49 nogtkinit => \$NO_GTK_INIT,
50 'type-init-func' => \$TYPE_INIT_FUNC,
51 'query-child-properties' => \$QUERY_CHILD_PROPERTIES,
52 'output-dir' => \$OUTPUT_DIR,
53 'version' => \$PRINT_VERSION,
54 'help' => \$PRINT_HELP);
56 GetOptions(\%optctl, "module=s", "types:s", "output-dir:s", "nogtkinit", "type-init-func:s", "query-child-properties:s", "version", "help");
59 # Do nothing. This just avoids a warning.
72 print "gtkdoc-scangobj version @VERSION@\n";
73 print "\n--module=MODULE_NAME Name of the doc module being parsed";
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--query-child-properties=FUNC A function that returns a list of child";
77 print "\n properties for a class";
78 print "\n--output-dir=DIRNAME The directory where the results are stored";
79 print "\n--version Print the version of this program";
80 print "\n--help Print this help\n";
84 $OUTPUT_DIR = $OUTPUT_DIR ? $OUTPUT_DIR : ".";
86 $TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$OUTPUT_DIR/$MODULE.types";
88 open (TYPES, $TYPES_FILE) || die "Cannot open $TYPES_FILE: $!\n";
89 open (OUTPUT, ">$MODULE-scan.c") || die "Cannot open $MODULE-scan.c: $!\n";
91 my $old_signals_filename = "$OUTPUT_DIR/$MODULE.signals";
92 my $new_signals_filename = "$OUTPUT_DIR/$MODULE.signals.new";
93 my $old_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy";
94 my $new_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy.new";
95 my $old_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces";
96 my $new_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces.new";
97 my $old_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites";
98 my $new_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites.new";
99 my $old_args_filename = "$OUTPUT_DIR/$MODULE.args";
100 my $new_args_filename = "$OUTPUT_DIR/$MODULE.args.new";
102 # write a C program to scan the types
110 } elsif (/^gnome_keyring_item_info_get_type$/) {
111 # HACK: This isn't really a GObject type so skip it.
123 $ntypes = @types + 1;
130 #include <glib-object.h>
135 print OUTPUT $includes;
138 print OUTPUT "extern GType $_ (void);\n";
142 if ($QUERY_CHILD_PROPERTIES) {
144 extern GParamSpec** $QUERY_CHILD_PROPERTIES (gpointer class, guint *n_properties);
150 #ifdef GTK_IS_WIDGET_CLASS
151 #include <gtk/gtkversion.h>
153 GType object_types[$ntypes];
156 get_object_types (void)
162 print OUTPUT " object_types[i++] = $_ ();\n";
168 /* Need to make sure all the types are loaded in and initialize
169 * their signals and properties.
171 for (i=0; object_types[i]; i++)
173 if (G_TYPE_IS_CLASSED (object_types[i]))
174 g_type_class_ref (object_types[i]);
175 if (G_TYPE_IS_INTERFACE (object_types[i]))
176 g_type_default_interface_ref (object_types[i]);
183 * This uses GObject type functions to output signal prototypes and the object
187 /* The output files */
188 const gchar *signals_filename = "$new_signals_filename";
189 const gchar *hierarchy_filename = "$new_hierarchy_filename";
190 const gchar *interfaces_filename = "$new_interfaces_filename";
191 const gchar *prerequisites_filename = "$new_prerequisites_filename";
192 const gchar *args_filename = "$new_args_filename";
195 static void output_signals (void);
196 static void output_object_signals (FILE *fp,
198 static void output_object_signal (FILE *fp,
199 const gchar *object_class_name,
201 static const gchar * get_type_name (GType type,
202 gboolean * is_pointer);
203 static const gchar * get_gdk_event (const gchar * signal_name);
204 static const gchar ** lookup_signal_arg_names (const gchar * type,
205 const gchar * signal_name);
207 static void output_object_hierarchy (void);
208 static void output_hierarchy (FILE *fp,
212 static void output_object_interfaces (void);
213 static void output_interfaces (FILE *fp,
216 static void output_interface_prerequisites (void);
217 static void output_prerequisites (FILE *fp,
220 static void output_args (void);
221 static void output_object_args (FILE *fp, GType object_type);
224 main (int argc, char *argv[])
226 /* Silence the compiler: */
227 if (argv != argv) argc = argc;
234 output_object_hierarchy ();
235 output_object_interfaces ();
236 output_interface_prerequisites ();
244 output_signals (void)
249 fp = fopen (signals_filename, "w");
252 g_warning ("Couldn't open output file: %s : %s", signals_filename, strerror(errno));
256 for (i = 0; object_types[i]; i++)
257 output_object_signals (fp, object_types[i]);
263 compare_signals (const void *a, const void *b)
265 const guint *signal_a = a;
266 const guint *signal_b = b;
268 return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b));
271 /* This outputs all the signals of one object. */
273 output_object_signals (FILE *fp, GType object_type)
275 const gchar *object_class_name;
276 guint *signals, n_signals;
279 if (G_TYPE_IS_INSTANTIATABLE (object_type) ||
280 G_TYPE_IS_INTERFACE (object_type))
283 object_class_name = g_type_name (object_type);
285 signals = g_signal_list_ids (object_type, &n_signals);
286 qsort (signals, n_signals, sizeof (guint), compare_signals);
288 for (sig = 0; sig < n_signals; sig++)
290 output_object_signal (fp, object_class_name, signals[sig]);
297 /* This outputs one signal. */
299 output_object_signal (FILE *fp,
300 const gchar *object_name,
303 GSignalQuery query_info;
304 const gchar *type_name, *ret_type, *object_arg, *arg_name;
305 gchar *pos, *object_arg_lower;
307 gchar ret_type_buffer[1024], buffer[1024];
309 const gchar **arg_names;
310 gint param_num, widget_num, event_num, callback_num;
312 gchar signal_name[128];
315 /* g_print ("Object: %s Signal: %u\\n", object_name, signal_id);*/
318 widget_num = event_num = callback_num = 0;
320 g_signal_query (signal_id, &query_info);
322 /* Output the return type and function name. */
323 ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
324 sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
326 /* Output the signal object type and the argument name. We assume the
327 type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
328 convert to lower case for the argument name. */
330 sprintf (pos, "%s ", object_name);
333 if (!strncmp (object_name, "Gtk", 3))
334 object_arg = object_name + 3;
335 else if (!strncmp (object_name, "Gnome", 5))
336 object_arg = object_name + 5;
338 object_arg = object_name;
340 object_arg_lower = g_ascii_strdown (object_arg, -1);
341 sprintf (pos, "*%s\\n", object_arg_lower);
343 if (!strncmp (object_arg_lower, "widget", 6))
345 g_free(object_arg_lower);
347 /* Convert signal name to use underscores rather than dashes '-'. */
348 strcpy (signal_name, query_info.signal_name);
349 for (i = 0; signal_name[i]; i++)
351 if (signal_name[i] == '-')
352 signal_name[i] = '_';
355 /* Output the signal parameters. */
356 arg_names = lookup_signal_arg_names (object_name, signal_name);
358 for (param = 0; param < query_info.n_params; param++)
362 sprintf (pos, "%s\\n", arg_names[param]);
367 type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
369 /* Most arguments to the callback are called "arg1", "arg2", etc.
370 GdkWidgets are called "widget", "widget2", ...
371 GdkEvents are called "event", "event2", ...
372 GtkCallbacks are called "callback", "callback2", ... */
373 if (!strcmp (type_name, "GtkWidget"))
376 arg_num = &widget_num;
378 else if (!strcmp (type_name, "GdkEvent"))
380 type_name = get_gdk_event (signal_name);
382 arg_num = &event_num;
385 else if (!strcmp (type_name, "GtkCallback")
386 || !strcmp (type_name, "GtkCCallback"))
388 arg_name = "callback";
389 arg_num = &callback_num;
394 arg_num = ¶m_num;
396 sprintf (pos, "%s ", type_name);
399 if (!arg_num || *arg_num == 0)
400 sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
402 sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
417 /* We use one-character flags for simplicity. */
418 if (query_info.signal_flags & G_SIGNAL_RUN_FIRST)
420 if (query_info.signal_flags & G_SIGNAL_RUN_LAST)
422 if (query_info.signal_flags & G_SIGNAL_RUN_CLEANUP)
424 if (query_info.signal_flags & G_SIGNAL_NO_RECURSE)
426 if (query_info.signal_flags & G_SIGNAL_DETAILED)
428 if (query_info.signal_flags & G_SIGNAL_ACTION)
430 if (query_info.signal_flags & G_SIGNAL_NO_HOOKS)
435 "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n<FLAGS>%s</FLAGS>\\n%s</SIGNAL>\\n\\n",
436 object_name, query_info.signal_name, ret_type_buffer, flags, buffer);
440 /* Returns the type name to use for a signal argument or return value, given
441 the GtkType from the signal info. It also sets is_pointer to TRUE if the
442 argument needs a '*' since it is a pointer. */
444 get_type_name (GType type, gboolean * is_pointer)
446 const gchar *type_name;
449 type_name = g_type_name (type);
463 /* These all have normal C type names so they are OK. */
467 /* A GtkString is really a gchar*. */
473 /* We use a gint for both of these. Hopefully a subtype with a decent
474 name will be registered and used instead, as GTK+ does itself. */
478 /* The boxed type shouldn't be used itself, only subtypes. Though we
479 return 'gpointer' just in case. */
483 /* A GParam is really a GParamSpec*. */
491 /* For all GObject subclasses we can use the class name with a "*",
492 e.g. 'GtkWidget *'. */
493 if (g_type_is_a (type, G_TYPE_OBJECT))
496 /* Also catch non GObject root types */
497 if (G_TYPE_IS_CLASSED (type))
500 /* All boxed subtypes will be pointers as well. */
501 if (g_type_is_a (type, G_TYPE_BOXED))
504 /* All pointer subtypes will be pointers as well. */
505 if (g_type_is_a (type, G_TYPE_POINTER))
508 /* But enums are not */
509 if (g_type_is_a (type, G_TYPE_ENUM) ||
510 g_type_is_a (type, G_TYPE_FLAGS))
518 get_gdk_event (const gchar * signal_name)
520 static const gchar *GbGDKEvents[] =
522 "button_press_event", "GdkEventButton",
523 "button_release_event", "GdkEventButton",
524 "motion_notify_event", "GdkEventMotion",
525 "delete_event", "GdkEvent",
526 "destroy_event", "GdkEvent",
527 "expose_event", "GdkEventExpose",
528 "key_press_event", "GdkEventKey",
529 "key_release_event", "GdkEventKey",
530 "enter_notify_event", "GdkEventCrossing",
531 "leave_notify_event", "GdkEventCrossing",
532 "configure_event", "GdkEventConfigure",
533 "focus_in_event", "GdkEventFocus",
534 "focus_out_event", "GdkEventFocus",
535 "map_event", "GdkEvent",
536 "unmap_event", "GdkEvent",
537 "property_notify_event", "GdkEventProperty",
538 "selection_clear_event", "GdkEventSelection",
539 "selection_request_event", "GdkEventSelection",
540 "selection_notify_event", "GdkEventSelection",
541 "proximity_in_event", "GdkEventProximity",
542 "proximity_out_event", "GdkEventProximity",
543 "drag_begin_event", "GdkEventDragBegin",
544 "drag_request_event", "GdkEventDragRequest",
545 "drag_end_event", "GdkEventDragRequest",
546 "drop_enter_event", "GdkEventDropEnter",
547 "drop_leave_event", "GdkEventDropLeave",
548 "drop_data_available_event", "GdkEventDropDataAvailable",
549 "other_event", "GdkEventOther",
550 "client_event", "GdkEventClient",
551 "no_expose_event", "GdkEventNoExpose",
552 "visibility_notify_event", "GdkEventVisibility",
553 "window_state_event", "GdkEventWindowState",
554 "scroll_event", "GdkEventScroll",
560 for (i = 0; GbGDKEvents[i]; i += 2)
562 if (!strcmp (signal_name, GbGDKEvents[i]))
563 return GbGDKEvents[i + 1];
569 /* This returns argument names to use for some known GTK signals.
570 It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
571 'select_row' and it returns a pointer to an array of argument types and
573 static const gchar **
574 lookup_signal_arg_names (const gchar * type, const gchar * signal_name)
576 /* Each arg array starts with the object type name and the signal name,
577 and then signal arguments follow. */
578 static const gchar *GbArgTable[][16] =
580 {"GtkCList", "select_row",
583 "GdkEventButton *event"},
584 {"GtkCList", "unselect_row",
587 "GdkEventButton *event"},
588 {"GtkCList", "click_column",
591 {"GtkCList", "resize_column",
595 {"GtkCList", "extend_selection",
596 "GtkScrollType scroll_type",
598 "gboolean auto_start_selection"},
599 {"GtkCList", "scroll_vertical",
600 "GtkScrollType scroll_type",
602 {"GtkCList", "scroll_horizontal",
603 "GtkScrollType scroll_type",
606 {"GtkCTree", "tree_select_row",
607 "GtkCTreeNode *node",
609 {"GtkCTree", "tree_unselect_row",
610 "GtkCTreeNode *node",
612 {"GtkCTree", "tree_expand",
613 "GtkCTreeNode *node"},
614 {"GtkCTree", "tree_collapse",
615 "GtkCTreeNode *node"},
616 {"GtkCTree", "tree_move",
617 "GtkCTreeNode *node",
618 "GtkCTreeNode *new_parent",
619 "GtkCTreeNode *new_sibling"},
620 {"GtkCTree", "change_focus_row_expansion",
621 "GtkCTreeExpansionType expansion"},
623 {"GtkEditable", "insert_text",
625 "gint new_text_length",
627 {"GtkEditable", "delete_text",
630 {"GtkEditable", "set_editable",
631 "gboolean is_editable"},
632 {"GtkEditable", "move_cursor",
635 {"GtkEditable", "move_word",
637 {"GtkEditable", "move_page",
640 {"GtkEditable", "move_to_row",
642 {"GtkEditable", "move_to_column",
645 {"GtkEditable", "kill_char",
647 {"GtkEditable", "kill_word",
649 {"GtkEditable", "kill_line",
653 {"GtkInputDialog", "enable_device",
654 "GdkDevice *deviceid"},
655 {"GtkInputDialog", "disable_device",
656 "GdkDevice *deviceid"},
658 {"GtkListItem", "extend_selection",
659 "GtkScrollType scroll_type",
661 "gboolean auto_start_selection"},
662 {"GtkListItem", "scroll_vertical",
663 "GtkScrollType scroll_type",
665 {"GtkListItem", "scroll_horizontal",
666 "GtkScrollType scroll_type",
669 {"GtkMenuShell", "move_current",
670 "GtkMenuDirectionType direction"},
671 {"GtkMenuShell", "activate_current",
672 "gboolean force_hide"},
675 {"GtkNotebook", "switch_page",
676 "GtkNotebookPage *page",
678 {"GtkStatusbar", "text_pushed",
681 {"GtkStatusbar", "text_popped",
684 {"GtkTipsQuery", "widget_entered",
687 "gchar *tip_private"},
688 {"GtkTipsQuery", "widget_selected",
691 "gchar *tip_private",
692 "GdkEventButton *event"},
693 {"GtkToolbar", "orientation_changed",
694 "GtkOrientation orientation"},
695 {"GtkToolbar", "style_changed",
696 "GtkToolbarStyle style"},
697 {"GtkWidget", "draw",
698 "GdkRectangle *area"},
699 {"GtkWidget", "size_request",
700 "GtkRequisition *requisition"},
701 {"GtkWidget", "size_allocate",
702 "GtkAllocation *allocation"},
703 {"GtkWidget", "state_changed",
704 "GtkStateType state"},
705 {"GtkWidget", "style_set",
706 "GtkStyle *previous_style"},
708 {"GtkWidget", "install_accelerator",
709 "gchar *signal_name",
713 {"GtkWidget", "add_accelerator",
714 "guint accel_signal_id",
715 "GtkAccelGroup *accel_group",
717 "GdkModifierType accel_mods",
718 "GtkAccelFlags accel_flags"},
720 {"GtkWidget", "parent_set",
721 "GtkObject *old_parent"},
723 {"GtkWidget", "remove_accelerator",
724 "GtkAccelGroup *accel_group",
726 "GdkModifierType accel_mods"},
727 {"GtkWidget", "debug_msg",
729 {"GtkWindow", "move_resize",
734 {"GtkWindow", "set_focus",
735 "GtkWidget *widget"},
737 {"GtkWidget", "selection_get",
738 "GtkSelectionData *data",
741 {"GtkWidget", "selection_received",
742 "GtkSelectionData *data",
745 {"GtkWidget", "drag_begin",
746 "GdkDragContext *drag_context"},
747 {"GtkWidget", "drag_end",
748 "GdkDragContext *drag_context"},
749 {"GtkWidget", "drag_data_delete",
750 "GdkDragContext *drag_context"},
751 {"GtkWidget", "drag_leave",
752 "GdkDragContext *drag_context",
754 {"GtkWidget", "drag_motion",
755 "GdkDragContext *drag_context",
759 {"GtkWidget", "drag_drop",
760 "GdkDragContext *drag_context",
764 {"GtkWidget", "drag_data_get",
765 "GdkDragContext *drag_context",
766 "GtkSelectionData *data",
769 {"GtkWidget", "drag_data_received",
770 "GdkDragContext *drag_context",
773 "GtkSelectionData *data",
782 for (i = 0; GbArgTable[i][0]; i++)
785 if (!strcmp (type, GbArgTable[i][0])
786 && !strcmp (signal_name, GbArgTable[i][1]))
787 return &GbArgTable[i][2];
793 /* This outputs the hierarchy of all objects which have been initialized,
794 i.e. by calling their XXX_get_type() initialization function. */
796 output_object_hierarchy (void)
801 fp = fopen (hierarchy_filename, "w");
804 g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, strerror(errno));
807 output_hierarchy (fp, G_TYPE_OBJECT, 0);
808 output_hierarchy (fp, G_TYPE_INTERFACE, 0);
810 for (i=0; object_types[i]; i++) {
811 if (!g_type_parent (object_types[i]) &&
812 (object_types[i] != G_TYPE_OBJECT) &&
813 (object_types[i] != G_TYPE_INTERFACE)
815 output_hierarchy (fp, object_types[i], 0);
822 /* This is called recursively to output the hierarchy of a widget. */
824 output_hierarchy (FILE *fp,
835 for (i = 0; i < level; i++)
837 fprintf (fp, "%s\\n", g_type_name (type));
839 children = g_type_children (type, &n_children);
841 for (i=0; i < n_children; i++)
842 output_hierarchy (fp, children[i], level + 1);
847 static void output_object_interfaces (void)
852 fp = fopen (interfaces_filename, "w");
855 g_warning ("Couldn't open output file: %s : %s", interfaces_filename, strerror(errno));
858 output_interfaces (fp, G_TYPE_OBJECT);
860 for (i = 0; object_types[i]; i++)
862 if (!g_type_parent (object_types[i]) &&
863 (object_types[i] != G_TYPE_OBJECT) &&
864 G_TYPE_IS_INSTANTIATABLE (object_types[i]))
866 output_interfaces (fp, object_types[i]);
873 output_interfaces (FILE *fp,
877 GType *children, *interfaces;
878 guint n_children, n_interfaces;
883 interfaces = g_type_interfaces (type, &n_interfaces);
885 if (n_interfaces > 0)
887 fprintf (fp, "%s", g_type_name (type));
888 for (i=0; i < n_interfaces; i++)
889 fprintf (fp, " %s", g_type_name (interfaces[i]));
894 children = g_type_children (type, &n_children);
896 for (i=0; i < n_children; i++)
897 output_interfaces (fp, children[i]);
902 static void output_interface_prerequisites (void)
906 fp = fopen (prerequisites_filename, "w");
909 g_warning ("Couldn't open output file: %s : %s", prerequisites_filename, strerror(errno));
912 output_prerequisites (fp, G_TYPE_INTERFACE);
917 output_prerequisites (FILE *fp,
920 #if GLIB_CHECK_VERSION(2,1,0)
922 GType *children, *prerequisites;
923 guint n_children, n_prerequisites;
928 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
930 if (n_prerequisites > 0)
932 fprintf (fp, "%s", g_type_name (type));
933 for (i=0; i < n_prerequisites; i++)
934 fprintf (fp, " %s", g_type_name (prerequisites[i]));
937 g_free (prerequisites);
939 children = g_type_children (type, &n_children);
941 for (i=0; i < n_children; i++)
942 output_prerequisites (fp, children[i]);
954 fp = fopen (args_filename, "w");
957 g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno));
961 for (i = 0; object_types[i]; i++) {
962 output_object_args (fp, object_types[i]);
969 compare_param_specs (const void *a, const void *b)
971 GParamSpec *spec_a = *(GParamSpec **)a;
972 GParamSpec *spec_b = *(GParamSpec **)b;
974 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
977 /* Its common to have unsigned properties restricted
978 * to the signed range. Therefore we make this look
979 * a bit nicer by spelling out the max constants.
982 /* Don't use "==" with floats, it might trigger a gcc warning. */
983 #define GTKDOC_COMPARE_FLOAT(x, y) (x <= y && x >= y)
986 describe_double_constant (gdouble value)
990 if (GTKDOC_COMPARE_FLOAT (value, G_MAXDOUBLE))
991 desc = g_strdup ("G_MAXDOUBLE");
992 else if (GTKDOC_COMPARE_FLOAT (value, G_MINDOUBLE))
993 desc = g_strdup ("G_MINDOUBLE");
994 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXDOUBLE))
995 desc = g_strdup ("-G_MAXDOUBLE");
996 else if (GTKDOC_COMPARE_FLOAT (value, G_MAXFLOAT))
997 desc = g_strdup ("G_MAXFLOAT");
998 else if (GTKDOC_COMPARE_FLOAT (value, G_MINFLOAT))
999 desc = g_strdup ("G_MINFLOAT");
1000 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXFLOAT))
1001 desc = g_strdup ("-G_MAXFLOAT");
1003 desc = g_strdup_printf ("%lg", value);
1009 describe_signed_constant (gint64 value)
1013 if (value == G_MAXINT)
1014 desc = g_strdup ("G_MAXINT");
1015 else if (value == G_MININT)
1016 desc = g_strdup ("G_MININT");
1017 else if (value == G_MAXUINT)
1018 desc = g_strdup ("G_MAXUINT");
1019 else if (value == G_MAXLONG)
1020 desc = g_strdup ("G_MAXLONG");
1021 else if (value == G_MINLONG)
1022 desc = g_strdup ("G_MINLONG");
1023 else if (value == G_MAXULONG)
1024 desc = g_strdup ("G_MAXULONG");
1025 else if (value == G_MAXINT64)
1026 desc = g_strdup ("G_MAXINT64");
1027 else if (value == G_MININT64)
1028 desc = g_strdup ("G_MININT64");
1030 desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
1036 describe_unsigned_constant (guint64 value)
1040 if (value == G_MAXINT)
1041 desc = g_strdup ("G_MAXINT");
1042 else if (value == G_MAXUINT)
1043 desc = g_strdup ("G_MAXUINT");
1044 else if (value == G_MAXLONG)
1045 desc = g_strdup ("G_MAXLONG");
1046 else if (value == G_MAXULONG)
1047 desc = g_strdup ("G_MAXULONG");
1048 else if (value == G_MAXINT64)
1049 desc = g_strdup ("G_MAXINT64");
1050 else if (value == G_MAXUINT64)
1051 desc = g_strdup ("G_MAXUINT64");
1053 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
1059 describe_type (GParamSpec *spec)
1065 if (G_IS_PARAM_SPEC_CHAR (spec))
1067 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1069 lower = describe_signed_constant (pspec->minimum);
1070 upper = describe_signed_constant (pspec->maximum);
1071 if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
1072 desc = g_strdup ("");
1073 else if (pspec->minimum == G_MININT8)
1074 desc = g_strdup_printf ("<= %s", upper);
1075 else if (pspec->maximum == G_MAXINT8)
1076 desc = g_strdup_printf (">= %s", lower);
1078 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1082 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1084 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1086 lower = describe_unsigned_constant (pspec->minimum);
1087 upper = describe_unsigned_constant (pspec->maximum);
1088 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
1089 desc = g_strdup ("");
1090 else if (pspec->minimum == 0)
1091 desc = g_strdup_printf ("<= %s", upper);
1092 else if (pspec->maximum == G_MAXUINT8)
1093 desc = g_strdup_printf (">= %s", lower);
1095 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1099 else if (G_IS_PARAM_SPEC_INT (spec))
1101 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1103 lower = describe_signed_constant (pspec->minimum);
1104 upper = describe_signed_constant (pspec->maximum);
1105 if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
1106 desc = g_strdup ("");
1107 else if (pspec->minimum == G_MININT)
1108 desc = g_strdup_printf ("<= %s", upper);
1109 else if (pspec->maximum == G_MAXINT)
1110 desc = g_strdup_printf (">= %s", lower);
1112 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1116 else if (G_IS_PARAM_SPEC_UINT (spec))
1118 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1120 lower = describe_unsigned_constant (pspec->minimum);
1121 upper = describe_unsigned_constant (pspec->maximum);
1122 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
1123 desc = g_strdup ("");
1124 else if (pspec->minimum == 0)
1125 desc = g_strdup_printf ("<= %s", upper);
1126 else if (pspec->maximum == G_MAXUINT)
1127 desc = g_strdup_printf (">= %s", lower);
1129 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1133 else if (G_IS_PARAM_SPEC_LONG (spec))
1135 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1137 lower = describe_signed_constant (pspec->minimum);
1138 upper = describe_signed_constant (pspec->maximum);
1139 if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
1140 desc = g_strdup ("");
1141 else if (pspec->minimum == G_MINLONG)
1142 desc = g_strdup_printf ("<= %s", upper);
1143 else if (pspec->maximum == G_MAXLONG)
1144 desc = g_strdup_printf (">= %s", lower);
1146 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1150 else if (G_IS_PARAM_SPEC_ULONG (spec))
1152 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1154 lower = describe_unsigned_constant (pspec->minimum);
1155 upper = describe_unsigned_constant (pspec->maximum);
1156 if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
1157 desc = g_strdup ("");
1158 else if (pspec->minimum == 0)
1159 desc = g_strdup_printf ("<= %s", upper);
1160 else if (pspec->maximum == G_MAXULONG)
1161 desc = g_strdup_printf (">= %s", lower);
1163 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1167 else if (G_IS_PARAM_SPEC_INT64 (spec))
1169 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1171 lower = describe_signed_constant (pspec->minimum);
1172 upper = describe_signed_constant (pspec->maximum);
1173 if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
1174 desc = g_strdup ("");
1175 else if (pspec->minimum == G_MININT64)
1176 desc = g_strdup_printf ("<= %s", upper);
1177 else if (pspec->maximum == G_MAXINT64)
1178 desc = g_strdup_printf (">= %s", lower);
1180 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1184 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1186 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1188 lower = describe_unsigned_constant (pspec->minimum);
1189 upper = describe_unsigned_constant (pspec->maximum);
1190 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
1191 desc = g_strdup ("");
1192 else if (pspec->minimum == 0)
1193 desc = g_strdup_printf ("<= %s", upper);
1194 else if (pspec->maximum == G_MAXUINT64)
1195 desc = g_strdup_printf (">= %s", lower);
1197 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1201 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1203 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1205 lower = describe_double_constant (pspec->minimum);
1206 upper = describe_double_constant (pspec->maximum);
1207 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXFLOAT))
1209 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1210 desc = g_strdup ("");
1212 desc = g_strdup_printf ("<= %s", upper);
1214 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1215 desc = g_strdup_printf (">= %s", lower);
1217 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1221 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1223 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1225 lower = describe_double_constant (pspec->minimum);
1226 upper = describe_double_constant (pspec->maximum);
1227 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXDOUBLE))
1229 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1230 desc = g_strdup ("");
1232 desc = g_strdup_printf ("<= %s", upper);
1234 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1235 desc = g_strdup_printf (">= %s", lower);
1237 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1243 desc = g_strdup ("");
1250 describe_default (GParamSpec *spec)
1254 if (G_IS_PARAM_SPEC_CHAR (spec))
1256 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1258 desc = g_strdup_printf ("%d", pspec->default_value);
1260 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1262 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1264 desc = g_strdup_printf ("%u", pspec->default_value);
1266 else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
1268 GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
1270 desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
1272 else if (G_IS_PARAM_SPEC_INT (spec))
1274 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1276 desc = g_strdup_printf ("%d", pspec->default_value);
1278 else if (G_IS_PARAM_SPEC_UINT (spec))
1280 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1282 desc = g_strdup_printf ("%u", pspec->default_value);
1284 else if (G_IS_PARAM_SPEC_LONG (spec))
1286 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1288 desc = g_strdup_printf ("%ld", pspec->default_value);
1290 else if (G_IS_PARAM_SPEC_LONG (spec))
1292 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1294 desc = g_strdup_printf ("%lu", pspec->default_value);
1296 else if (G_IS_PARAM_SPEC_INT64 (spec))
1298 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1300 desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
1302 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1304 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1306 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
1308 else if (G_IS_PARAM_SPEC_UNICHAR (spec))
1310 GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
1312 if (g_unichar_isprint (pspec->default_value))
1313 desc = g_strdup_printf ("'%c'", pspec->default_value);
1315 desc = g_strdup_printf ("%u", pspec->default_value);
1317 else if (G_IS_PARAM_SPEC_ENUM (spec))
1319 GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
1321 GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
1323 desc = g_strdup_printf ("%s", value->value_name);
1325 desc = g_strdup_printf ("%d", pspec->default_value);
1327 else if (G_IS_PARAM_SPEC_FLAGS (spec))
1329 GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
1330 guint default_value;
1333 default_value = pspec->default_value;
1334 acc = g_string_new ("");
1336 while (default_value)
1338 GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
1344 g_string_append (acc, "|");
1345 g_string_append (acc, value->value_name);
1347 default_value &= ~value->value;
1350 if (default_value == 0)
1351 desc = g_string_free (acc, FALSE);
1354 desc = g_strdup_printf ("%d", pspec->default_value);
1355 g_string_free (acc, TRUE);
1358 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1360 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1362 desc = g_strdup_printf ("%g", pspec->default_value);
1364 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1366 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1368 desc = g_strdup_printf ("%lg", pspec->default_value);
1370 else if (G_IS_PARAM_SPEC_STRING (spec))
1372 GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
1374 if (pspec->default_value)
1376 gchar *esc = g_strescape (pspec->default_value, NULL);
1378 desc = g_strdup_printf ("\\"%s\\"", esc);
1383 desc = g_strdup_printf ("NULL");
1387 desc = g_strdup ("");
1395 output_object_args (FILE *fp, GType object_type)
1398 const gchar *object_class_name;
1400 gchar flags[16], *pos;
1401 GParamSpec **properties;
1403 gboolean child_prop;
1404 gboolean style_prop;
1405 gboolean is_pointer;
1406 const gchar *type_name;
1408 gchar *default_value;
1410 if (G_TYPE_IS_OBJECT (object_type))
1412 class = g_type_class_peek (object_type);
1416 properties = g_object_class_list_properties (class, &n_properties);
1418 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
1419 else if (G_TYPE_IS_INTERFACE (object_type))
1421 class = g_type_default_interface_ref (object_type);
1426 properties = g_object_interface_list_properties (class, &n_properties);
1432 object_class_name = g_type_name (object_type);
1438 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
1439 for (arg = 0; arg < n_properties; arg++)
1441 GParamSpec *spec = properties[arg];
1442 const gchar *nick, *blurb, *dot;
1444 if (spec->owner_type != object_type)
1448 /* We use one-character flags for simplicity. */
1449 if (child_prop && !style_prop)
1453 if (spec->flags & G_PARAM_READABLE)
1455 if (spec->flags & G_PARAM_WRITABLE)
1457 if (spec->flags & G_PARAM_CONSTRUCT)
1459 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
1463 nick = g_param_spec_get_nick (spec);
1464 blurb = g_param_spec_get_blurb (spec);
1468 int str_len = strlen (blurb);
1469 if (str_len > 0 && blurb[str_len - 1] != '.')
1473 type_desc = describe_type (spec);
1474 default_value = describe_default (spec);
1475 type_name = get_type_name (spec->value_type, &is_pointer);
1476 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",
1477 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);
1479 g_free (default_value);
1482 g_free (properties);
1484 #ifdef GTK_IS_CONTAINER_CLASS
1485 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
1486 properties = gtk_container_class_list_child_properties (class, &n_properties);
1492 #ifdef GTK_IS_WIDGET_CLASS
1493 #if GTK_CHECK_VERSION(2,1,0)
1494 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
1495 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1504 if ($QUERY_CHILD_PROPERTIES) {
1507 properties = $QUERY_CHILD_PROPERTIES (class, &n_properties);
1525 # Compile and run our file
1527 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
1528 $LD = $ENV{LD} ? $ENV{LD} : $CC;
1529 $CFLAGS = $ENV{CFLAGS} ? $ENV{CFLAGS} : "";
1530 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
1533 if ($CC =~ /libtool/) {
1534 $o_file = "$MODULE-scan.lo"
1536 $o_file = "$MODULE-scan.o"
1539 print "gtk-doc: Compiling scanner\n";
1540 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c";
1541 system($command) == 0 or die "Compilation of scanner failed: $!\n";
1543 print "gtk-doc: Linking scanner\n";
1544 $command = "$LD -o $MODULE-scan $o_file $LDFLAGS";
1545 system($command) == 0 or die "Linking of scanner failed: $!\n";
1547 print "gtk-doc: Running scanner $MODULE-scan\n";
1548 system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n";
1550 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
1552 &UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
1553 &UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
1554 &UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
1555 &UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
1556 &UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);