1 /* GObject introspection: gen-introspect
3 * Copyright (C) 2007 Jürg Billeter
4 * Copyright (C) 2007 Johan Dahlin
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 * Jürg Billeter <j@bitron.ch>
35 static void node_generate (GIdlWriter * writer, GIdlNode * node);
38 g_writer_write_inline (GIdlWriter * writer, const char *s)
40 fprintf (writer->output, "%s", s);
44 g_writer_write (GIdlWriter * writer, const char *s)
47 for (i = 0; i < writer->indent; i++)
49 fprintf (writer->output, "\t");
52 g_writer_write_inline (writer, s);
56 g_writer_write_indent (GIdlWriter * writer, const char *s)
58 g_writer_write (writer, s);
63 g_writer_write_unindent (GIdlWriter * writer, const char *s)
66 g_writer_write (writer, s);
70 field_generate (GIdlWriter * writer, GIdlNodeField * node)
73 g_markup_printf_escaped ("<field name=\"%s\" type=\"%s\"/>\n",
74 node->node.name, node->type->unparsed);
75 g_writer_write (writer, markup);
80 value_generate (GIdlWriter * writer, GIdlNodeValue * node)
83 g_markup_printf_escaped ("<member name=\"%s\" value=\"%d\"/>\n",
84 node->node.name, node->value);
85 g_writer_write (writer, markup);
90 constant_generate (GIdlWriter * writer, GIdlNodeConstant * node)
93 g_markup_printf_escaped
94 ("<constant name=\"%s\" type=\"%s\" value=\"%s\"/>\n", node->node.name,
95 node->type->unparsed, node->value);
96 g_writer_write (writer, markup);
101 property_generate (GIdlWriter * writer, GIdlNodeProperty * node)
104 g_markup_printf_escaped ("<property name=\"%s\" "
109 "construct-only=\"%s\"/>\n",
111 node->type->unparsed,
112 node->readable ? "1" : "0",
113 node->writable ? "1" : "0",
114 node->construct ? "1" : "0",
115 node->construct_only ? "1" : "0");
116 g_writer_write (writer, markup);
121 function_generate (GIdlWriter * writer, GIdlNodeFunction * node)
123 const char *tag_name;
127 if (node->node.type == G_IR_NODE_CALLBACK)
128 tag_name = "callback";
129 else if (node->is_constructor)
130 tag_name = "constructor";
131 else if (node->is_method)
134 tag_name = "function";
136 markup_s = g_string_new ("<");
137 g_string_append_printf (markup_s,
139 tag_name, node->node.name);
141 if (node->node.type != G_IR_NODE_CALLBACK)
142 g_string_append_printf (markup_s,
143 g_markup_printf_escaped (" symbol=\"%s\"", node->symbol));
145 if (node->deprecated)
146 g_string_append_printf (markup_s, " deprecated=\"1\"");
148 g_string_append (markup_s, ">\n");
150 g_writer_write_indent (writer, markup_s->str);
151 g_string_free (markup_s, TRUE);
154 g_string_new (g_markup_printf_escaped ("<return-type type=\"%s\"",
155 node->result->type->unparsed));
157 if (node->result->transfer)
158 g_string_append (markup_s, g_markup_printf_escaped (" transfer=\"full\"/>\n"));
160 g_string_append (markup_s, "/>\n");
162 g_writer_write (writer, markup_s->str);
163 g_string_free (markup_s, TRUE);
165 if (node->parameters != NULL)
168 g_writer_write_indent (writer, "<parameters>\n");
169 for (l = node->parameters; l != NULL; l = l->next)
171 GIdlNodeParam *param = l->data;
172 const gchar *direction = g_idl_node_param_direction_string (param);
174 markup_s = g_string_new ("<parameter");
176 g_string_append_printf (markup_s, " name=\"%s\"", param->node.name);
178 g_string_append (markup_s,
179 g_markup_printf_escaped (" type=\"%s\"",
180 param->type->unparsed));
183 g_string_append (markup_s,
184 g_markup_printf_escaped (" transfer=\"full\""));
186 if (param->allow_none)
187 g_string_append (markup_s,
188 g_markup_printf_escaped (" allow-none=\"1\""));
190 if (strcmp (direction, "in") != 0)
191 g_string_append (markup_s,
192 g_markup_printf_escaped (" direction=\"%s\"",
195 g_string_append (markup_s, "/>\n");
197 g_writer_write (writer, markup_s->str);
198 g_string_free (markup_s, TRUE);
200 g_writer_write_unindent (writer, "</parameters>\n");
202 markup = g_strdup_printf ("</%s>\n", tag_name);
203 g_writer_write_unindent (writer, markup);
208 vfunc_generate (GIdlWriter * writer, GIdlNodeVFunc * node)
211 g_markup_printf_escaped ("<vfunc name=\"%s\">\n", node->node.name);
212 g_writer_write_indent (writer, markup);
215 g_markup_printf_escaped ("<return-type type=\"%s\"/>\n",
216 node->result->type->unparsed);
217 g_writer_write (writer, markup);
219 if (node->parameters != NULL)
222 g_writer_write_indent (writer, "<parameters>\n");
223 for (l = node->parameters; l != NULL; l = l->next)
225 GIdlNodeParam *param = l->data;
227 g_markup_printf_escaped ("<parameter name=\"%s\" type=\"%s\"/>\n",
228 param->node.name, param->type->unparsed);
229 g_writer_write (writer, markup);
232 g_writer_write_unindent (writer, "</parameters>\n");
234 g_writer_write_unindent (writer, "</vfunc>\n");
238 signal_generate (GIdlWriter * writer, GIdlNodeSignal * node)
241 const char *when = "LAST";
246 else if (node->run_cleanup)
251 g_markup_printf_escaped ("<signal name=\"%s\" when=\"%s\">\n",
252 node->node.name, when);
253 g_writer_write_indent (writer, markup);
256 g_markup_printf_escaped ("<return-type type=\"%s\"/>\n",
257 node->result->type->unparsed);
258 g_writer_write (writer, markup);
260 if (node->parameters != NULL)
263 g_writer_write_indent (writer, "<parameters>\n");
264 for (l = node->parameters; l != NULL; l = l->next)
266 GIdlNodeParam *param = l->data;
268 g_markup_printf_escaped ("<parameter name=\"%s\" type=\"%s\"/>\n",
269 param->node.name, param->type->unparsed);
270 g_writer_write (writer, markup);
273 g_writer_write_unindent (writer, "</parameters>\n");
275 g_writer_write_unindent (writer, "</signal>\n");
279 interface_generate (GIdlWriter * writer, GIdlNodeInterface * node)
283 if (node->node.type == G_IR_NODE_OBJECT)
286 g_markup_printf_escaped ("<object name=\"%s\" "
289 "get-type=\"%s\">\n",
295 else if (node->node.type == G_IR_NODE_INTERFACE)
298 g_markup_printf_escaped
299 ("<interface name=\"%s\" type-name=\"%s\" get-type=\"%s\">\n",
300 node->node.name, node->gtype_name, node->gtype_init);
303 g_writer_write_indent (writer, markup);
305 if (node->node.type == G_IR_NODE_OBJECT && node->interfaces != NULL)
308 g_writer_write_indent (writer, "<implements>\n");
309 for (l = node->interfaces; l != NULL; l = l->next)
312 g_markup_printf_escaped ("<interface name=\"%s\"/>\n",
314 g_writer_write (writer, markup);
317 g_writer_write_unindent (writer, "</implements>\n");
319 else if (node->node.type == G_IR_NODE_INTERFACE
320 && node->prerequisites != NULL)
323 g_writer_write_indent (writer, "<requires>\n");
324 for (l = node->prerequisites; l != NULL; l = l->next)
327 g_markup_printf_escaped ("<interface name=\"%s\"/>\n",
329 g_writer_write (writer, markup);
332 g_writer_write_unindent (writer, "</requires>\n");
335 for (l = node->members; l != NULL; l = l->next)
337 node_generate (writer, l->data);
340 if (node->node.type == G_IR_NODE_OBJECT)
342 g_writer_write_unindent (writer, "</object>\n");
344 else if (node->node.type == G_IR_NODE_INTERFACE)
346 g_writer_write_unindent (writer, "</interface>\n");
351 struct_generate (GIdlWriter * writer, GIdlNodeStruct * node)
355 g_markup_printf_escaped ("<struct name=\"%s\">\n", node->node.name);
356 g_writer_write_indent (writer, markup);
358 for (l = node->members; l != NULL; l = l->next)
360 node_generate (writer, l->data);
362 g_writer_write_unindent (writer, "</struct>\n");
366 union_generate (GIdlWriter * writer, GIdlNodeUnion * node)
370 g_markup_printf_escaped ("<union name=\"%s\">\n", node->node.name);
371 g_writer_write_indent (writer, markup);
373 for (l = node->members; l != NULL; l = l->next)
375 node_generate (writer, l->data);
377 g_writer_write_unindent (writer, "</union>\n");
381 boxed_generate (GIdlWriter * writer, GIdlNodeBoxed * node)
385 g_markup_printf_escaped
386 ("<boxed name=\"%s\" type-name=\"%s\" get-type=\"%s\">\n",
387 node->node.name, node->gtype_name, node->gtype_init);
388 g_writer_write_indent (writer, markup);
390 for (l = node->members; l != NULL; l = l->next)
392 node_generate (writer, l->data);
394 g_writer_write_unindent (writer, "</boxed>\n");
398 enum_generate (GIdlWriter * writer, GIdlNodeEnum * node)
403 const char *tag_name = NULL;
405 if (node->node.type == G_IR_NODE_ENUM)
409 else if (node->node.type == G_IR_NODE_FLAGS)
414 markup_s = g_string_new ("<");
415 g_string_append_printf (markup_s,
417 tag_name, node->node.name);
419 if (node->gtype_name != NULL)
420 g_string_append_printf (markup_s,
421 g_markup_printf_escaped (" type-name=\"%s\"", node->gtype_name));
423 if (node->gtype_init != NULL)
424 g_string_append_printf (markup_s,
425 g_markup_printf_escaped (" get-type=\"%s\"", node->gtype_init));
427 if (node->deprecated)
428 g_string_append_printf (markup_s, " deprecated=\"1\"");
430 g_string_append (markup_s, ">\n");
432 g_writer_write_indent (writer, markup_s->str);
433 g_string_free (markup_s, TRUE);
435 for (l = node->values; l != NULL; l = l->next)
437 node_generate (writer, l->data);
440 markup = g_strdup_printf ("</%s>\n", tag_name);
441 g_writer_write_unindent (writer, markup);
446 node_generate (GIdlWriter * writer, GIdlNode * node)
450 case G_IR_NODE_FUNCTION:
451 case G_IR_NODE_CALLBACK:
452 function_generate (writer, (GIdlNodeFunction *) node);
454 case G_IR_NODE_VFUNC:
455 vfunc_generate (writer, (GIdlNodeVFunc *) node);
457 case G_IR_NODE_OBJECT:
458 case G_IR_NODE_INTERFACE:
459 interface_generate (writer, (GIdlNodeInterface *) node);
461 case G_IR_NODE_STRUCT:
462 struct_generate (writer, (GIdlNodeStruct *) node);
464 case G_IR_NODE_UNION:
465 union_generate (writer, (GIdlNodeUnion *) node);
467 case G_IR_NODE_BOXED:
468 boxed_generate (writer, (GIdlNodeBoxed *) node);
471 case G_IR_NODE_FLAGS:
472 enum_generate (writer, (GIdlNodeEnum *) node);
474 case G_IR_NODE_PROPERTY:
475 property_generate (writer, (GIdlNodeProperty *) node);
477 case G_IR_NODE_FIELD:
478 field_generate (writer, (GIdlNodeField *) node);
480 case G_IR_NODE_SIGNAL:
481 signal_generate (writer, (GIdlNodeSignal *) node);
483 case G_IR_NODE_VALUE:
484 value_generate (writer, (GIdlNodeValue *) node);
486 case G_IR_NODE_CONSTANT:
487 constant_generate (writer, (GIdlNodeConstant *) node);
490 g_assert_not_reached ();
495 g_writer_write_module (GIdlWriter * writer, GIdlModule * module)
499 g_markup_printf_escaped ("<namespace name=\"%s\">\n", module->name);
500 g_writer_write_indent (writer, markup);
502 for (l = module->entries; l != NULL; l = l->next)
504 node_generate (writer, l->data);
506 g_writer_write_unindent (writer, "</namespace>\n");
510 g_idl_writer_save_file (GIdlModule *module,
511 const gchar *filename)
515 writer = g_new0 (GIdlWriter, 1);
518 writer->output = stdout;
520 writer->output = fopen (filename, "w");
522 g_writer_write (writer, "<?xml version=\"1.0\"?>\n");
523 g_writer_write_indent (writer, "<repository version=\"1.0\""
524 "xmlns=\"http://www.gtk.org/introspection/core/1.0\""
525 "xmlns:c=\"http://www.gtk.org/introspection/c/1.0\""
526 "xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\">");
527 g_writer_write_module (writer, module);
528 g_writer_write_unindent (writer, "</repository>\n");
531 fclose (writer->output);