diff options
author | David Zeuthen <davidz@redhat.com> | 2009-05-15 21:10:12 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2009-05-15 21:10:12 -0400 |
commit | 7dc2e9b3e4a4233e142801014abc51478b55ebd6 (patch) | |
tree | db4de6d413d8e7292fe6b25ce5fa58ce54df305c | |
parent | bff070ee2be359d5555fdc29b98d5e8a31c85042 (diff) |
Add a tool to generate docbook
-rw-r--r-- | src/didl2docbook.c | 1223 |
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, "<"); + 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, ">"); + } +} + +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> :</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;; +} |