null/demo.local.php
[gitlive] / tmp-introspectKC0zE1 / Xss-1.0.c
1 /* This file is generated, do not edit */
2 #include <glib.h>
3 #include <string.h>
4 #include <stdlib.h>
5
6 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
7  * GObject introspection: Dump introspection data
8  *
9  * Copyright (C) 2008 Colin Walters <walters@verbum.org>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the
23  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24  * Boston, MA 02111-1307, USA.
25  */
26
27 #include <stdlib.h>
28
29 #include <glib.h>
30 #include <glib-object.h>
31 #include <gio/gio.h>
32
33 /* This file is both compiled into libgirepository.so, and installed
34  * on the filesystem.  But for the dumper, we want to avoid linking
35  * to libgirepository; see
36  * https://bugzilla.gnome.org/show_bug.cgi?id=630342
37  */
38 #ifdef G_IREPOSITORY_COMPILATION
39 #include "config.h"
40 #include "girepository.h"
41 #endif
42
43 #include <string.h>
44
45 static void
46 escaped_printf (GOutputStream *out, const char *fmt, ...)
47 {
48   char *str;
49   va_list args;
50   gsize written;
51   GError *error = NULL;
52
53   va_start (args, fmt);
54
55   str = g_markup_vprintf_escaped (fmt, args);
56   if (!g_output_stream_write_all (out, str, strlen (str), &written, NULL, &error))
57     {
58       g_critical ("failed to write to iochannel: %s", error->message);
59       g_clear_error (&error);
60     }
61   g_free (str);
62
63   va_end (args);
64 }
65
66 static void
67 goutput_write (GOutputStream *out, const char *str)
68 {
69   gsize written;
70   GError *error = NULL;
71   if (!g_output_stream_write_all (out, str, strlen (str), &written, NULL, &error))
72     {
73       g_critical ("failed to write to iochannel: %s", error->message);
74       g_clear_error (&error);
75     }
76 }
77
78 typedef GType (*GetTypeFunc)(void);
79 typedef GQuark (*ErrorQuarkFunc)(void);
80
81 static GType
82 invoke_get_type (GModule *self, const char *symbol, GError **error)
83 {
84   GetTypeFunc sym;
85   GType ret;
86
87   if (!g_module_symbol (self, symbol, (void**)&sym))
88     {
89       g_set_error (error,
90                    G_IO_ERROR,
91                    G_IO_ERROR_FAILED,
92                    "Failed to find symbol '%s'", symbol);
93       return G_TYPE_INVALID;
94     }
95
96   ret = sym ();
97   if (ret == G_TYPE_INVALID)
98     {
99       g_set_error (error,
100                    G_IO_ERROR,
101                    G_IO_ERROR_FAILED,
102                    "Function '%s' returned G_TYPE_INVALID", symbol);
103     }
104   return ret;
105 }
106
107 static GQuark
108 invoke_error_quark (GModule *self, const char *symbol, GError **error)
109 {
110   ErrorQuarkFunc sym;
111
112   if (!g_module_symbol (self, symbol, (void**)&sym))
113     {
114       g_set_error (error,
115                    G_IO_ERROR,
116                    G_IO_ERROR_FAILED,
117                    "Failed to find symbol '%s'", symbol);
118       return G_TYPE_INVALID;
119     }
120
121   return sym ();
122 }
123
124 static void
125 dump_properties (GType type, GOutputStream *out)
126 {
127   guint i;
128   guint n_properties;
129   GParamSpec **props;
130
131   if (G_TYPE_FUNDAMENTAL (type) == G_TYPE_OBJECT)
132     {
133       GObjectClass *klass;
134       klass = g_type_class_ref (type);
135       props = g_object_class_list_properties (klass, &n_properties);
136     }
137   else
138     {
139       void *klass;
140       klass = g_type_default_interface_ref (type);
141       props = g_object_interface_list_properties (klass, &n_properties);
142     }
143
144   for (i = 0; i < n_properties; i++)
145     {
146       GParamSpec *prop;
147
148       prop = props[i];
149       if (prop->owner_type != type)
150         continue;
151
152       escaped_printf (out, "    <property name=\"%s\" type=\"%s\" flags=\"%d\"/>\n",
153                       prop->name, g_type_name (prop->value_type), prop->flags);
154     }
155   g_free (props);
156 }
157
158 static void
159 dump_signals (GType type, GOutputStream *out)
160 {
161   guint i;
162   guint n_sigs;
163   guint *sig_ids;
164
165   sig_ids = g_signal_list_ids (type, &n_sigs);
166   for (i = 0; i < n_sigs; i++)
167     {
168       guint sigid;
169       GSignalQuery query;
170       guint j;
171
172       sigid = sig_ids[i];
173       g_signal_query (sigid, &query);
174
175       escaped_printf (out, "    <signal name=\"%s\" return=\"%s\"",
176                       query.signal_name, g_type_name (query.return_type));
177
178       if (query.signal_flags & G_SIGNAL_RUN_FIRST)
179         escaped_printf (out, " when=\"first\"");
180       else if (query.signal_flags & G_SIGNAL_RUN_LAST)
181         escaped_printf (out, " when=\"last\"");
182       else if (query.signal_flags & G_SIGNAL_RUN_CLEANUP)
183         escaped_printf (out, " when=\"cleanup\"");
184 #if GLIB_CHECK_VERSION(2, 29, 15)
185       else if (query.signal_flags & G_SIGNAL_MUST_COLLECT)
186         escaped_printf (out, " when=\"must-collect\"");
187 #endif
188       if (query.signal_flags & G_SIGNAL_NO_RECURSE)
189         escaped_printf (out, " no-recurse=\"1\"");
190
191       if (query.signal_flags & G_SIGNAL_DETAILED)
192         escaped_printf (out, " detailed=\"1\"");
193
194       if (query.signal_flags & G_SIGNAL_ACTION)
195         escaped_printf (out, " action=\"1\"");
196
197       if (query.signal_flags & G_SIGNAL_NO_HOOKS)
198         escaped_printf (out, " no-hooks=\"1\"");
199
200       goutput_write (out, ">\n");
201
202       for (j = 0; j < query.n_params; j++)
203         {
204           escaped_printf (out, "      <param type=\"%s\"/>\n",
205                           g_type_name (query.param_types[j]));
206         }
207       goutput_write (out, "    </signal>\n");
208     }
209 }
210
211 static void
212 dump_object_type (GType type, const char *symbol, GOutputStream *out)
213 {
214   guint n_interfaces;
215   guint i;
216   GType *interfaces;
217
218   escaped_printf (out, "  <class name=\"%s\" get-type=\"%s\"",
219                   g_type_name (type), symbol);
220   if (type != G_TYPE_OBJECT)
221     {
222       GString *parent_str;
223       GType parent;
224       gboolean first = TRUE;
225
226       parent = g_type_parent (type);
227       parent_str = g_string_new ("");
228       while (parent != G_TYPE_INVALID)
229         {
230           if (first)
231             first = FALSE;
232           else
233             g_string_append_c (parent_str, ',');
234           g_string_append (parent_str, g_type_name (parent));
235           parent = g_type_parent (parent);
236         }
237
238       escaped_printf (out, " parents=\"%s\"", parent_str->str);
239
240       g_string_free (parent_str, TRUE);
241     }
242
243   if (G_TYPE_IS_ABSTRACT (type))
244     escaped_printf (out, " abstract=\"1\"");
245   goutput_write (out, ">\n");
246
247   interfaces = g_type_interfaces (type, &n_interfaces);
248   for (i = 0; i < n_interfaces; i++)
249     {
250       GType itype = interfaces[i];
251       escaped_printf (out, "    <implements name=\"%s\"/>\n",
252                       g_type_name (itype));
253     }
254   dump_properties (type, out);
255   dump_signals (type, out);
256   goutput_write (out, "  </class>\n");
257 }
258
259 static void
260 dump_interface_type (GType type, const char *symbol, GOutputStream *out)
261 {
262   guint n_interfaces;
263   guint i;
264   GType *interfaces;
265
266   escaped_printf (out, "  <interface name=\"%s\" get-type=\"%s\">\n",
267                   g_type_name (type), symbol);
268
269   interfaces = g_type_interface_prerequisites (type, &n_interfaces);
270   for (i = 0; i < n_interfaces; i++)
271     {
272       GType itype = interfaces[i];
273       if (itype == G_TYPE_OBJECT)
274         {
275           /* Treat this as implicit for now; in theory GInterfaces are
276            * supported on things like GstMiniObject, but right now
277            * the introspection system only supports GObject.
278            * http://bugzilla.gnome.org/show_bug.cgi?id=559706
279            */
280           continue;
281         }
282       escaped_printf (out, "    <prerequisite name=\"%s\"/>\n",
283                       g_type_name (itype));
284     }
285   dump_properties (type, out);
286   dump_signals (type, out);
287   goutput_write (out, "  </interface>\n");
288 }
289
290 static void
291 dump_boxed_type (GType type, const char *symbol, GOutputStream *out)
292 {
293   escaped_printf (out, "  <boxed name=\"%s\" get-type=\"%s\"/>\n",
294                   g_type_name (type), symbol);
295 }
296
297 static void
298 dump_flags_type (GType type, const char *symbol, GOutputStream *out)
299 {
300   guint i;
301   GFlagsClass *klass;
302
303   klass = g_type_class_ref (type);
304   escaped_printf (out, "  <flags name=\"%s\" get-type=\"%s\">\n",
305                   g_type_name (type), symbol);
306
307   for (i = 0; i < klass->n_values; i++)
308     {
309       GFlagsValue *value = &(klass->values[i]);
310
311       escaped_printf (out, "    <member name=\"%s\" nick=\"%s\" value=\"%d\"/>\n",
312                       value->value_name, value->value_nick, value->value);
313     }
314   goutput_write (out, "  </flags>\n");
315 }
316
317 static void
318 dump_enum_type (GType type, const char *symbol, GOutputStream *out)
319 {
320   guint i;
321   GEnumClass *klass;
322
323   klass = g_type_class_ref (type);
324   escaped_printf (out, "  <enum name=\"%s\" get-type=\"%s\">\n",
325                   g_type_name (type), symbol);
326
327   for (i = 0; i < klass->n_values; i++)
328     {
329       GEnumValue *value = &(klass->values[i]);
330
331       escaped_printf (out, "    <member name=\"%s\" nick=\"%s\" value=\"%d\"/>\n",
332                       value->value_name, value->value_nick, value->value);
333     }
334   goutput_write (out, "  </enum>");
335 }
336
337 static void
338 dump_fundamental_type (GType type, const char *symbol, GOutputStream *out)
339 {
340   guint n_interfaces;
341   guint i;
342   GType *interfaces;
343   GString *parent_str;
344   GType parent;
345   gboolean first = TRUE;
346
347
348   escaped_printf (out, "  <fundamental name=\"%s\" get-type=\"%s\"",
349                   g_type_name (type), symbol);
350
351   if (G_TYPE_IS_ABSTRACT (type))
352     escaped_printf (out, " abstract=\"1\"");
353
354   if (G_TYPE_IS_INSTANTIATABLE (type))
355     escaped_printf (out, " instantiatable=\"1\"");
356
357   parent = g_type_parent (type);
358   parent_str = g_string_new ("");
359   while (parent != G_TYPE_INVALID)
360     {
361       if (first)
362         first = FALSE;
363       else
364         g_string_append_c (parent_str, ',');
365       if (!g_type_name (parent))
366         break;
367       g_string_append (parent_str, g_type_name (parent));
368       parent = g_type_parent (parent);
369     }
370
371   if (parent_str->len > 0)
372     escaped_printf (out, " parents=\"%s\"", parent_str->str);
373   g_string_free (parent_str, TRUE);
374
375   goutput_write (out, ">\n");
376
377   interfaces = g_type_interfaces (type, &n_interfaces);
378   for (i = 0; i < n_interfaces; i++)
379     {
380       GType itype = interfaces[i];
381       escaped_printf (out, "    <implements name=\"%s\"/>\n",
382                       g_type_name (itype));
383     }
384   goutput_write (out, "  </fundamental>\n");
385 }
386
387 static void
388 dump_type (GType type, const char *symbol, GOutputStream *out)
389 {
390   switch (g_type_fundamental (type))
391     {
392     case G_TYPE_OBJECT:
393       dump_object_type (type, symbol, out);
394       break;
395     case G_TYPE_INTERFACE:
396       dump_interface_type (type, symbol, out);
397       break;
398     case G_TYPE_BOXED:
399       dump_boxed_type (type, symbol, out);
400       break;
401     case G_TYPE_FLAGS:
402       dump_flags_type (type, symbol, out);
403       break;
404     case G_TYPE_ENUM:
405       dump_enum_type (type, symbol, out);
406       break;
407     case G_TYPE_POINTER:
408       /* GValue, etc.  Just skip them. */
409       break;
410     default:
411       dump_fundamental_type (type, symbol, out);
412       break;
413     }
414 }
415
416 static void
417 dump_error_quark (GQuark quark, const char *symbol, GOutputStream *out)
418 {
419   escaped_printf (out, "  <error-quark function=\"%s\" domain=\"%s\"/>\n",
420                   symbol, g_quark_to_string (quark));
421 }
422
423 /**
424  * g_irepository_dump:
425  * @arg: Comma-separated pair of input and output filenames
426  * @error: a %GError
427  *
428  * Argument specified is a comma-separated pair of filenames; i.e. of
429  * the form "input.txt,output.xml".  The input file should be a
430  * UTF-8 Unix-line-ending text file, with each line containing the name
431  * of a GType _get_type function.
432  *
433  * The output file should already exist, but be empty.  This function will
434  * overwrite its contents.
435  *
436  * Returns: %TRUE on success, %FALSE on error
437  */
438 #ifndef G_IREPOSITORY_COMPILATION
439 static gboolean
440 dump_irepository (const char *arg, GError **error) G_GNUC_UNUSED;
441 static gboolean
442 dump_irepository (const char *arg, GError **error)
443 #else
444 gboolean
445 g_irepository_dump (const char *arg, GError **error)
446 #endif
447 {
448   GHashTable *output_types;
449   char **args;
450   GFile *input_file;
451   GFile *output_file;
452   GFileInputStream *input;
453   GFileOutputStream *output;
454   GDataInputStream *in;
455   GModule *self;
456   gboolean caught_error = FALSE;
457
458   self = g_module_open (NULL, 0);
459   if (!self)
460     {
461       g_set_error (error,
462                    G_IO_ERROR,
463                    G_IO_ERROR_FAILED,
464                    "failed to open self: %s",
465                    g_module_error ());
466       return FALSE;
467     }
468
469   args = g_strsplit (arg, ",", 2);
470
471   input_file = g_file_new_for_path (args[0]);
472   output_file = g_file_new_for_path (args[1]);
473
474   input = g_file_read (input_file, NULL, error);
475   if (input == NULL)
476     return FALSE;
477
478   output = g_file_replace (output_file, NULL, FALSE, 0, NULL, error);
479   if (output == NULL)
480     {
481       g_input_stream_close (G_INPUT_STREAM (input), NULL, NULL);
482       return FALSE;
483     }
484
485   goutput_write (G_OUTPUT_STREAM (output), "<?xml version=\"1.0\"?>\n");
486   goutput_write (G_OUTPUT_STREAM (output), "<dump>\n");
487
488   output_types = g_hash_table_new (NULL, NULL);
489
490   in = g_data_input_stream_new (G_INPUT_STREAM (input));
491   g_object_unref (input);
492
493   while (TRUE)
494     {
495       gsize len;
496       char *line = g_data_input_stream_read_line (in, &len, NULL, NULL);
497       const char *function;
498
499       if (line == NULL || *line == '\0')
500         {
501           g_free (line);
502           break;
503         }
504
505       g_strchomp (line);
506
507       if (strncmp (line, "get-type:", strlen ("get-type:")) == 0)
508         {
509           GType type;
510
511           function = line + strlen ("get-type:");
512
513           type = invoke_get_type (self, function, error);
514
515           if (type == G_TYPE_INVALID)
516             {
517               g_printerr ("Invalid GType function: '%s'\n", function);
518               caught_error = TRUE;
519               g_free (line);
520               break;
521             }
522
523           if (g_hash_table_lookup (output_types, (gpointer) type))
524             goto next;
525           g_hash_table_insert (output_types, (gpointer) type, (gpointer) type);
526
527           dump_type (type, function, G_OUTPUT_STREAM (output));
528         }
529       else if (strncmp (line, "error-quark:", strlen ("error-quark:")) == 0)
530         {
531           GQuark quark;
532           function = line + strlen ("error-quark:");
533           quark = invoke_error_quark (self, function, error);
534
535           if (quark == 0)
536             {
537               g_printerr ("Invalid error quark function: '%s'\n", function);
538               caught_error = TRUE;
539               g_free (line);
540               break;
541             }
542
543           dump_error_quark (quark, function, G_OUTPUT_STREAM (output));
544         }
545
546
547     next:
548       g_free (line);
549     }
550
551   g_hash_table_destroy (output_types);
552
553   goutput_write (G_OUTPUT_STREAM (output), "</dump>\n");
554
555   {
556     GError **ioerror;
557     /* Avoid overwriting an earlier set error */
558     if (caught_error)
559       ioerror = NULL;
560     else
561       ioerror = error;
562     if (!g_input_stream_close (G_INPUT_STREAM (in), NULL, ioerror))
563       return FALSE;
564     if (!g_output_stream_close (G_OUTPUT_STREAM (output), NULL, ioerror))
565       return FALSE;
566   }
567
568   return !caught_error;
569 }
570
571
572 int
573 main(int argc, char **argv)
574 {
575   GError *error = NULL;
576   const char *introspect_dump_prefix = "--introspect-dump=";
577
578   g_type_init ();
579
580   
581
582   if (argc != 2 || !g_str_has_prefix (argv[1], introspect_dump_prefix))
583     {
584       g_printerr ("Usage: %s --introspect-dump=input,output", argv[0]);
585       exit (1);
586     }
587
588   if (!dump_irepository (argv[1] + strlen(introspect_dump_prefix), &error))
589     {
590       g_printerr ("%s\n", error->message);
591       exit (1);
592     }
593   exit (0);
594 }