summaryrefslogtreecommitdiff
path: root/girepository/girwriter.c
diff options
context:
space:
mode:
authorJohan Dahlin <johan@gnome.org>2008-08-09 12:46:48 +0000
committerJohan Dahlin <johan@src.gnome.org>2008-08-09 12:46:48 +0000
commitc37a96568cec88cb82ba3eadfaf513578eca7c76 (patch)
tree2185ece8e97167ec65e37ec866f7486e5b5eb88f /girepository/girwriter.c
parentb9c41e1af4e481c370806996cfa1e7ca61226a60 (diff)
downloadgobject-introspection-c37a96568cec88cb82ba3eadfaf513578eca7c76.tar.gz
Move shared *.[ch] files to girepository from tools
2008-08-09 Johan Dahlin <johan@gnome.org> * girepository/Makefile.am: * tools/Makefile.am: * tools/girmodule.c: * tools/girmodule.h: * tools/girnode.c: * tools/girnode.h: * tools/girparser.c: * tools/girparser.h: * tools/girwriter.c: * tools/girwriter.h: Move shared *.[ch] files to girepository from tools svn path=/trunk/; revision=337
Diffstat (limited to 'girepository/girwriter.c')
-rw-r--r--girepository/girwriter.c532
1 files changed, 532 insertions, 0 deletions
diff --git a/girepository/girwriter.c b/girepository/girwriter.c
new file mode 100644
index 00000000..d4d55063
--- /dev/null
+++ b/girepository/girwriter.c
@@ -0,0 +1,532 @@
+/* GObject introspection: gen-introspect
+ *
+ * Copyright (C) 2007 Jürg Billeter
+ * Copyright (C) 2007 Johan Dahlin
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Jürg Billeter <j@bitron.ch>
+ */
+
+#include <stdio.h>
+#include <glib.h>
+#include "scanner.h"
+#include "gidlnode.h"
+
+typedef struct {
+ int indent;
+ FILE *output;
+} GIdlWriter;
+
+static void node_generate (GIdlWriter * writer, GIdlNode * node);
+
+static void
+g_writer_write_inline (GIdlWriter * writer, const char *s)
+{
+ fprintf (writer->output, "%s", s);
+}
+
+static void
+g_writer_write (GIdlWriter * writer, const char *s)
+{
+ int i;
+ for (i = 0; i < writer->indent; i++)
+ {
+ fprintf (writer->output, "\t");
+ }
+
+ g_writer_write_inline (writer, s);
+}
+
+static void
+g_writer_write_indent (GIdlWriter * writer, const char *s)
+{
+ g_writer_write (writer, s);
+ writer->indent++;
+}
+
+static void
+g_writer_write_unindent (GIdlWriter * writer, const char *s)
+{
+ writer->indent--;
+ g_writer_write (writer, s);
+}
+
+static void
+field_generate (GIdlWriter * writer, GIdlNodeField * node)
+{
+ char *markup =
+ g_markup_printf_escaped ("<field name=\"%s\" type=\"%s\"/>\n",
+ node->node.name, node->type->unparsed);
+ g_writer_write (writer, markup);
+ g_free (markup);
+}
+
+static void
+value_generate (GIdlWriter * writer, GIdlNodeValue * node)
+{
+ char *markup =
+ g_markup_printf_escaped ("<member name=\"%s\" value=\"%d\"/>\n",
+ node->node.name, node->value);
+ g_writer_write (writer, markup);
+ g_free (markup);
+}
+
+static void
+constant_generate (GIdlWriter * writer, GIdlNodeConstant * node)
+{
+ char *markup =
+ g_markup_printf_escaped
+ ("<constant name=\"%s\" type=\"%s\" value=\"%s\"/>\n", node->node.name,
+ node->type->unparsed, node->value);
+ g_writer_write (writer, markup);
+ g_free (markup);
+}
+
+static void
+property_generate (GIdlWriter * writer, GIdlNodeProperty * node)
+{
+ char *markup =
+ g_markup_printf_escaped ("<property name=\"%s\" "
+ "type=\"%s\" "
+ "readable=\"%s\" "
+ "writable=\"%s\" "
+ "construct=\"%s\" "
+ "construct-only=\"%s\"/>\n",
+ node->node.name,
+ node->type->unparsed,
+ node->readable ? "1" : "0",
+ node->writable ? "1" : "0",
+ node->construct ? "1" : "0",
+ node->construct_only ? "1" : "0");
+ g_writer_write (writer, markup);
+ g_free (markup);
+}
+
+static void
+function_generate (GIdlWriter * writer, GIdlNodeFunction * node)
+{
+ const char *tag_name;
+ GString *markup_s;
+ gchar *markup;
+
+ if (node->node.type == G_IR_NODE_CALLBACK)
+ tag_name = "callback";
+ else if (node->is_constructor)
+ tag_name = "constructor";
+ else if (node->is_method)
+ tag_name = "method";
+ else
+ tag_name = "function";
+
+ markup_s = g_string_new ("<");
+ g_string_append_printf (markup_s,
+ "%s name=\"%s\"",
+ tag_name, node->node.name);
+
+ if (node->node.type != G_IR_NODE_CALLBACK)
+ g_string_append_printf (markup_s,
+ g_markup_printf_escaped (" symbol=\"%s\"", node->symbol));
+
+ if (node->deprecated)
+ g_string_append_printf (markup_s, " deprecated=\"1\"");
+
+ g_string_append (markup_s, ">\n");
+
+ g_writer_write_indent (writer, markup_s->str);
+ g_string_free (markup_s, TRUE);
+
+ markup_s =
+ g_string_new (g_markup_printf_escaped ("<return-type type=\"%s\"",
+ node->result->type->unparsed));
+
+ if (node->result->transfer)
+ g_string_append (markup_s, g_markup_printf_escaped (" transfer=\"full\"/>\n"));
+ else
+ g_string_append (markup_s, "/>\n");
+
+ g_writer_write (writer, markup_s->str);
+ g_string_free (markup_s, TRUE);
+
+ if (node->parameters != NULL)
+ {
+ GList *l;
+ g_writer_write_indent (writer, "<parameters>\n");
+ for (l = node->parameters; l != NULL; l = l->next)
+ {
+ GIdlNodeParam *param = l->data;
+ const gchar *direction = g_idl_node_param_direction_string (param);
+
+ markup_s = g_string_new ("<parameter");
+
+ g_string_append_printf (markup_s, " name=\"%s\"", param->node.name);
+
+ g_string_append (markup_s,
+ g_markup_printf_escaped (" type=\"%s\"",
+ param->type->unparsed));
+
+ if (param->transfer)
+ g_string_append (markup_s,
+ g_markup_printf_escaped (" transfer=\"full\""));
+
+ if (param->null_ok)
+ g_string_append (markup_s,
+ g_markup_printf_escaped (" null-ok=\"1\""));
+
+ if (strcmp (direction, "in") != 0)
+ g_string_append (markup_s,
+ g_markup_printf_escaped (" direction=\"%s\"",
+ direction));
+
+ g_string_append (markup_s, "/>\n");
+
+ g_writer_write (writer, markup_s->str);
+ g_string_free (markup_s, TRUE);
+ }
+ g_writer_write_unindent (writer, "</parameters>\n");
+ }
+ markup = g_strdup_printf ("</%s>\n", tag_name);
+ g_writer_write_unindent (writer, markup);
+ g_free (markup);
+}
+
+static void
+vfunc_generate (GIdlWriter * writer, GIdlNodeVFunc * node)
+{
+ char *markup =
+ g_markup_printf_escaped ("<vfunc name=\"%s\">\n", node->node.name);
+ g_writer_write_indent (writer, markup);
+ g_free (markup);
+ markup =
+ g_markup_printf_escaped ("<return-type type=\"%s\"/>\n",
+ node->result->type->unparsed);
+ g_writer_write (writer, markup);
+ g_free (markup);
+ if (node->parameters != NULL)
+ {
+ GList *l;
+ g_writer_write_indent (writer, "<parameters>\n");
+ for (l = node->parameters; l != NULL; l = l->next)
+ {
+ GIdlNodeParam *param = l->data;
+ markup =
+ g_markup_printf_escaped ("<parameter name=\"%s\" type=\"%s\"/>\n",
+ param->node.name, param->type->unparsed);
+ g_writer_write (writer, markup);
+ g_free (markup);
+ }
+ g_writer_write_unindent (writer, "</parameters>\n");
+ }
+ g_writer_write_unindent (writer, "</vfunc>\n");
+}
+
+static void
+signal_generate (GIdlWriter * writer, GIdlNodeSignal * node)
+{
+ char *markup;
+ const char *when = "LAST";
+ if (node->run_first)
+ {
+ when = "FIRST";
+ }
+ else if (node->run_cleanup)
+ {
+ when = "CLEANUP";
+ }
+ markup =
+ g_markup_printf_escaped ("<signal name=\"%s\" when=\"%s\">\n",
+ node->node.name, when);
+ g_writer_write_indent (writer, markup);
+ g_free (markup);
+ markup =
+ g_markup_printf_escaped ("<return-type type=\"%s\"/>\n",
+ node->result->type->unparsed);
+ g_writer_write (writer, markup);
+ g_free (markup);
+ if (node->parameters != NULL)
+ {
+ GList *l;
+ g_writer_write_indent (writer, "<parameters>\n");
+ for (l = node->parameters; l != NULL; l = l->next)
+ {
+ GIdlNodeParam *param = l->data;
+ markup =
+ g_markup_printf_escaped ("<parameter name=\"%s\" type=\"%s\"/>\n",
+ param->node.name, param->type->unparsed);
+ g_writer_write (writer, markup);
+ g_free (markup);
+ }
+ g_writer_write_unindent (writer, "</parameters>\n");
+ }
+ g_writer_write_unindent (writer, "</signal>\n");
+}
+
+static void
+interface_generate (GIdlWriter * writer, GIdlNodeInterface * node)
+{
+ GList *l;
+ char *markup;
+ if (node->node.type == G_IR_NODE_OBJECT)
+ {
+ markup =
+ g_markup_printf_escaped ("<object name=\"%s\" "
+ "parent=\"%s\" "
+ "type-name=\"%s\" "
+ "get-type=\"%s\">\n",
+ node->node.name,
+ node->parent,
+ node->gtype_name,
+ node->gtype_init);
+ }
+ else if (node->node.type == G_IR_NODE_INTERFACE)
+ {
+ markup =
+ g_markup_printf_escaped
+ ("<interface name=\"%s\" type-name=\"%s\" get-type=\"%s\">\n",
+ node->node.name, node->gtype_name, node->gtype_init);
+ }
+
+ g_writer_write_indent (writer, markup);
+ g_free (markup);
+ if (node->node.type == G_IR_NODE_OBJECT && node->interfaces != NULL)
+ {
+ GList *l;
+ g_writer_write_indent (writer, "<implements>\n");
+ for (l = node->interfaces; l != NULL; l = l->next)
+ {
+ markup =
+ g_markup_printf_escaped ("<interface name=\"%s\"/>\n",
+ (char *) l->data);
+ g_writer_write (writer, markup);
+ g_free (markup);
+ }
+ g_writer_write_unindent (writer, "</implements>\n");
+ }
+ else if (node->node.type == G_IR_NODE_INTERFACE
+ && node->prerequisites != NULL)
+ {
+ GList *l;
+ g_writer_write_indent (writer, "<requires>\n");
+ for (l = node->prerequisites; l != NULL; l = l->next)
+ {
+ markup =
+ g_markup_printf_escaped ("<interface name=\"%s\"/>\n",
+ (char *) l->data);
+ g_writer_write (writer, markup);
+ g_free (markup);
+ }
+ g_writer_write_unindent (writer, "</requires>\n");
+ }
+
+ for (l = node->members; l != NULL; l = l->next)
+ {
+ node_generate (writer, l->data);
+ }
+
+ if (node->node.type == G_IR_NODE_OBJECT)
+ {
+ g_writer_write_unindent (writer, "</object>\n");
+ }
+ else if (node->node.type == G_IR_NODE_INTERFACE)
+ {
+ g_writer_write_unindent (writer, "</interface>\n");
+ }
+}
+
+static void
+struct_generate (GIdlWriter * writer, GIdlNodeStruct * node)
+{
+ GList *l;
+ char *markup =
+ g_markup_printf_escaped ("<struct name=\"%s\">\n", node->node.name);
+ g_writer_write_indent (writer, markup);
+ g_free (markup);
+ for (l = node->members; l != NULL; l = l->next)
+ {
+ node_generate (writer, l->data);
+ }
+ g_writer_write_unindent (writer, "</struct>\n");
+}
+
+static void
+union_generate (GIdlWriter * writer, GIdlNodeUnion * node)
+{
+ GList *l;
+ char *markup =
+ g_markup_printf_escaped ("<union name=\"%s\">\n", node->node.name);
+ g_writer_write_indent (writer, markup);
+ g_free (markup);
+ for (l = node->members; l != NULL; l = l->next)
+ {
+ node_generate (writer, l->data);
+ }
+ g_writer_write_unindent (writer, "</union>\n");
+}
+
+static void
+boxed_generate (GIdlWriter * writer, GIdlNodeBoxed * node)
+{
+ GList *l;
+ char *markup =
+ g_markup_printf_escaped
+ ("<boxed name=\"%s\" type-name=\"%s\" get-type=\"%s\">\n",
+ node->node.name, node->gtype_name, node->gtype_init);
+ g_writer_write_indent (writer, markup);
+ g_free (markup);
+ for (l = node->members; l != NULL; l = l->next)
+ {
+ node_generate (writer, l->data);
+ }
+ g_writer_write_unindent (writer, "</boxed>\n");
+}
+
+static void
+enum_generate (GIdlWriter * writer, GIdlNodeEnum * node)
+{
+ GList *l;
+ GString *markup_s;
+ char *markup;
+ const char *tag_name = NULL;
+
+ if (node->node.type == G_IR_NODE_ENUM)
+ {
+ tag_name = "enum";
+ }
+ else if (node->node.type == G_IR_NODE_FLAGS)
+ {
+ tag_name = "flags";
+ }
+
+ markup_s = g_string_new ("<");
+ g_string_append_printf (markup_s,
+ "%s name=\"%s\"",
+ tag_name, node->node.name);
+
+ if (node->gtype_name != NULL)
+ g_string_append_printf (markup_s,
+ g_markup_printf_escaped (" type-name=\"%s\"", node->gtype_name));
+
+ if (node->gtype_init != NULL)
+ g_string_append_printf (markup_s,
+ g_markup_printf_escaped (" get-type=\"%s\"", node->gtype_init));
+
+ if (node->deprecated)
+ g_string_append_printf (markup_s, " deprecated=\"1\"");
+
+ g_string_append (markup_s, ">\n");
+
+ g_writer_write_indent (writer, markup_s->str);
+ g_string_free (markup_s, TRUE);
+
+ for (l = node->values; l != NULL; l = l->next)
+ {
+ node_generate (writer, l->data);
+ }
+
+ markup = g_strdup_printf ("</%s>\n", tag_name);
+ g_writer_write_unindent (writer, markup);
+ g_free (markup);
+}
+
+static void
+node_generate (GIdlWriter * writer, GIdlNode * node)
+{
+ switch (node->type)
+ {
+ case G_IR_NODE_FUNCTION:
+ case G_IR_NODE_CALLBACK:
+ function_generate (writer, (GIdlNodeFunction *) node);
+ break;
+ case G_IR_NODE_VFUNC:
+ vfunc_generate (writer, (GIdlNodeVFunc *) node);
+ break;
+ case G_IR_NODE_OBJECT:
+ case G_IR_NODE_INTERFACE:
+ interface_generate (writer, (GIdlNodeInterface *) node);
+ break;
+ case G_IR_NODE_STRUCT:
+ struct_generate (writer, (GIdlNodeStruct *) node);
+ break;
+ case G_IR_NODE_UNION:
+ union_generate (writer, (GIdlNodeUnion *) node);
+ break;
+ case G_IR_NODE_BOXED:
+ boxed_generate (writer, (GIdlNodeBoxed *) node);
+ break;
+ case G_IR_NODE_ENUM:
+ case G_IR_NODE_FLAGS:
+ enum_generate (writer, (GIdlNodeEnum *) node);
+ break;
+ case G_IR_NODE_PROPERTY:
+ property_generate (writer, (GIdlNodeProperty *) node);
+ break;
+ case G_IR_NODE_FIELD:
+ field_generate (writer, (GIdlNodeField *) node);
+ break;
+ case G_IR_NODE_SIGNAL:
+ signal_generate (writer, (GIdlNodeSignal *) node);
+ break;
+ case G_IR_NODE_VALUE:
+ value_generate (writer, (GIdlNodeValue *) node);
+ break;
+ case G_IR_NODE_CONSTANT:
+ constant_generate (writer, (GIdlNodeConstant *) node);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+g_writer_write_module (GIdlWriter * writer, GIdlModule * module)
+{
+ GList *l;
+ char *markup =
+ g_markup_printf_escaped ("<namespace name=\"%s\">\n", module->name);
+ g_writer_write_indent (writer, markup);
+ g_free (markup);
+ for (l = module->entries; l != NULL; l = l->next)
+ {
+ node_generate (writer, l->data);
+ }
+ g_writer_write_unindent (writer, "</namespace>\n");
+}
+
+void
+g_idl_writer_save_file (GIdlModule *module,
+ const gchar *filename)
+{
+ GIdlWriter *writer;
+
+ writer = g_new0 (GIdlWriter, 1);
+
+ if (!filename)
+ writer->output = stdout;
+ else
+ writer->output = fopen (filename, "w");
+
+ g_writer_write (writer, "<?xml version=\"1.0\"?>\n");
+ g_writer_write_indent (writer, "<repository version=\"1.0\""
+ "xmlns=\"http://www.gtk.org/introspection/core/1.0\""
+ "xmlns:c=\"http://www.gtk.org/introspection/c/1.0\""
+ "xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\">");
+ g_writer_write_module (writer, module);
+ g_writer_write_unindent (writer, "</repository>\n");
+
+ if (filename)
+ fclose (writer->output);
+}