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, g_type_name (type));
840 children = g_type_children (type, &n_children);
842 for (i=0; i < n_children; i++)
843 output_hierarchy (fp, children[i], level + 1);
848 static void output_object_interfaces (void)
853 fp = fopen (interfaces_filename, "w");
856 g_warning ("Couldn't open output file: %s : %s", interfaces_filename, strerror(errno));
859 output_interfaces (fp, G_TYPE_OBJECT);
861 for (i = 0; object_types[i]; i++)
863 if (!g_type_parent (object_types[i]) &&
864 (object_types[i] != G_TYPE_OBJECT) &&
865 G_TYPE_IS_INSTANTIATABLE (object_types[i]))
867 output_interfaces (fp, object_types[i]);
874 output_interfaces (FILE *fp,
878 GType *children, *interfaces;
879 guint n_children, n_interfaces;
884 interfaces = g_type_interfaces (type, &n_interfaces);
886 if (n_interfaces > 0)
888 fprintf (fp, g_type_name (type));
889 for (i=0; i < n_interfaces; i++)
890 fprintf (fp, " %s", g_type_name (interfaces[i]));
895 children = g_type_children (type, &n_children);
897 for (i=0; i < n_children; i++)
898 output_interfaces (fp, children[i]);
903 static void output_interface_prerequisites (void)
907 fp = fopen (prerequisites_filename, "w");
910 g_warning ("Couldn't open output file: %s : %s", prerequisites_filename, strerror(errno));
913 output_prerequisites (fp, G_TYPE_INTERFACE);
918 output_prerequisites (FILE *fp,
921 #if GLIB_CHECK_VERSION(2,1,0)
923 GType *children, *prerequisites;
924 guint n_children, n_prerequisites;
929 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
931 if (n_prerequisites > 0)
933 fprintf (fp, g_type_name (type));
934 for (i=0; i < n_prerequisites; i++)
935 fprintf (fp, " %s", g_type_name (prerequisites[i]));
938 g_free (prerequisites);
940 children = g_type_children (type, &n_children);
942 for (i=0; i < n_children; i++)
943 output_prerequisites (fp, children[i]);
955 fp = fopen (args_filename, "w");
958 g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno));
962 for (i = 0; object_types[i]; i++) {
963 output_object_args (fp, object_types[i]);
970 compare_param_specs (const void *a, const void *b)
972 GParamSpec *spec_a = *(GParamSpec **)a;
973 GParamSpec *spec_b = *(GParamSpec **)b;
975 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
978 /* Its common to have unsigned properties restricted
979 * to the signed range. Therefore we make this look
980 * a bit nicer by spelling out the max constants.
983 /* Don't use "==" with floats, it might trigger a gcc warning. */
984 #define GTKDOC_COMPARE_FLOAT(x, y) (x <= y && x >= y)
987 describe_double_constant (gdouble value)
991 if (GTKDOC_COMPARE_FLOAT (value, G_MAXDOUBLE))
992 desc = g_strdup ("G_MAXDOUBLE");
993 else if (GTKDOC_COMPARE_FLOAT (value, G_MINDOUBLE))
994 desc = g_strdup ("G_MINDOUBLE");
995 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXDOUBLE))
996 desc = g_strdup ("-G_MAXDOUBLE");
997 else if (GTKDOC_COMPARE_FLOAT (value, G_MAXFLOAT))
998 desc = g_strdup ("G_MAXFLOAT");
999 else if (GTKDOC_COMPARE_FLOAT (value, G_MINFLOAT))
1000 desc = g_strdup ("G_MINFLOAT");
1001 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXFLOAT))
1002 desc = g_strdup ("-G_MAXFLOAT");
1004 desc = g_strdup_printf ("%lg", value);
1010 describe_signed_constant (gint64 value)
1014 if (value == G_MAXINT)
1015 desc = g_strdup ("G_MAXINT");
1016 else if (value == G_MININT)
1017 desc = g_strdup ("G_MININT");
1018 else if (value == G_MAXUINT)
1019 desc = g_strdup ("G_MAXUINT");
1020 else if (value == G_MAXLONG)
1021 desc = g_strdup ("G_MAXLONG");
1022 else if (value == G_MINLONG)
1023 desc = g_strdup ("G_MINLONG");
1024 else if (value == G_MAXULONG)
1025 desc = g_strdup ("G_MAXULONG");
1026 else if (value == G_MAXINT64)
1027 desc = g_strdup ("G_MAXINT64");
1028 else if (value == G_MININT64)
1029 desc = g_strdup ("G_MININT64");
1031 desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
1037 describe_unsigned_constant (guint64 value)
1041 if (value == G_MAXINT)
1042 desc = g_strdup ("G_MAXINT");
1043 else if (value == G_MAXUINT)
1044 desc = g_strdup ("G_MAXUINT");
1045 else if (value == G_MAXLONG)
1046 desc = g_strdup ("G_MAXLONG");
1047 else if (value == G_MAXULONG)
1048 desc = g_strdup ("G_MAXULONG");
1049 else if (value == G_MAXINT64)
1050 desc = g_strdup ("G_MAXINT64");
1051 else if (value == G_MAXUINT64)
1052 desc = g_strdup ("G_MAXUINT64");
1054 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
1060 describe_type (GParamSpec *spec)
1066 if (G_IS_PARAM_SPEC_CHAR (spec))
1068 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1070 lower = describe_signed_constant (pspec->minimum);
1071 upper = describe_signed_constant (pspec->maximum);
1072 if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
1073 desc = g_strdup ("");
1074 else if (pspec->minimum == G_MININT8)
1075 desc = g_strdup_printf ("<= %s", upper);
1076 else if (pspec->maximum == G_MAXINT8)
1077 desc = g_strdup_printf (">= %s", lower);
1079 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1083 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1085 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1087 lower = describe_unsigned_constant (pspec->minimum);
1088 upper = describe_unsigned_constant (pspec->maximum);
1089 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
1090 desc = g_strdup ("");
1091 else if (pspec->minimum == 0)
1092 desc = g_strdup_printf ("<= %s", upper);
1093 else if (pspec->maximum == G_MAXUINT8)
1094 desc = g_strdup_printf (">= %s", lower);
1096 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1100 else if (G_IS_PARAM_SPEC_INT (spec))
1102 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1104 lower = describe_signed_constant (pspec->minimum);
1105 upper = describe_signed_constant (pspec->maximum);
1106 if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
1107 desc = g_strdup ("");
1108 else if (pspec->minimum == G_MININT)
1109 desc = g_strdup_printf ("<= %s", upper);
1110 else if (pspec->maximum == G_MAXINT)
1111 desc = g_strdup_printf (">= %s", lower);
1113 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1117 else if (G_IS_PARAM_SPEC_UINT (spec))
1119 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1121 lower = describe_unsigned_constant (pspec->minimum);
1122 upper = describe_unsigned_constant (pspec->maximum);
1123 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
1124 desc = g_strdup ("");
1125 else if (pspec->minimum == 0)
1126 desc = g_strdup_printf ("<= %s", upper);
1127 else if (pspec->maximum == G_MAXUINT)
1128 desc = g_strdup_printf (">= %s", lower);
1130 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1134 else if (G_IS_PARAM_SPEC_LONG (spec))
1136 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1138 lower = describe_signed_constant (pspec->minimum);
1139 upper = describe_signed_constant (pspec->maximum);
1140 if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
1141 desc = g_strdup ("");
1142 else if (pspec->minimum == G_MINLONG)
1143 desc = g_strdup_printf ("<= %s", upper);
1144 else if (pspec->maximum == G_MAXLONG)
1145 desc = g_strdup_printf (">= %s", lower);
1147 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1151 else if (G_IS_PARAM_SPEC_ULONG (spec))
1153 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1155 lower = describe_unsigned_constant (pspec->minimum);
1156 upper = describe_unsigned_constant (pspec->maximum);
1157 if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
1158 desc = g_strdup ("");
1159 else if (pspec->minimum == 0)
1160 desc = g_strdup_printf ("<= %s", upper);
1161 else if (pspec->maximum == G_MAXULONG)
1162 desc = g_strdup_printf (">= %s", lower);
1164 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1168 else if (G_IS_PARAM_SPEC_INT64 (spec))
1170 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1172 lower = describe_signed_constant (pspec->minimum);
1173 upper = describe_signed_constant (pspec->maximum);
1174 if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
1175 desc = g_strdup ("");
1176 else if (pspec->minimum == G_MININT64)
1177 desc = g_strdup_printf ("<= %s", upper);
1178 else if (pspec->maximum == G_MAXINT64)
1179 desc = g_strdup_printf (">= %s", lower);
1181 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1185 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1187 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1189 lower = describe_unsigned_constant (pspec->minimum);
1190 upper = describe_unsigned_constant (pspec->maximum);
1191 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
1192 desc = g_strdup ("");
1193 else if (pspec->minimum == 0)
1194 desc = g_strdup_printf ("<= %s", upper);
1195 else if (pspec->maximum == G_MAXUINT64)
1196 desc = g_strdup_printf (">= %s", lower);
1198 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1202 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1204 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1206 lower = describe_double_constant (pspec->minimum);
1207 upper = describe_double_constant (pspec->maximum);
1208 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXFLOAT))
1210 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1211 desc = g_strdup ("");
1213 desc = g_strdup_printf ("<= %s", upper);
1215 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1216 desc = g_strdup_printf (">= %s", lower);
1218 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1222 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1224 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1226 lower = describe_double_constant (pspec->minimum);
1227 upper = describe_double_constant (pspec->maximum);
1228 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXDOUBLE))
1230 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1231 desc = g_strdup ("");
1233 desc = g_strdup_printf ("<= %s", upper);
1235 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1236 desc = g_strdup_printf (">= %s", lower);
1238 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1244 desc = g_strdup ("");
1251 describe_default (GParamSpec *spec)
1255 if (G_IS_PARAM_SPEC_CHAR (spec))
1257 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1259 desc = g_strdup_printf ("%d", pspec->default_value);
1261 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1263 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1265 desc = g_strdup_printf ("%u", pspec->default_value);
1267 else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
1269 GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
1271 desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
1273 else if (G_IS_PARAM_SPEC_INT (spec))
1275 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1277 desc = g_strdup_printf ("%d", pspec->default_value);
1279 else if (G_IS_PARAM_SPEC_UINT (spec))
1281 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1283 desc = g_strdup_printf ("%u", pspec->default_value);
1285 else if (G_IS_PARAM_SPEC_LONG (spec))
1287 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1289 desc = g_strdup_printf ("%ld", pspec->default_value);
1291 else if (G_IS_PARAM_SPEC_LONG (spec))
1293 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1295 desc = g_strdup_printf ("%lu", pspec->default_value);
1297 else if (G_IS_PARAM_SPEC_INT64 (spec))
1299 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1301 desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
1303 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1305 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1307 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
1309 else if (G_IS_PARAM_SPEC_UNICHAR (spec))
1311 GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
1313 if (g_unichar_isprint (pspec->default_value))
1314 desc = g_strdup_printf ("'%c'", pspec->default_value);
1316 desc = g_strdup_printf ("%u", pspec->default_value);
1318 else if (G_IS_PARAM_SPEC_ENUM (spec))
1320 GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
1322 GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
1324 desc = g_strdup_printf ("%s", value->value_name);
1326 desc = g_strdup_printf ("%d", pspec->default_value);
1328 else if (G_IS_PARAM_SPEC_FLAGS (spec))
1330 GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
1331 guint default_value;
1334 default_value = pspec->default_value;
1335 acc = g_string_new ("");
1337 while (default_value)
1339 GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
1345 g_string_append (acc, "|");
1346 g_string_append (acc, value->value_name);
1348 default_value &= ~value->value;
1351 if (default_value == 0)
1352 desc = g_string_free (acc, FALSE);
1355 desc = g_strdup_printf ("%d", pspec->default_value);
1356 g_string_free (acc, TRUE);
1359 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1361 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1363 desc = g_strdup_printf ("%g", pspec->default_value);
1365 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1367 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1369 desc = g_strdup_printf ("%lg", pspec->default_value);
1371 else if (G_IS_PARAM_SPEC_STRING (spec))
1373 GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
1375 if (pspec->default_value)
1377 gchar *esc = g_strescape (pspec->default_value, NULL);
1379 desc = g_strdup_printf ("\\"%s\\"", esc);
1384 desc = g_strdup_printf ("NULL");
1388 desc = g_strdup ("");
1396 output_object_args (FILE *fp, GType object_type)
1399 const gchar *object_class_name;
1401 gchar flags[16], *pos;
1402 GParamSpec **properties;
1404 gboolean child_prop;
1405 gboolean style_prop;
1406 gboolean is_pointer;
1407 const gchar *type_name;
1409 gchar *default_value;
1411 if (G_TYPE_IS_OBJECT (object_type))
1413 class = g_type_class_peek (object_type);
1417 properties = g_object_class_list_properties (class, &n_properties);
1419 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
1420 else if (G_TYPE_IS_INTERFACE (object_type))
1422 class = g_type_default_interface_ref (object_type);
1427 properties = g_object_interface_list_properties (class, &n_properties);
1433 object_class_name = g_type_name (object_type);
1439 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
1440 for (arg = 0; arg < n_properties; arg++)
1442 GParamSpec *spec = properties[arg];
1443 const gchar *nick, *blurb, *dot;
1445 if (spec->owner_type != object_type)
1449 /* We use one-character flags for simplicity. */
1450 if (child_prop && !style_prop)
1454 if (spec->flags & G_PARAM_READABLE)
1456 if (spec->flags & G_PARAM_WRITABLE)
1458 if (spec->flags & G_PARAM_CONSTRUCT)
1460 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
1464 nick = g_param_spec_get_nick (spec);
1465 blurb = g_param_spec_get_blurb (spec);
1469 int str_len = strlen (blurb);
1470 if (str_len > 0 && blurb[str_len - 1] != '.')
1474 type_desc = describe_type (spec);
1475 default_value = describe_default (spec);
1476 type_name = get_type_name (spec->value_type, &is_pointer);
1477 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",
1478 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);
1480 g_free (default_value);
1483 g_free (properties);
1485 #ifdef GTK_IS_CONTAINER_CLASS
1486 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
1487 properties = gtk_container_class_list_child_properties (class, &n_properties);
1493 #ifdef GTK_IS_WIDGET_CLASS
1494 #if GTK_CHECK_VERSION(2,1,0)
1495 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
1496 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1505 if ($QUERY_CHILD_PROPERTIES) {
1508 properties = $QUERY_CHILD_PROPERTIES (class, &n_properties);
1526 # Compile and run our file
1528 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
1529 $LD = $ENV{LD} ? $ENV{LD} : $CC;
1530 $CFLAGS = $ENV{CFLAGS} ? $ENV{CFLAGS} : "";
1531 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
1534 if ($CC =~ /libtool/) {
1535 $o_file = "$MODULE-scan.lo"
1537 $o_file = "$MODULE-scan.o"
1540 print "gtk-doc: Compiling scanner\n";
1541 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c";
1542 system($command) == 0 or die "Compilation of scanner failed: $!\n";
1544 print "gtk-doc: Linking scanner\n";
1545 $command = "$LD -o $MODULE-scan $o_file $LDFLAGS";
1546 system($command) == 0 or die "Linking of scanner failed: $!\n";
1548 print "gtk-doc: Running scanner $MODULE-scan\n";
1549 system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n";
1551 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
1553 &UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
1554 &UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
1555 &UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
1556 &UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
1557 &UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);