Use full symbol, if it does not belong to the namespace.
[gtk-doc.git] / gtkdoc-scanobj.in
blobf844491cc2cb35f39a0379d49168edb830bfcab8
1 #!@PERL@ -w
2 # -*- cperl -*-
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.
31 use Getopt::Long;
33 unshift @INC, '@PACKAGE_DATA_DIR@';
34 require "gtkdoc-common.pl";
36 # Options
38 # name of documentation module
39 my $MODULE;
40 my $OUTPUT_DIR;
41 my $PRINT_VERSION;
43 %optctl = (module => \$MODULE,
44            types => \$TYPES_FILE,
45            nogtkinit => \$NO_GTK_INIT,
46            'output-dir' => \$OUTPUT_DIR,
47            'version' => \$PRINT_VERSION);
48            
49 GetOptions(\%optctl, "module=s", "types:s", "output-dir:s", "nogtkinit", "version");
51 if ($PRINT_VERSION) {
52     print "@VERSION@\n";
53     exit 0;
56 $OUTPUT_DIR = $OUTPUT_DIR ? $OUTPUT_DIR : ".";
58 $TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$OUTPUT_DIR/$MODULE.types";
60 open (TYPES, $TYPES_FILE) || die "Cannot open $TYPES_FILE: $!\n";
61 open (OUTPUT, ">$MODULE-scan.c") || die "Cannot open $MODULE-scan.c: $!\n";
63 my $old_signals_filename = "$OUTPUT_DIR/$MODULE.signals";
64 my $new_signals_filename = "$OUTPUT_DIR/$MODULE.signals.new";
65 my $old_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy";
66 my $new_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy.new";
67 my $old_args_filename = "$OUTPUT_DIR/$MODULE.args";
68 my $new_args_filename = "$OUTPUT_DIR/$MODULE.args.new";
70 # write a C program to scan the types
72 $includes = "";
73 @types = ();
75 for (<TYPES>) {
76     if (/^#include/) {
77         $includes .= $_;
78     } elsif (/^%/) {
79         next;
80     } elsif (/^\s*$/) {
81         next;
82     } else {
83         chomp;
84         push @types, $_;
85     }
88 $ntypes = @types + 1;
90 print OUTPUT <<EOT;
91 #include <string.h>
92 #include <stdlib.h>
93 #include <stdio.h>
94 #include <errno.h>
96 $includes
97 GtkType object_types[$ntypes];
99 GtkType *
100 get_object_types (void)
102     gint i = 0;
105 for (@types) {
106     print OUTPUT "    object_types[i++] = $_ ();\n";
109 print OUTPUT <<EOT;
110     object_types[i] = 0;
112     return object_types;
116  * This uses GTK type functions to output signal prototypes and the widget
117  * hierarchy.
118  */
120 /* The output files */
121 gchar *signals_filename = "$new_signals_filename";
122 gchar *hierarchy_filename = "$new_hierarchy_filename";
123 gchar *args_filename = "$new_args_filename";
126 static void output_signals (void);
127 static void output_widget_signals (FILE *fp,
128                                    GtkType object_type);
129 static void output_widget_signal (FILE *fp,
130                                   GtkType object_type,
131                                   gchar *object_class_name,
132                                   guint signal_id);
133 static gchar * get_type_name (GtkType type,
134                               gboolean * is_pointer);
135 static gchar * get_gdk_event (const gchar * signal_name);
136 static gchar ** lookup_signal_arg_names (gchar * type,
137                                          const gchar * signal_name);
139 static void output_widget_hierarchy (void);
140 static void output_hierarchy (FILE *fp,
141                               GtkType type,
142                               guint level);
144 static void output_args (void);
145 static void output_widget_args (FILE *fp, GtkType object_type);
148 main (int argc, char *argv[])
152   if ($NO_GTK_INIT) {
153     print OUTPUT <<EOT;
154   gtk_type_init ();
156   } else {
157     print OUTPUT <<EOT;
158   gtk_init (&argc, &argv);
160   }
162 print OUTPUT <<EOT;
163   get_object_types ();
165   output_signals ();
166   output_widget_hierarchy ();
167   output_args ();
169   return 0;
173 static void
174 output_signals (void)
176   FILE *fp;
177   gint i;
179   fp = fopen (signals_filename, "w");
180   if (fp == NULL)
181     {
182       g_warning ("Couldn't open output file: %s : %s", signals_filename, strerror(errno));
183       return;
184     }
186   for (i = 0; object_types[i]; i++)
187     output_widget_signals (fp, object_types[i]);
189   fclose (fp);
193 /* This outputs all the signals of one widget. */
194 static void
195 output_widget_signals (FILE *fp, GtkType object_type)
197   GtkObjectClass *class;
198   gchar *object_class_name;
199   guint sig;
201   class = gtk_type_class (object_type);
202   if (!class || class->nsignals == 0)
203     return;
205   object_class_name = gtk_type_name (object_type);
207   for (sig = 0; sig < class->nsignals; sig++)
208     {
209       if (!class->signals[sig])
210         {
211           /*g_print ("Signal slot [%u] is empty\\n", sig);*/
212           continue;
213         }
215       output_widget_signal (fp, object_type, object_class_name,
216                             class->signals[sig]);
217     }
221 /* This outputs one signal. */
222 static void
223 output_widget_signal (FILE *fp,
224                       GtkType object_type,
225                       gchar *object_name,
226                       guint signal_id)
228   GtkSignalQuery *query_info;
229   gchar *ret_type, *pos, *type_name, *arg_name, *object_arg, *object_arg_start;
230   gboolean is_pointer;
231   gchar ret_type_buffer[1024], buffer[1024];
232   guint i, param;
233   gchar **arg_names;
234   gint param_num, widget_num, event_num, callback_num;
235   gint *arg_num;
236   gchar signal_name[128];
239   /*  g_print ("Object: %s Type: %i Signal: %u\\n", object_name, object_type,
240       signal_id);*/
242   param_num = 1;
243   widget_num = event_num = callback_num = 0;
245   query_info = gtk_signal_query (signal_id);
246   if (query_info == NULL)
247     {
248       g_warning ("Couldn't query signal");
249       return;
250     }
252   /* Output the return type and function name. */
253   ret_type = get_type_name (query_info->return_val, &is_pointer);
254   sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
256   /* Output the signal object type and the argument name. We assume the
257      type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
258      convert to lower case for the argument name. */
259   pos = buffer;
260   sprintf (pos, "%s ", object_name);
261   pos += strlen (pos);
263   if (!strncmp (object_name, "Gtk", 3))
264       object_arg = object_name + 3;
265   else if (!strncmp (object_name, "Gnome", 5))
266       object_arg = object_name + 5;
267   else
268       object_arg = object_name;
270   object_arg_start = pos;
271   sprintf (pos, "*%s\\n", object_arg);
272   pos += strlen (pos);
273   g_strdown (object_arg_start);
274   if (!strcmp (object_arg_start, "widget"))
275     widget_num++;
276   
277   /* Convert signal name to use underscores rather than dashes '-'. */
278   strcpy (signal_name, query_info->signal_name);
279   for (i = 0; signal_name[i]; i++)
280     {
281       if (signal_name[i] == '-')
282         signal_name[i] = '_';
283     }
285   /* Output the signal parameters. */
286   arg_names = lookup_signal_arg_names (object_name, signal_name);
288   for (param = 0; param < query_info->nparams; param++)
289     {
290       if (arg_names)
291         {
292           sprintf (pos, "%s\\n", arg_names[param]);
293           pos += strlen (pos);
294         }
295       else
296         {
297           type_name = get_type_name (query_info->params[param], &is_pointer);
299           /* Most arguments to the callback are called "arg1", "arg2", etc.
300              GdkWidgets are called "widget", "widget2", ...
301              GdkEvents are called "event", "event2", ...
302              GtkCallbacks are called "callback", "callback2", ... */
303           if (!strcmp (type_name, "GtkWidget"))
304             {
305               arg_name = "widget";
306               arg_num = &widget_num;
307             }
308           else if (!strcmp (type_name, "GdkEvent"))
309             {
310               type_name = get_gdk_event (signal_name);
311               arg_name = "event";
312               arg_num = &event_num;
313               is_pointer = TRUE;
314             }
315           else if (!strcmp (type_name, "GtkCallback")
316                    || !strcmp (type_name, "GtkCCallback"))
317             {
318               arg_name = "callback";
319               arg_num = &callback_num;
320             }
321           else
322             {
323               arg_name = "arg";
324               arg_num = &param_num;
325             }
326           sprintf (pos, "%s ", type_name);
327           pos += strlen (pos);
329           if (!arg_num || *arg_num == 0)
330             sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
331           else
332             sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
333                      *arg_num);
334               pos += strlen (pos);
335               
336               if (arg_num)
337                 *arg_num += 1;
338         }
339     }
340   
341   fprintf (fp,
342            "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n%s</SIGNAL>\\n\\n",
343            object_name, query_info->signal_name, ret_type_buffer, buffer);
344   g_free (query_info);
348 /* Returns the type name to use for a signal argument or return value, given
349    the GtkType from the signal info. It also sets is_pointer to TRUE if the
350    argument needs a '*' since it is a pointer. */
351 static gchar *
352 get_type_name (GtkType type, gboolean * is_pointer)
354   gchar *type_name;
356   *is_pointer = FALSE;
357   type_name = gtk_type_name (type);
359   switch (type) {
360   case GTK_TYPE_NONE:
361   case GTK_TYPE_CHAR:
362   case GTK_TYPE_UCHAR:
363   case GTK_TYPE_BOOL:
364   case GTK_TYPE_INT:
365   case GTK_TYPE_UINT:
366   case GTK_TYPE_LONG:
367   case GTK_TYPE_ULONG:
368   case GTK_TYPE_FLOAT:
369   case GTK_TYPE_DOUBLE:
370   case GTK_TYPE_POINTER:
371     /* These all have normal C type names so they are OK. */
372     return type_name;
374   case GTK_TYPE_STRING:
375     /* A GtkString is really a gchar*. */
376     *is_pointer = TRUE;
377     return "gchar";
379   case GTK_TYPE_ENUM:
380   case GTK_TYPE_FLAGS:
381     /* We use a gint for both of these. Hopefully a subtype with a decent
382        name will be registered and used instead, as GTK+ does itself. */
383     return "gint";
385   case GTK_TYPE_BOXED:
386     /* A boxed value is just an opaque pointer, I think. */
387     return "gpointer";
389   case GTK_TYPE_SIGNAL:
390   case GTK_TYPE_ARGS:
391   case GTK_TYPE_FOREIGN:
392   case GTK_TYPE_CALLBACK:
393   case GTK_TYPE_C_CALLBACK:
394     /* FIXME: These are wrong. I think they expand into more than 1 argument.
395        See the GtkArg struct in gtktypeutils.h and gtkargcollector.c.
396        Fortunately I doubt anything uses these as signal args. */
397     return "gpointer";
399   default:
400     break;
401   }
403   /* For all GtkObject subclasses we can use the class name with a "*",
404      e.g. 'GtkWidget *'. */
405   if (gtk_type_is_a (type, GTK_TYPE_OBJECT))
406     *is_pointer = TRUE;
408   return type_name;
412 static gchar *
413 get_gdk_event (const gchar * signal_name)
415   static gchar *GbGDKEvents[] =
416   {
417     "button_press_event", "GdkEventButton",
418     "button_release_event", "GdkEventButton",
419     "motion_notify_event", "GdkEventMotion",
420     "delete_event", "GdkEvent",
421     "destroy_event", "GdkEvent",
422     "expose_event", "GdkEventExpose",
423     "key_press_event", "GdkEventKey",
424     "key_release_event", "GdkEventKey",
425     "enter_notify_event", "GdkEventCrossing",
426     "leave_notify_event", "GdkEventCrossing",
427     "configure_event", "GdkEventConfigure",
428     "focus_in_event", "GdkEventFocus",
429     "focus_out_event", "GdkEventFocus",
430     "map_event", "GdkEvent",
431     "unmap_event", "GdkEvent",
432     "property_notify_event", "GdkEventProperty",
433     "selection_clear_event", "GdkEventSelection",
434     "selection_request_event", "GdkEventSelection",
435     "selection_notify_event", "GdkEventSelection",
436     "proximity_in_event", "GdkEventProximity",
437     "proximity_out_event", "GdkEventProximity",
438     "drag_begin_event", "GdkEventDragBegin",
439     "drag_request_event", "GdkEventDragRequest",
440     "drag_end_event", "GdkEventDragRequest",
441     "drop_enter_event", "GdkEventDropEnter",
442     "drop_leave_event", "GdkEventDropLeave",
443     "drop_data_available_event", "GdkEventDropDataAvailable",
444     "other_event", "GdkEventOther",
445     "client_event", "GdkEventClient",
446     "no_expose_event", "GdkEventNoExpose",
447     "visibility_notify_event", "GdkEventVisibility",
448     "window_state_event", "GdkEventWindowState",
449     "scroll_event", "GdkEventScroll",
450     NULL
451   };
453   gint i;
455   for (i = 0; GbGDKEvents[i]; i += 2)
456     {
457       if (!strcmp (signal_name, GbGDKEvents[i]))
458         return GbGDKEvents[i + 1];
459     }
460   return "GdkEvent";
464 /* This returns argument names to use for some known GTK signals.
465     It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
466     'select_row' and it returns a pointer to an array of argument types and
467     names. */
468 static gchar **
469 lookup_signal_arg_names (gchar * type, const gchar * signal_name)
471   /* Each arg array starts with the object type name and the signal name,
472      and then signal arguments follow. */
473   static gchar *GbArgTable[][16] =
474   {
475     {"GtkCList", "select_row",
476      "gint             row",
477      "gint             column",
478      "GdkEventButton  *event"},
479     {"GtkCList", "unselect_row",
480      "gint             row",
481      "gint             column",
482      "GdkEventButton  *event"},
483     {"GtkCList", "click_column",
484      "gint             column"},
486     {"GtkCList", "resize_column",
487      "gint             column",
488      "gint             width"},
490     {"GtkCList", "extend_selection",
491      "GtkScrollType    scroll_type",
492      "gfloat           position",
493      "gboolean         auto_start_selection"},
494     {"GtkCList", "scroll_vertical",
495      "GtkScrollType    scroll_type",
496      "gfloat           position"},
497     {"GtkCList", "scroll_horizontal",
498      "GtkScrollType    scroll_type",
499      "gfloat           position"},
500     {"GtkContainer", "focus",
501      "GtkDirectionType direction"},
502     {"GtkCTree", "tree_select_row",
503      "GList           *node",
504      "gint             column"},
505     {"GtkCTree", "tree_unselect_row",
506      "GList           *node",
507      "gint             column"},
509     {"GtkCTree", "tree_expand",
510      "GList           *node"},
511     {"GtkCTree", "tree_collapse",
512      "GList           *node"},
513     {"GtkCTree", "tree_move",
514      "GList           *node",
515      "GList           *new_parent",
516      "GList           *new_sibling"},
517     {"GtkCTree", "change_focus_row_expansion",
518      "GtkCTreeExpansionType expansion"},
520     {"GtkEditable", "insert_text",
521      "gchar           *new_text",
522      "gint             new_text_length",
523      "gint            *position"},
524     {"GtkEditable", "delete_text",
525      "gint             start_pos",
526      "gint             end_pos"},
527     {"GtkEditable", "set_editable",
528      "gboolean         is_editable"},
529     {"GtkEditable", "move_cursor",
530      "gint             x",
531      "gint             y"},
532     {"GtkEditable", "move_word",
533      "gint             num_words"},
534     {"GtkEditable", "move_page",
535      "gint             x",
536      "gint             y"},
537     {"GtkEditable", "move_to_row",
538      "gint             row"},
539     {"GtkEditable", "move_to_column",
540      "gint             column"},
542     {"GtkEditable", "kill_char",
543      "gint             direction"},
544     {"GtkEditable", "kill_word",
545      "gint             direction"},
546     {"GtkEditable", "kill_line",
547      "gint             direction"},
550     {"GtkInputDialog", "enable_device",
551      "gint             deviceid"},
552     {"GtkInputDialog", "disable_device",
553      "gint             deviceid"},
555     {"GtkListItem", "extend_selection",
556      "GtkScrollType    scroll_type",
557      "gfloat           position",
558      "gboolean         auto_start_selection"},
559     {"GtkListItem", "scroll_vertical",
560      "GtkScrollType    scroll_type",
561      "gfloat           position"},
562     {"GtkListItem", "scroll_horizontal",
563      "GtkScrollType    scroll_type",
564      "gfloat           position"},
566     {"GtkMenuShell", "move_current",
567      "GtkMenuDirectionType direction"},
568     {"GtkMenuShell", "activate_current",
569      "gboolean         force_hide"},
572     {"GtkNotebook", "switch_page",
573      "GtkNotebookPage *page",
574      "gint             page_num"},
575     {"GtkStatusbar", "text_pushed",
576      "guint            context_id",
577      "gchar           *text"},
578     {"GtkStatusbar", "text_popped",
579      "guint            context_id",
580      "gchar           *text"},
581     {"GtkTipsQuery", "widget_entered",
582      "GtkWidget       *widget",
583      "gchar           *tip_text",
584      "gchar           *tip_private"},
585     {"GtkTipsQuery", "widget_selected",
586      "GtkWidget       *widget",
587      "gchar           *tip_text",
588      "gchar           *tip_private",
589      "GdkEventButton  *event"},
590     {"GtkToolbar", "orientation_changed",
591      "GtkOrientation   orientation"},
592     {"GtkToolbar", "style_changed",
593      "GtkToolbarStyle  style"},
594     {"GtkWidget", "draw",
595      "GdkRectangle    *area"},
596     {"GtkWidget", "size_request",
597      "GtkRequisition  *requisition"},
598     {"GtkWidget", "size_allocate",
599      "GtkAllocation   *allocation"},
600     {"GtkWidget", "state_changed",
601      "GtkStateType     state"},
602     {"GtkWidget", "style_set",
603      "GtkStyle        *previous_style"},
605     {"GtkWidget", "install_accelerator",
606      "gchar           *signal_name",
607      "gchar            key",
608      "gint             modifiers"},
610     {"GtkWidget", "add_accelerator",
611      "guint            accel_signal_id",
612      "GtkAccelGroup   *accel_group",
613      "guint            accel_key",
614      "GdkModifierType  accel_mods",
615      "GtkAccelFlags    accel_flags"},
617     {"GtkWidget", "parent_set",
618      "GtkObject       *old_parent"},
620     {"GtkWidget", "remove_accelerator",
621      "GtkAccelGroup   *accel_group",
622      "guint            accel_key",
623      "GdkModifierType  accel_mods"},
624     {"GtkWidget", "debug_msg",
625      "gchar           *message"},
626     {"GtkWindow", "move_resize",
627      "gint            *x",
628      "gint            *y",
629      "gint             width",
630      "gint             height"},
631     {"GtkWindow", "set_focus",
632      "GtkWidget       *widget"},
634     {"GtkWidget", "selection_get",
635      "GtkSelectionData *data",
636      "guint            info",
637      "guint            time"},
638     {"GtkWidget", "selection_received",
639      "GtkSelectionData *data",
640      "guint            time"},
642     {"GtkWidget", "drag_begin",
643      "GdkDragContext  *drag_context"},
644     {"GtkWidget", "drag_end",
645      "GdkDragContext  *drag_context"},
646     {"GtkWidget", "drag_data_delete",
647      "GdkDragContext  *drag_context"},
648     {"GtkWidget", "drag_leave",
649      "GdkDragContext  *drag_context",
650      "guint            time"},
651     {"GtkWidget", "drag_motion",
652      "GdkDragContext  *drag_context",
653      "gint             x",
654      "gint             y",
655      "guint            time"},
656     {"GtkWidget", "drag_drop",
657      "GdkDragContext  *drag_context",
658      "gint             x",
659      "gint             y",
660      "guint            time"},
661     {"GtkWidget", "drag_data_get",
662      "GdkDragContext  *drag_context",
663      "GtkSelectionData *data",
664      "guint            info",
665      "guint            time"},
666     {"GtkWidget", "drag_data_received",
667      "GdkDragContext  *drag_context",
668      "gint             x",
669      "gint             y",
670      "GtkSelectionData *data",
671      "guint            info",
672      "guint            time"},
674     {NULL}
675   };
677   gint i;
679   for (i = 0; GbArgTable[i][0]; i++)
680     {
681       if (!strcmp (type, GbArgTable[i][0])
682           && !strcmp (signal_name, GbArgTable[i][1]))
683         return &GbArgTable[i][2];
684     }
685   return NULL;
689 /* This outputs the hierarchy of all widgets which have been initialized,
690    i.e. by calling their XXX_get_type() initialization function. */
691 static void
692 output_widget_hierarchy (void)
694   FILE *fp;
696   fp = fopen (hierarchy_filename, "w");
697   if (fp == NULL)
698     {
699       g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, strerror(errno));
700       return;
701     }
702   output_hierarchy (fp, GTK_TYPE_OBJECT, 0);
703   fclose (fp);
707 /* This is called recursively to output the hierarchy of a widget. */
708 static void
709 output_hierarchy (FILE *fp,
710                   GtkType type,
711                   guint level)
713   GList *list;
714   guint i;
716   if (!type)
717     return;
719   for (i = 0; i < level; i++)
720     fprintf (fp, "  ");
721   fprintf (fp, "%s\\n", gtk_type_name (type));
723   list = gtk_type_children_types (type);
725   while (list)
726     {
727       GtkType child = (GtkType) list->data;
728       output_hierarchy (fp, child, level + 1);
729       list = list->next;
730     }
734 static void
735 output_args (void)
737   FILE *fp;
738   gint i;
740   fp = fopen (args_filename, "w");
741   if (fp == NULL)
742     {
743       g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno));
744       return;
745     }
747   for (i = 0; object_types[i]; i++)
748     output_widget_args (fp, object_types[i]);
750   fclose (fp);
754 static void
755 output_widget_args (FILE *fp, GtkType object_type)
757   GtkObjectClass *class;
758   gchar *object_class_name;
759   GtkArg *args;
760   guint32 *arg_flags;
761   guint n_args;
762   guint arg;
763   gchar flags[16], *pos;
765   class = gtk_type_class (object_type);
766   if (!class)
767     return;
769   object_class_name = gtk_type_name (object_type);
771   args = gtk_object_query_args (class->type, &arg_flags, &n_args);
773   for (arg = 0; arg < n_args; arg++)
774     {
775       pos = flags;
776       /* We use one-character flags for simplicity. */
777       if (arg_flags[arg] & GTK_ARG_READABLE)
778         *pos++ = 'r';
779       if (arg_flags[arg] & GTK_ARG_WRITABLE)
780         *pos++ = 'w';
781       if (arg_flags[arg] & GTK_ARG_CONSTRUCT)
782         *pos++ = 'x';
783       if (arg_flags[arg] & GTK_ARG_CONSTRUCT_ONLY)
784         *pos++ = 'X';
785       if (arg_flags[arg] & GTK_ARG_CHILD_ARG)
786         *pos++ = 'c';
787       *pos = 0;
789       fprintf (fp, "<ARG>\\n<NAME>%s</NAME>\\n<TYPE>%s</TYPE>\\n<FLAGS>%s</FLAGS>\\n</ARG>\\n\\n",
790                args[arg].name, gtk_type_name (args[arg].type), flags);
791     }
793   g_free (args);
794   g_free (arg_flags);
798 close OUTPUT;
800 # Compile and run our file
802 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
803 $LD = $ENV{LD} ? $ENV{LD} : $CC;
804 $CFLAGS = $ENV{CFLAGS} ? $ENV{CFLAGS} : "";
805 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
807 my $o_file;
808 if ($CC =~ /libtool/) {
809   $o_file  = "$MODULE-scan.lo"
810 } else {
811   $o_file = "$MODULE-scan.o"
814 print "gtk-doc: Compiling scanner\n";
815 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c";
816 system($command) == 0 or die "Compilation of scanner failed: $!\n";
818 print "gtk-doc: Linking scanner\n";
819 $command = "$LD -o $MODULE-scan $o_file $LDFLAGS";
820 system($command) == 0 or die "Linking of scanner failed: $!\n";
822 print "gtk-doc: Running scanner $MODULE-scan\n";
823 system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n";
825 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
827 &UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
828 &UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
829 &UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);