summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2009-05-15 21:10:12 -0400
committerDavid Zeuthen <davidz@redhat.com>2009-05-15 21:10:12 -0400
commit7dc2e9b3e4a4233e142801014abc51478b55ebd6 (patch)
treedb4de6d413d8e7292fe6b25ce5fa58ce54df305c
parentbff070ee2be359d5555fdc29b98d5e8a31c85042 (diff)
Add a tool to generate docbook
-rw-r--r--src/didl2docbook.c1223
1 files changed, 1223 insertions, 0 deletions
diff --git a/src/didl2docbook.c b/src/didl2docbook.c
new file mode 100644
index 0000000..827cb07
--- /dev/null
+++ b/src/didl2docbook.c
@@ -0,0 +1,1223 @@
+/* Copyright (C) 2009 David Zeuthen <zeuthen@gmail.com>
+ *
+ * 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 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: David Zeuthen <zeuthen@gmail.com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "dbusidl.h"
+
+static gchar **opt_input_files;
+static gchar *opt_output_dir;
+static gchar **opt_namespaces;
+static GOptionEntry entries[] =
+{
+ { "idl", 'i', 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_input_files, "IDL files (may be used several times)", NULL },
+ { "output", 'o', 0, G_OPTION_ARG_FILENAME, &opt_output_dir, "Directory for output", NULL },
+ { "namespaces", 'n', 0, G_OPTION_ARG_STRING_ARRAY, &opt_namespaces, "Namespaces to consider (may be used several times)", NULL },
+ { NULL }
+};
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+check_ignore_namespace (DINamespace *namespace,
+ gchar **namespaces_to_consider)
+{
+ guint n;
+ gboolean ret;
+
+ ret = FALSE;
+
+ for (n = 0; namespaces_to_consider[n] != NULL; n++)
+ {
+ if (g_strcmp0 (di_namespace_get_name (namespace), namespaces_to_consider[n]) == 0)
+ goto out;
+ }
+
+ ret = TRUE;
+
+ out:
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+print_type (DIType *type,
+ GString *s,
+ GString *sl)
+{
+ GList *inner_types;
+ GList *l;
+ const gchar *name;
+
+ name = di_type_get_name (type);
+
+ if (s != NULL)
+ g_string_append (s, name);
+ if (sl != NULL)
+ {
+ g_string_append_printf (sl, "<link linkend=\"didl-%s\">%s</link>",
+ name,
+ name);
+ }
+
+ inner_types = di_type_get_inner_types (type);
+ if (inner_types != NULL)
+ {
+ if (s != NULL)
+ g_string_append (s, "<");
+ if (sl != NULL)
+ g_string_append (sl, "&lt;");
+ for (l = inner_types; l != NULL; l = l->next)
+ {
+ DIType *inner_type = l->data;
+ print_type (inner_type, s, sl);
+ if (l->next != NULL)
+ {
+ if (s != NULL)
+ g_string_append (s, ",");
+ if (sl != NULL)
+ g_string_append (sl, ",");
+ }
+ }
+ if (s != NULL)
+ g_string_append (s, ">");
+ if (sl != NULL)
+ g_string_append (sl, "&gt;");
+ }
+}
+
+static guint
+get_type_len (DIType *type)
+{
+ GString *s;
+ guint len;
+
+ s = g_string_new (NULL);
+ print_type (type, s, NULL);
+ len = s->len;
+ g_string_free (s, TRUE);
+
+ return len;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static const gchar *
+get_doc (gpointer base, gboolean brief)
+{
+ const gchar *doc;
+
+ if (brief)
+ doc = di_base_get_doc_brief ((DIBase *) base);
+ else
+ doc = di_base_get_doc ((DIBase *) base);
+
+ if (doc == NULL)
+ {
+ if (brief)
+ doc = "FIXME: not documented";
+ else
+ doc = "FIXME: not documented.";
+ }
+
+ return doc;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+print_arg (DIArg *arg,
+ guint arg_align,
+ GString *s)
+{
+ DIType *type;
+ guint type_len;
+ const gchar *prefix;
+
+ switch (di_arg_get_direction (arg))
+ {
+ case DI_ARG_DIRECTION_NONE:
+ prefix = "";
+ break;
+ case DI_ARG_DIRECTION_IN:
+ prefix = "IN ";
+ break;
+ case DI_ARG_DIRECTION_OUT:
+ prefix = "OUT ";
+ break;
+ }
+
+ g_string_append (s, prefix);
+
+ type = di_arg_get_type (arg);
+
+ print_type (type, NULL, s);
+
+ type_len = get_type_len (type);
+
+ g_string_append_printf (s, "%*s%s",
+ arg_align - type_len, "",
+ di_arg_get_name (arg));
+}
+
+static void
+print_method_prototype (DIMethod *method,
+ guint align,
+ guint arg_align,
+ GString *s)
+{
+ guint len;
+ GList *l;
+ guint n;
+
+ len = strlen (di_method_get_name (method));
+ g_string_append_printf (s, "%s%*s(",
+ di_method_get_name (method),
+ align - len - 1, "");
+ for (l = di_method_get_args (method), n = 0; l != NULL; l = l->next, n++)
+ {
+ DIArg *arg = l->data;
+
+ print_arg (arg, arg_align, s);
+
+ if (l->next != NULL)
+ g_string_append_printf (s, ",\n%*s", align, "");
+ }
+ g_string_append (s, ");");
+
+}
+
+static void
+print_signal_prototype (DISignal *signal,
+ guint align,
+ guint arg_align,
+ GString *s)
+{
+ guint len;
+ GList *l;
+ guint n;
+
+ len = strlen (di_signal_get_name (signal));
+ g_string_append_printf (s, "%s%*s(",
+ di_signal_get_name (signal),
+ align - len - 1, "");
+ for (l = di_signal_get_args (signal), n = 0; l != NULL; l = l->next, n++)
+ {
+ DIArg *arg = l->data;
+
+ print_arg (arg, arg_align, s);
+
+ if (l->next != NULL)
+ g_string_append_printf (s, ",\n%*s", align, "");
+ }
+ g_string_append (s, ");");
+}
+
+static void
+print_property_prototype (DIProperty *property,
+ guint type_align,
+ GString *s)
+{
+ guint type_len;
+ const gchar *modifier;
+
+ switch (di_property_get_flags (property))
+ {
+ case DI_PROPERTY_FLAGS_READABLE:
+ modifier = "readonly ";
+ break;
+
+ case DI_PROPERTY_FLAGS_WRITABLE:
+ modifier = "writeonly ";
+ break;
+
+ case DI_PROPERTY_FLAGS_READWRITE:
+ modifier = "readwrite ";
+ break;
+
+ default:
+ case DI_PROPERTY_FLAGS_NONE:
+ g_assert_not_reached ();
+ break;
+ }
+
+ g_string_append_printf (s, "%s ", modifier);
+
+ type_len = get_type_len (di_property_get_type (property));
+
+ print_type (di_property_get_type (property), NULL, s);
+
+ g_string_append_printf (s, "%*s%s;",
+ type_align - type_len > 0 ? : 0, "",
+ di_property_get_name (property));
+}
+
+static guint
+get_arg_align_for_args (GList *args)
+{
+ GList *l;
+ guint arg_align;
+
+ arg_align = 0;
+ for (l = args; l != NULL; l = l->next)
+ {
+ DIArg *arg = l->data;
+ guint arg_len;
+
+ arg_len = get_type_len (di_arg_get_type (arg));
+ if (arg_len > arg_align)
+ arg_align = arg_len;
+ }
+
+ return arg_align;
+}
+
+static void
+print_param (const gchar *prefix,
+ const gchar *name,
+ const gchar *docstring,
+ GString *s)
+{
+ g_string_append_printf (s, " <varlistentry>\n");
+ g_string_append_printf (s, " <term><literal>%s</literal><parameter>%s</parameter>&#160;:</term>\n",
+ prefix,
+ name);
+ g_string_append_printf (s, " <listitem>\n");
+ g_string_append_printf (s, " <para>\n");
+ g_string_append_printf (s, "%s\n",
+ docstring);
+ g_string_append_printf (s, " </para>\n");
+ g_string_append_printf (s, " </listitem>\n");
+ g_string_append_printf (s, " </varlistentry>\n");
+}
+
+static void
+print_args (GList *args,
+ GString *s)
+{
+ GList *l;
+
+ if (args == NULL)
+ goto out;
+
+ g_string_append_printf (s, "<variablelist role=\"params\">\n");
+ for (l = args; l != NULL; l = l->next)
+ {
+ DIArg *arg = l->data;
+ const gchar *prefix;
+
+ switch (di_arg_get_direction (arg))
+ {
+ case DI_ARG_DIRECTION_NONE:
+ prefix = "";
+ break;
+ case DI_ARG_DIRECTION_IN:
+ prefix = "IN ";
+ break;
+ case DI_ARG_DIRECTION_OUT:
+ prefix = "OUT ";
+ break;
+ }
+
+ print_param (prefix, di_arg_get_name (arg),
+ get_doc (arg, FALSE),
+ s);
+
+ }
+ g_string_append_printf (s, "</variablelist>\n");
+
+ out:
+ ;
+}
+
+static void
+print_interface (DIInterface *iface,
+ GString *s)
+{
+ GList *l;
+
+ g_string_append_printf (s,
+ "<refentry id=\"didl-%s\">\n"
+ " <refmeta>\n"
+ " <refentrytitle role=\"top_of_page\">Interface %s</refentrytitle>\n"
+ " </refmeta>\n"
+ " <refnamediv>\n"
+ " <refname>Interface %s</refname>\n"
+ " <refpurpose>%s</refpurpose>\n"
+ " </refnamediv>\n",
+ di_interface_get_fully_qualified_name (iface),
+ di_interface_get_fully_qualified_name (iface),
+ di_interface_get_fully_qualified_name (iface),
+ get_doc (iface, TRUE));
+
+ /* Synopsis for methods */
+ if (di_interface_get_methods (iface) != NULL)
+ {
+ guint align;
+ guint arg_align;
+
+ g_string_append_printf (s, " <refsynopsisdiv role=\"synopsis\">\n");
+ g_string_append_printf (s, " <title role=\"synopsis.title\">Methods</title>\n");
+ g_string_append_printf (s, " <synopsis>\n");
+
+ align = 0;
+ arg_align = 0;
+ for (l = di_interface_get_methods (iface); l != NULL; l = l->next)
+ {
+ DIMethod *method = l->data;
+ guint len;
+ guint arg_align_for_method;
+
+ len = strlen (di_method_get_name (method));
+ if (len > align)
+ align = len;
+
+ arg_align_for_method = get_arg_align_for_args (di_method_get_args (method));
+ if (arg_align_for_method > arg_align)
+ arg_align = arg_align_for_method;
+ }
+
+ for (l = di_interface_get_methods (iface); l != NULL; l = l->next)
+ {
+ DIMethod *method = l->data;
+ print_method_prototype (method, align + 2, arg_align + 1, s);
+ if (l->next != NULL)
+ g_string_append_printf (s, "\n");
+ }
+
+ g_string_append_printf (s, " </synopsis>\n");
+ g_string_append_printf (s, " </refsynopsisdiv>\n");
+ }
+
+ /* Synopsis for signals */
+ if (di_interface_get_signals (iface) != NULL)
+ {
+ guint align;
+ guint arg_align;
+
+ g_string_append_printf (s, " <refsect1 role=\"synopsis\">\n");
+ g_string_append_printf (s, " <title role=\"synopsis.title\">Signals</title>\n");
+ g_string_append_printf (s, " <synopsis>\n");
+
+ align = 0;
+ arg_align = 0;
+ for (l = di_interface_get_signals (iface); l != NULL; l = l->next)
+ {
+ DISignal *signal = l->data;
+ guint len;
+ guint arg_align_for_signal;
+
+ len = strlen (di_signal_get_name (signal));
+ if (len > align)
+ align = len;
+
+ arg_align_for_signal = get_arg_align_for_args (di_signal_get_args (signal));
+ if (arg_align_for_signal > arg_align)
+ arg_align = arg_align_for_signal;
+ }
+
+ for (l = di_interface_get_signals (iface); l != NULL; l = l->next)
+ {
+ DISignal *signal = l->data;
+ print_signal_prototype (signal, align + 2, arg_align + 1, s);
+ if (l->next != NULL)
+ g_string_append_printf (s, "\n");
+ }
+
+ g_string_append_printf (s, " </synopsis>\n");
+ g_string_append_printf (s, " </refsect1>\n");
+ }
+
+ /* Synopsis for properties */
+ if (di_interface_get_properties (iface) != NULL)
+ {
+ guint type_align;
+
+ g_string_append_printf (s, " <refsect1 role=\"synopsis\">\n");
+ g_string_append_printf (s, " <title role=\"synopsis.title\">Properties</title>\n");
+ g_string_append_printf (s, " <synopsis>\n");
+
+ type_align = 0;
+ for (l = di_interface_get_properties (iface); l != NULL; l = l->next)
+ {
+ DIProperty *property = l->data;
+ guint type_len;
+
+ type_len = get_type_len (di_property_get_type (property));
+ if (type_len > type_align)
+ type_align = type_len;
+ }
+
+ for (l = di_interface_get_properties (iface); l != NULL; l = l->next)
+ {
+ DIProperty *property = l->data;
+ print_property_prototype (property, type_align + 1, s);
+ if (l->next != NULL)
+ g_string_append_printf (s, "\n");
+ }
+
+ g_string_append_printf (s, " </synopsis>\n");
+ g_string_append_printf (s, " </refsect1>\n");
+ }
+
+ /* Description */
+ g_string_append_printf (s, " <refsect1 role=\"desc\">\n");
+ g_string_append_printf (s, " <title role=\"desc.title\">Description</title>\n");
+ g_string_append_printf (s, " <para>\n");
+ g_string_append_printf (s, "%s\n",
+ get_doc (iface, FALSE));
+ g_string_append_printf (s, " </para>\n");
+ g_string_append_printf (s, " </refsect1>\n");
+
+ /* Descriptions of each method */
+ if (di_interface_get_methods (iface) != NULL)
+ {
+ g_string_append_printf (s, " <refsect1 role=\"details\">\n");
+ g_string_append_printf (s, " <title role=\"details.title\">Method Details</title>\n");
+
+ for (l = di_interface_get_methods (iface); l != NULL; l = l->next)
+ {
+ DIMethod *method = l->data;
+ guint arg_align_for_method;
+
+ g_string_append_printf (s, " <refsect2 role=\"function\" id=\"didl-%s\">\n"
+ " <title>%s ()</title>\n",
+ di_method_get_fully_qualified_name (method),
+ di_method_get_name (method));
+ g_string_append_printf (s, " <programlisting>\n");
+
+ arg_align_for_method = get_arg_align_for_args (di_method_get_args (method));
+
+ print_method_prototype (method,
+ strlen (di_method_get_name (method)) + 2,
+ arg_align_for_method + 1, s);
+
+ g_string_append_printf (s, " </programlisting>\n");
+
+ g_string_append_printf (s, " <para>\n");
+ g_string_append_printf (s, "%s\n",
+ get_doc (method, FALSE));
+ g_string_append_printf (s, " </para>\n");
+
+ print_args (di_method_get_args (method), s);
+
+ g_string_append_printf (s, " </refsect2>\n");
+ }
+ g_string_append_printf (s, " </refsect1>\n");
+ }
+
+ /* Descriptions of each signal */
+ if (di_interface_get_signals (iface) != NULL)
+ {
+ g_string_append_printf (s, " <refsect1 role=\"details\">\n");
+ g_string_append_printf (s, " <title role=\"details.title\">Signal Details</title>\n");
+
+ for (l = di_interface_get_signals (iface); l != NULL; l = l->next)
+ {
+ DISignal *signal = l->data;
+ guint arg_align_for_signal;
+
+ g_string_append_printf (s, " <refsect2 role=\"function\" id=\"didl-%s\">\n"
+ " <title>%s ()</title>\n",
+ di_signal_get_fully_qualified_name (signal),
+ di_signal_get_name (signal));
+ g_string_append_printf (s, " <programlisting>\n");
+
+ arg_align_for_signal = get_arg_align_for_args (di_signal_get_args (signal));
+
+ print_signal_prototype (signal,
+ strlen (di_signal_get_name (signal)) + 2,
+ arg_align_for_signal + 1, s);
+
+ g_string_append_printf (s, " </programlisting>\n");
+
+ g_string_append_printf (s, " <para>\n");
+ g_string_append_printf (s, "%s\n",
+ get_doc (signal, FALSE));
+ g_string_append_printf (s, " </para>\n");
+
+ print_args (di_signal_get_args (signal), s);
+
+ g_string_append_printf (s, " </refsect2>\n");
+ }
+ g_string_append_printf (s, " </refsect1>\n");
+ }
+
+ /* Descriptions of each property */
+ if (di_interface_get_properties (iface) != NULL)
+ {
+ g_string_append_printf (s, " <refsect1 role=\"details\">\n");
+ g_string_append_printf (s, " <title role=\"details.title\">Property Details</title>\n");
+
+ for (l = di_interface_get_properties (iface); l != NULL; l = l->next)
+ {
+ DIProperty *property = l->data;
+
+ g_string_append_printf (s, " <refsect2 role=\"function\" id=\"didl-%s\">\n"
+ " <title>%s ()</title>\n",
+ di_property_get_fully_qualified_name (property),
+ di_property_get_name (property));
+ g_string_append_printf (s, " <programlisting>\n");
+
+ print_property_prototype (property,
+ 1,
+ s);
+
+ g_string_append_printf (s, " </programlisting>\n");
+
+ g_string_append_printf (s, " <para>\n");
+ g_string_append_printf (s, "%s\n",
+ get_doc (property, FALSE));
+ g_string_append_printf (s, " </para>\n");
+
+ g_string_append_printf (s, " </refsect2>\n");
+ }
+ g_string_append_printf (s, " </refsect1>\n");
+ }
+
+ g_string_append_printf (s, "</refentry>\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+print_struct_members (GList *members,
+ const gchar *struct_type,
+ const gchar *struct_name,
+ const gchar *struct_docs,
+ GString *s)
+{
+ GList *l;
+ guint type_align;
+
+ g_string_append_printf (s, " <refsect1 role=\"details\">\n");
+ g_string_append_printf (s, " <title role=\"details.title\">Details</title>\n");
+
+ type_align = 0;
+ for (l = members; l != NULL; l = l->next)
+ {
+ DIStructMember *member = l->data;
+ guint type_len;
+
+ type_len = get_type_len (di_struct_member_get_type (member));
+ if (type_len > type_align)
+ type_align = type_len;
+ }
+
+ g_string_append_printf (s, " <programlisting>\n");
+
+ g_string_append_printf (s,
+ "%s %s\n"
+ "{\n",
+ struct_type,
+ struct_name);
+
+ for (l = members; l != NULL; l = l->next)
+ {
+ DIStructMember *member = l->data;
+ guint type_len;
+
+ type_len = get_type_len (di_struct_member_get_type (member));
+
+ g_string_append_printf (s, " ");
+
+ print_type (di_struct_member_get_type (member), NULL, s);
+
+ g_string_append_printf (s, "%*s %s;\n",
+ type_align - type_len, "",
+ di_struct_member_get_name (member));
+ }
+
+ g_string_append_printf (s, "};");
+ g_string_append_printf (s, " </programlisting>\n");
+
+ g_string_append_printf (s, " <para>\n");
+ g_string_append_printf (s, "%s\n",
+ struct_docs);
+ g_string_append_printf (s, " </para>\n");
+
+ g_string_append_printf (s, "<variablelist>\n");
+ for (l = members; l != NULL; l = l->next)
+ {
+ DIStructMember *member = l->data;
+
+ print_param ("", di_struct_member_get_name (member),
+ get_doc (member, FALSE),
+ s);
+ }
+ g_string_append_printf (s, "</variablelist>\n");
+
+ g_string_append_printf (s, " </refsect1>\n");
+
+ g_string_append_printf (s, "</refentry>\n");
+
+}
+
+static void
+print_struct (DIStruct *struct_,
+ GString *s)
+{
+ g_string_append_printf (s,
+ "<refentry id=\"didl-%s\">\n"
+ " <refmeta>\n"
+ " <refentrytitle role=\"top_of_page\">Struct %s</refentrytitle>\n"
+ " </refmeta>\n"
+ " <refnamediv>\n"
+ " <refname>Struct %s</refname>\n"
+ " <refpurpose>%s</refpurpose>\n"
+ " </refnamediv>\n",
+ di_struct_get_fully_qualified_name (struct_),
+ di_struct_get_fully_qualified_name (struct_),
+ di_struct_get_fully_qualified_name (struct_),
+ get_doc (struct_, TRUE));
+
+ print_struct_members (di_struct_get_members (struct_),
+ "struct",
+ di_struct_get_fully_qualified_name (struct_),
+ get_doc (struct_, FALSE),
+ s);
+}
+
+static void
+print_dynamic_struct (DIDynamicStruct *dynamic_struct,
+ GString *s)
+{
+ g_string_append_printf (s,
+ "<refentry id=\"didl-%s\">\n"
+ " <refmeta>\n"
+ " <refentrytitle role=\"top_of_page\">Dynamic Struct %s</refentrytitle>\n"
+ " </refmeta>\n"
+ " <refnamediv>\n"
+ " <refname>Dynamic Struct %s</refname>\n"
+ " <refpurpose>%s</refpurpose>\n"
+ " </refnamediv>\n",
+ di_dynamic_struct_get_fully_qualified_name (dynamic_struct),
+ di_dynamic_struct_get_fully_qualified_name (dynamic_struct),
+ di_dynamic_struct_get_fully_qualified_name (dynamic_struct),
+ get_doc (dynamic_struct, TRUE));
+
+ print_struct_members (di_dynamic_struct_get_members (dynamic_struct),
+ "dynamic_struct",
+ di_dynamic_struct_get_fully_qualified_name (dynamic_struct),
+ get_doc (dynamic_struct, FALSE),
+ s);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+print_enum (DIEnum *enum_,
+ GString *s)
+{
+ g_string_append_printf (s,
+ "<refentry id=\"didl-%s\">\n"
+ " <refmeta>\n"
+ " <refentrytitle role=\"top_of_page\">Enum %s</refentrytitle>\n"
+ " </refmeta>\n"
+ " <refnamediv>\n"
+ " <refname>Enum %s</refname>\n"
+ " <refpurpose>%s</refpurpose>\n"
+ " </refnamediv>\n",
+ di_enum_get_fully_qualified_name (enum_),
+ di_enum_get_fully_qualified_name (enum_),
+ di_enum_get_fully_qualified_name (enum_),
+ get_doc (enum_, TRUE));
+
+
+ GList *l;
+ guint name_align;
+
+ g_string_append_printf (s, " <refsect1 role=\"details\">\n");
+ g_string_append_printf (s, " <title role=\"details.title\">Details</title>\n");
+
+ name_align = 0;
+ for (l = di_enum_get_members (enum_); l != NULL; l = l->next)
+ {
+ DIEnumMember *member = l->data;
+ guint name_len;
+
+ name_len = strlen (di_enum_member_get_name (member));
+ if (name_len > name_align)
+ name_align = name_len;
+ }
+
+ g_string_append_printf (s, " <programlisting>\n");
+
+ g_string_append_printf (s,
+ "enum %s\n"
+ "{\n",
+ di_enum_get_fully_qualified_name (enum_));
+
+ for (l = di_enum_get_members (enum_); l != NULL; l = l->next)
+ {
+ DIEnumMember *member = l->data;
+ guint name_len;
+
+ name_len = strlen (di_enum_member_get_name (member));
+
+ g_string_append_printf (s, " ");
+
+ g_string_append_printf (s, "%s%*s = %d",
+ di_enum_member_get_name (member),
+ name_align - name_len, "",
+ di_enum_member_get_value (member));
+
+ if (l->next != NULL)
+ g_string_append_printf (s, ",");
+ g_string_append_printf (s, "\n");
+ }
+
+ g_string_append_printf (s, "};");
+ g_string_append_printf (s, " </programlisting>\n");
+
+ g_string_append_printf (s, " <para>\n");
+ g_string_append_printf (s, "%s\n",
+ get_doc (enum_, FALSE));
+ g_string_append_printf (s, " </para>\n");
+
+ g_string_append_printf (s, "<variablelist>\n");
+ for (l = di_enum_get_members (enum_); l != NULL; l = l->next)
+ {
+ DIEnumMember *member = l->data;
+
+ print_param ("", di_enum_member_get_name (member),
+ get_doc (member, FALSE),
+ s);
+ }
+ g_string_append_printf (s, "</variablelist>\n");
+
+ g_string_append_printf (s, " </refsect1>\n");
+
+ g_string_append_printf (s, "</refentry>\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+print_error_domain (DIErrorDomain *error_domain,
+ GString *s)
+{
+ g_string_append_printf (s,
+ "<refentry id=\"didl-%s\">\n"
+ " <refmeta>\n"
+ " <refentrytitle role=\"top_of_page\">Error Domain %s</refentrytitle>\n"
+ " </refmeta>\n"
+ " <refnamediv>\n"
+ " <refname>Error Domain %s</refname>\n"
+ " <refpurpose>%s</refpurpose>\n"
+ " </refnamediv>\n",
+ di_error_domain_get_fully_qualified_name (error_domain),
+ di_error_domain_get_fully_qualified_name (error_domain),
+ di_error_domain_get_fully_qualified_name (error_domain),
+ get_doc (error_domain, TRUE));
+
+
+ GList *l;
+
+ g_string_append_printf (s, " <refsect1 role=\"details\">\n");
+ g_string_append_printf (s, " <title role=\"details.title\">Details</title>\n");
+
+ g_string_append_printf (s, " <programlisting>\n");
+
+ g_string_append_printf (s,
+ "error_domain %s\n"
+ "{\n",
+ di_error_domain_get_fully_qualified_name (error_domain));
+
+ for (l = di_error_domain_get_members (error_domain); l != NULL; l = l->next)
+ {
+ DIErrorMember *member = l->data;
+ g_string_append_printf (s, " %s",
+ di_error_member_get_name (member));
+ if (l->next != NULL)
+ g_string_append_printf (s, ",");
+ g_string_append_printf (s, "\n");
+ }
+
+ g_string_append_printf (s, "};");
+ g_string_append_printf (s, " </programlisting>\n");
+
+ g_string_append_printf (s, " <para>\n");
+ g_string_append_printf (s, "%s\n",
+ get_doc (error_domain, FALSE));
+ g_string_append_printf (s, " </para>\n");
+
+ g_string_append_printf (s, "<variablelist>\n");
+ for (l = di_error_domain_get_members (error_domain); l != NULL; l = l->next)
+ {
+ DIErrorMember *member = l->data;
+
+ print_param ("", di_error_member_get_name (member),
+ get_doc (member, FALSE),
+ s);
+ }
+ g_string_append_printf (s, "</variablelist>\n");
+
+ g_string_append_printf (s, " </refsect1>\n");
+
+ g_string_append_printf (s, "</refentry>\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+write_file (const gchar *filename,
+ GString *s,
+ GError **error)
+{
+ gboolean ret;
+ gchar *path;
+
+ ret = FALSE;
+ path = NULL;
+
+ if (opt_output_dir == NULL)
+ path = g_strdup (filename);
+ else
+ path = g_build_filename (opt_output_dir, filename, NULL);
+
+ if (!g_file_set_contents (path,
+ s->str,
+ s->len,
+ error))
+ goto out;
+
+ ret = TRUE;
+
+ out:
+ g_free (path);
+ return ret;
+}
+
+static gboolean
+print_namespace (DINamespace *namespace,
+ GError **error)
+{
+ GList *l;
+ gboolean ret;
+ gchar *filename;
+ GString *sn;
+
+ ret = FALSE;
+
+
+ sn = g_string_new (NULL);
+ g_string_append (sn,
+ "<?xml version=\"1.0\"?>\n"
+ "<!DOCTYPE book PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2 //EN\"\n"
+ "\"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">\n");
+
+ g_string_append_printf (sn,
+ "<book id=\"didl-%s\" xmlns:xi=\"http://www.w3.org/2003/XInclude\">\n",
+ di_namespace_get_name (namespace));
+
+ g_string_append_printf (sn,
+ " <reference>\n"
+ " <title>Foo</title>\n");
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /* Print all interfaces in separate files */
+ g_string_append_printf (sn,
+ " <chapter id=\"bar\">\n"
+ " <title>D-Bus interfaces</title>\n");
+ for (l = di_namespace_get_interfaces (namespace); l != NULL; l = l->next)
+ {
+ DIInterface *iface = l->data;
+ GString *s;
+
+ s = g_string_new (NULL);
+ g_string_append (s, "<?xml version=\"1.0\"?>\n"
+ "<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2 //EN\"\n"
+ "\"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">\n");
+
+ print_interface (iface, s);
+
+ filename = g_strdup_printf ("didl-%s.xml",
+ di_interface_get_fully_qualified_name (iface));
+ if (!write_file (filename, s, error))
+ {
+ g_free (filename);
+ g_string_free (s, TRUE);
+ goto out;
+ }
+ g_string_free (s, TRUE);
+
+ g_string_append_printf (sn,
+ " <xi:include href=\"%s\"/>\n",
+ filename);
+
+ g_free (filename);
+ }
+ g_string_append_printf (sn,
+ " </chapter>\n");
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /* Print all structs in separate files */
+ g_string_append_printf (sn,
+ " <chapter>\n"
+ " <title>Structs</title>\n");
+ for (l = di_namespace_get_structs (namespace); l != NULL; l = l->next)
+ {
+ DIStruct *struct_ = l->data;
+ GString *s;
+
+ s = g_string_new (NULL);
+ g_string_append (s, "<?xml version=\"1.0\"?>\n"
+ "<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2 //EN\"\n"
+ "\"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">\n");
+
+ print_struct (struct_, s);
+
+ filename = g_strdup_printf ("didl-%s.xml",
+ di_struct_get_fully_qualified_name (struct_));
+ if (!write_file (filename, s, error))
+ {
+ g_free (filename);
+ g_string_free (s, TRUE);
+ goto out;
+ }
+ g_string_free (s, TRUE);
+
+ g_string_append_printf (sn,
+ " <xi:include href=\"%s\"/>\n",
+ filename);
+
+ g_free (filename);
+ }
+ g_string_append_printf (sn,
+ " </chapter>\n");
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /* Print all dynamic structs in separate files */
+ g_string_append_printf (sn,
+ " <chapter>\n"
+ " <title>Dynamic Structs</title>\n");
+ for (l = di_namespace_get_dynamic_structs (namespace); l != NULL; l = l->next)
+ {
+ DIDynamicStruct *dynamic_struct = l->data;
+ GString *s;
+
+ s = g_string_new (NULL);
+ g_string_append (s, "<?xml version=\"1.0\"?>\n"
+ "<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2 //EN\"\n"
+ "\"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">\n");
+
+ print_dynamic_struct (dynamic_struct, s);
+
+ filename = g_strdup_printf ("didl-%s.xml",
+ di_dynamic_struct_get_fully_qualified_name (dynamic_struct));
+ if (!write_file (filename, s, error))
+ {
+ g_free (filename);
+ g_string_free (s, TRUE);
+ goto out;
+ }
+ g_string_free (s, TRUE);
+
+ g_string_append_printf (sn,
+ " <xi:include href=\"%s\"/>\n",
+ filename);
+
+ g_free (filename);
+ }
+ g_string_append_printf (sn,
+ " </chapter>\n");
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /* Print all enums in separate files */
+ g_string_append_printf (sn,
+ " <chapter>\n"
+ " <title>Enumerations</title>\n");
+ for (l = di_namespace_get_enums (namespace); l != NULL; l = l->next)
+ {
+ DIEnum *enum_ = l->data;
+ GString *s;
+
+ s = g_string_new (NULL);
+ g_string_append (s, "<?xml version=\"1.0\"?>\n"
+ "<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2 //EN\"\n"
+ "\"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">\n");
+
+ print_enum (enum_, s);
+
+ filename = g_strdup_printf ("didl-%s.xml",
+ di_enum_get_fully_qualified_name (enum_));
+ if (!write_file (filename, s, error))
+ {
+ g_free (filename);
+ g_string_free (s, TRUE);
+ goto out;
+ }
+ g_string_free (s, TRUE);
+
+ g_string_append_printf (sn,
+ " <xi:include href=\"%s\"/>\n",
+ filename);
+
+ g_free (filename);
+ }
+ g_string_append_printf (sn,
+ " </chapter>\n");
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /* Print all error domains in separate files */
+ g_string_append_printf (sn,
+ " <chapter>\n"
+ " <title>Error domains</title>\n");
+ for (l = di_namespace_get_error_domains (namespace); l != NULL; l = l->next)
+ {
+ DIErrorDomain *error_domain = l->data;
+ GString *s;
+
+ s = g_string_new (NULL);
+ g_string_append (s, "<?xml version=\"1.0\"?>\n"
+ "<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2 //EN\"\n"
+ "\"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">\n");
+
+ print_error_domain (error_domain, s);
+
+ filename = g_strdup_printf ("didl-%s.xml",
+ di_error_domain_get_fully_qualified_name (error_domain));
+ if (!write_file (filename, s, error))
+ {
+ g_free (filename);
+ g_string_free (s, TRUE);
+ goto out;
+ }
+ g_string_free (s, TRUE);
+
+ g_string_append_printf (sn,
+ " <xi:include href=\"%s\"/>\n",
+ filename);
+
+ g_free (filename);
+ }
+ g_string_append_printf (sn,
+ " </chapter>\n");
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ g_string_append_printf (sn,
+ " </reference>\n");
+ g_string_append_printf (sn, "</book>\n");
+
+ filename = g_strdup_printf ("didl-%s.xml",
+ di_namespace_get_name (namespace));
+ if (!write_file (filename, sn, error))
+ {
+ g_free (filename);
+ goto out;
+ }
+ g_free (filename);
+
+
+ ret = TRUE;
+
+ out:
+ if (sn != NULL)
+ g_string_free (sn, TRUE);
+
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+int
+main (int argc, char *argv[])
+{
+ DIParser *parser;
+ GList *l;
+ gint ret;
+ gchar *s;
+ GError *error;
+ GOptionContext *context;
+
+ opt_input_files = NULL;
+ opt_output_dir = NULL;
+ opt_namespaces = NULL;
+
+ ret = 1;
+
+ error = NULL;
+ context = g_option_context_new ("- D-Bus IDL to Docbook compiler");
+ g_option_context_add_main_entries (context, entries, NULL);
+ if (!g_option_context_parse (context, &argc, &argv, &error))
+ {
+ g_printerr ("option parsing failed: %s\n", error->message);
+ goto out;
+ }
+
+ if (opt_input_files == NULL)
+ {
+ s = g_option_context_get_help (context, FALSE, NULL);
+ g_print ("%s\n", s);
+ g_free (s);
+ goto out;
+ }
+
+ parser = di_parser_new (opt_input_files[0]);
+ for (l = di_parser_get_errors (parser); l != NULL; l = l->next)
+ {
+ g_printerr ("%s\n", (const gchar *) l->data);
+ }
+ for (l = di_parser_get_warnings (parser); l != NULL; l = l->next)
+ {
+ g_printerr ("%s\n", (const gchar *) l->data);
+ }
+ if (di_parser_get_errors (parser) != NULL)
+ goto out;
+
+ for (l = di_parser_get_namespaces (parser); l != NULL; l = l->next)
+ {
+ DINamespace *namespace = l->data;
+
+ if (opt_namespaces != NULL)
+ if (check_ignore_namespace (namespace, opt_namespaces))
+ continue;
+
+ error = NULL;
+ if (!print_namespace (namespace, &error))
+ {
+ g_printerr ("Error writing file: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+ }
+
+ ret = 0;
+
+ out:
+ if (parser != NULL)
+ di_parser_free (parser);
+ if (context != NULL)
+ g_option_context_free (context);
+ g_strfreev (opt_input_files);
+ g_free (opt_output_dir);
+ g_strfreev (opt_namespaces);
+ return ret;;
+}