diff options
author | David Zeuthen <davidz@redhat.com> | 2009-02-03 12:15:55 -0500 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2009-02-03 12:15:55 -0500 |
commit | fc47c0c30a33ff8bb0e0074994b2eafdfa36c84c (patch) | |
tree | cc2944b79a468f6d95bea97c22eb81b26fc875a8 | |
parent | 7006f3f8350d319c3950509086b15ced581bd17e (diff) |
move docbook generator into separate source files
-rw-r--r-- | src/eggdbus/Makefile.am | 1 | ||||
-rw-r--r-- | src/eggdbus/docbook.c | 801 | ||||
-rw-r--r-- | src/eggdbus/docbook.h | 34 | ||||
-rw-r--r-- | src/eggdbus/eggdbusbindingtool.c | 1 | ||||
-rw-r--r-- | src/eggdbus/interface.c | 770 | ||||
-rw-r--r-- | src/eggdbus/interface.h | 3 |
6 files changed, 837 insertions, 773 deletions
diff --git a/src/eggdbus/Makefile.am b/src/eggdbus/Makefile.am index e744b49..b0c7f2e 100644 --- a/src/eggdbus/Makefile.am +++ b/src/eggdbus/Makefile.am @@ -77,6 +77,7 @@ eggdbus_binding_tool_SOURCES = \ interface.c interface.h \ struct.c struct.h \ enum.c enum.h \ + docbook.c docbook.h \ $(NULL) eggdbus_binding_tool_CFLAGS = \ diff --git a/src/eggdbus/docbook.c b/src/eggdbus/docbook.c new file mode 100644 index 0000000..888834d --- /dev/null +++ b/src/eggdbus/docbook.c @@ -0,0 +1,801 @@ +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * 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 <davidz@redhat.com> + */ + +#include "config.h" + +#include <glib.h> +#include <string.h> +#include <dbus/dbus.h> +#include <eggdbus/eggdbuserror.h> +#include <eggdbus/eggdbusutils.h> +#include <eggdbus/eggdbusinterface.h> + +#include "eggdbusbindingtool.h" +#include "docbook.h" + +static void +get_type_name_for_sig_iter (DBusSignatureIter *sig_iter, + gchar **out_raw, + gchar **out_name) +{ + GString *ret_raw; + GString *ret; + gchar *s; + gchar *s_raw; + gchar *s1; + gchar *s1_raw; + guint n; + DBusSignatureIter sub_sig_iter; + int cur_type; + + ret_raw = NULL; + ret = g_string_new (NULL); + + cur_type = dbus_signature_iter_get_current_type (sig_iter); + + switch (cur_type) + { + case DBUS_TYPE_BYTE: + g_string_append (ret, "Byte"); + break; + + case DBUS_TYPE_BOOLEAN: + g_string_append (ret, "Boolean"); + break; + + case DBUS_TYPE_INT16: + g_string_append (ret, "Int16"); + break; + + case DBUS_TYPE_UINT16: + g_string_append (ret, "UInt16"); + break; + + case DBUS_TYPE_INT32: + g_string_append (ret, "Int32"); + break; + + case DBUS_TYPE_UINT32: + g_string_append (ret, "UInt32"); + break; + + case DBUS_TYPE_INT64: + g_string_append (ret, "Int64"); + break; + + case DBUS_TYPE_UINT64: + g_string_append (ret, "UInt64"); + break; + + case DBUS_TYPE_DOUBLE: + g_string_append (ret, "Double"); + break; + + case DBUS_TYPE_STRING: + g_string_append (ret, "String"); + break; + + case DBUS_TYPE_OBJECT_PATH: + g_string_append (ret, "ObjectPath"); + break; + + case DBUS_TYPE_SIGNATURE: + g_string_append (ret, "Signature"); + break; + + case DBUS_TYPE_VARIANT: + g_string_append (ret, "Variant"); + break; + + case DBUS_TYPE_DICT_ENTRY: + ret_raw = g_string_new (NULL); + + dbus_signature_iter_recurse (sig_iter, &sub_sig_iter); + get_type_name_for_sig_iter (&sub_sig_iter, &s_raw, &s); + g_assert (dbus_signature_iter_next (&sub_sig_iter) == TRUE); + get_type_name_for_sig_iter (&sub_sig_iter, &s1_raw, &s1); + g_assert (dbus_signature_iter_next (&sub_sig_iter) == FALSE); + g_string_append_printf (ret_raw, "Dict<%s_%s>", s_raw, s1_raw); + g_string_append_printf (ret, "Dict<%s→%s>", s, s1); /* U+2192 RIGHTWARDS ARROW */ + g_free (s_raw); + g_free (s); + g_free (s1_raw); + g_free (s1); + break; + + case DBUS_TYPE_STRUCT: + ret_raw = g_string_new (NULL); + + g_string_append (ret_raw, "["); + g_string_append (ret, "["); + dbus_signature_iter_recurse (sig_iter, &sub_sig_iter); + n = 0; + do + { + get_type_name_for_sig_iter (&sub_sig_iter, &s_raw, &s); + if (n != 0) + { + g_string_append (ret_raw, ","); + g_string_append (ret, ","); + } + g_string_append_printf (ret_raw, "%s", s_raw); + g_string_append_printf (ret, "%s", s); + g_free (s_raw); + g_free (s); + n++; + } + while (dbus_signature_iter_next (&sub_sig_iter)); + g_string_append (ret_raw, "]"); + g_string_append (ret, "]"); + break; + + case DBUS_TYPE_ARRAY: + ret_raw = g_string_new (NULL); + + dbus_signature_iter_recurse (sig_iter, &sub_sig_iter); + get_type_name_for_sig_iter (&sub_sig_iter, &s_raw, &s); + if (g_str_has_prefix (s, "Dict<")) + { + g_string_append (ret_raw, s_raw); + g_string_append (ret, s); + } + else + { + g_string_append_printf (ret_raw, "Array<%s>", s_raw); + g_string_append_printf (ret, "Array<%s>", s); + } + g_free (s); + break; + + default: + g_warning ("Unable to handle %s", dbus_signature_iter_get_signature (sig_iter)); + g_assert_not_reached (); + break; + } + + s = g_string_free (ret, FALSE); + + if (ret_raw != NULL) + s_raw = g_string_free (ret_raw, FALSE); + else + s_raw = g_strdup (s); + + if (out_raw != NULL) + { + *out_raw = s_raw; + s_raw = NULL; + } + + if (out_name != NULL) + { + *out_name = s; + s = NULL; + } + + g_free (s); + g_free (s_raw); +} + +static void +docbook_get_typename_for_signature (const gchar *signature, + gchar **out_name, + gchar **out_link) +{ + DBusSignatureIter iter; + gchar *name; + gchar *name_link; + + name = NULL; + name_link = NULL; + + dbus_signature_iter_init (&iter, signature); + get_type_name_for_sig_iter (&iter, &name, &name_link); + + if (out_name != NULL) + { + *out_name = name; + name = NULL; + } + + if (out_link != NULL) + { + *out_link = name_link; + name_link = NULL; + } + + g_free (name); + g_free (name_link); +} + +static void +docbook_print_arg (const EggDBusInterfaceArgInfo *arg, + const gchar *arg_prefix, + guint arg_max_len) +{ + gchar *arg_type_name; + gchar *arg_type_link; + + docbook_get_typename_for_signature (arg->signature, &arg_type_name, &arg_type_link); + + g_print ("%s%s%*s%s", + arg_prefix, + arg_type_link, + (int) (arg_max_len - strlen (arg_type_name)), "", + arg->name); + + g_free (arg_type_name); + g_free (arg_type_link); +} + +static guint +docbook_get_max_arg_len_for_method (const EggDBusInterfaceMethodInfo *method) +{ + guint n; + guint max_arg_len; + + max_arg_len = 0; + + for (n = 0; n < method->in_num_args; n++) + { + const EggDBusInterfaceArgInfo *arg = method->in_args + n; + gchar *arg_type_name; + guint arg_len; + + docbook_get_typename_for_signature (arg->signature, &arg_type_name, NULL); + arg_len = strlen (arg_type_name); + g_free (arg_type_name); + + if (arg_len > max_arg_len) + max_arg_len = arg_len; + } + + for (n = 0; n < method->out_num_args; n++) + { + const EggDBusInterfaceArgInfo *arg = method->out_args + n; + gchar *arg_type_name; + guint arg_len; + + docbook_get_typename_for_signature (arg->signature, &arg_type_name, NULL); + arg_len = strlen (arg_type_name); + g_free (arg_type_name); + + if (arg_len > max_arg_len) + max_arg_len = arg_len; + } + + return max_arg_len; +} + +static guint +docbook_get_max_arg_len_for_signal (const EggDBusInterfaceSignalInfo *signal) +{ + guint n; + guint max_arg_len; + + max_arg_len = 0; + + for (n = 0; n < signal->num_args; n++) + { + const EggDBusInterfaceArgInfo *arg = signal->args + n; + gchar *arg_type_name; + guint arg_len; + + docbook_get_typename_for_signature (arg->signature, &arg_type_name, NULL); + arg_len = strlen (arg_type_name); + g_free (arg_type_name); + + if (arg_len > max_arg_len) + max_arg_len = arg_len; + } + + return max_arg_len; +} + +static void +docbook_print_method_prototype (const EggDBusInterfaceInfo *interface, + const EggDBusInterfaceMethodInfo *method, + guint indent, + guint arg_max_len, + gboolean use_hyperlink) +{ + guint n; + guint num_printed; + guint first_indent; + + first_indent = indent - strlen (method->name) - 1; + + if (use_hyperlink) + { + g_print ("<link linkend=\"%s.%s\">%s</link>%*s(", + interface->name, + method->name, + method->name, + first_indent, ""); + } + else + { + g_print ("%s%*s(", + method->name, + first_indent, ""); + } + + num_printed = 0; + for (n = 0; n < method->in_num_args; n++) + { + const EggDBusInterfaceArgInfo *arg = method->in_args + n; + + if (num_printed != 0) + g_print (",\n%*s", indent, ""); + + docbook_print_arg (arg, "IN ", arg_max_len); + + num_printed++; + } + + for (n = 0; n < method->out_num_args; n++) + { + const EggDBusInterfaceArgInfo *arg = method->out_args + n; + + if (num_printed != 0) + g_print (",\n%*s", indent, ""); + + docbook_print_arg (arg, "OUT ", arg_max_len); + + num_printed++; + } + + g_print (")\n"); +} + +static void +docbook_print_signal_prototype (const EggDBusInterfaceInfo *interface, + const EggDBusInterfaceSignalInfo *signal, + guint indent, + guint arg_max_len, + gboolean use_hyperlink) +{ + guint n; + guint num_printed; + guint first_indent; + + first_indent = indent - strlen (signal->name) - 1; + + if (use_hyperlink) + { + g_print ("<link linkend=\"%s::%s\">%s</link>%*s(", + interface->name, + signal->name, + signal->name, + first_indent, ""); + } + else + { + g_print ("%s%*s(", + signal->name, + first_indent, ""); + } + + num_printed = 0; + for (n = 0; n < signal->num_args; n++) + { + const EggDBusInterfaceArgInfo *arg = signal->args + n; + + if (num_printed != 0) + g_print (",\n%*s", indent, ""); + + docbook_print_arg (arg, "", arg_max_len); + + num_printed++; + } + + g_print (")\n"); +} + +static void +docbook_print_property_prototype (const EggDBusInterfaceInfo *interface, + const EggDBusInterfacePropertyInfo *property, + guint indent, + gboolean use_hyperlink) +{ + guint first_indent; + gchar *arg_type_link; + + first_indent = indent - strlen (property->name) - 1; + + if (use_hyperlink) + { + g_print ("<link linkend=\"%s:%s\">%s</link>%*s ", + interface->name, + property->name, + property->name, + first_indent, ""); + } + else + { + g_print ("%s%*s ", + property->name, + first_indent, ""); + } + + if ((property->flags & EGG_DBUS_INTERFACE_PROPERTY_INFO_FLAGS_READABLE) && + (property->flags & EGG_DBUS_INTERFACE_PROPERTY_INFO_FLAGS_WRITABLE)) + { + g_print ("readwrite "); + } + else if (property->flags & EGG_DBUS_INTERFACE_PROPERTY_INFO_FLAGS_READABLE) + { + g_print ("readable "); + } + else if (property->flags & EGG_DBUS_INTERFACE_PROPERTY_INFO_FLAGS_WRITABLE) + { + g_print ("writable "); + } + else + { + g_print (" "); + } + + docbook_get_typename_for_signature (property->signature, NULL, &arg_type_link); + + g_print (" %s\n", arg_type_link); + + g_free (arg_type_link); +} + +static void +docbook_print_arg_in_list (const gchar *prefix, + const EggDBusInterfaceArgInfo *arg) +{ + gchar *arg_doc_string; + gchar *arg_type_link; + + arg_doc_string = get_doc_string (arg->annotations, "Argument"); + + docbook_get_typename_for_signature (arg->signature, NULL, &arg_type_link); + + g_print (" <varlistentry>\n"); + g_print (" <term><literal>%s%s <parameter>%s</parameter></literal>:</term>\n", + prefix, + arg_type_link, + arg->name); + g_print (" <listitem>\n"); + g_print (" <para>\n"); + g_print ("%s\n", arg_doc_string); + g_print (" </para>\n"); + g_print (" </listitem>\n"); + g_print (" </varlistentry>\n"); + + g_free (arg_doc_string); + + g_free (arg_type_link); +} + +static void +docbook_print_args (const EggDBusInterfaceInfo *interface, + const gchar *prefix0, + const EggDBusInterfaceArgInfo *args0, + guint num_args0, + const gchar *prefix1, + const EggDBusInterfaceArgInfo *args1, + guint num_args1) +{ + guint n; + + g_print ("<variablelist role=\"params\">\n"); + + for (n = 0; n < num_args0; n++) + { + const EggDBusInterfaceArgInfo *arg = args0 + n; + docbook_print_arg_in_list (prefix0, arg); + } + + for (n = 0; n < num_args1; n++) + { + const EggDBusInterfaceArgInfo *arg = args1 + n; + docbook_print_arg_in_list (prefix1, arg); + } + + g_print ("</variablelist>\n"); +} + +gboolean +interface_generate_docbook (const EggDBusInterfaceInfo *interface, + GError **error) +{ + gboolean ret; + gchar *interface_summary_doc_string; + gchar *interface_doc_string; + guint n; + guint indent; + guint arg_max_len_for_all; + + ret = FALSE; + + interface_summary_doc_string = get_summary_doc_string (interface->annotations, "Interface"); + interface_doc_string = get_doc_string (interface->annotations, "Interface"); + + g_print ("<?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"); + + g_print ("<refentry id=\"%s\">\n", interface->name); + g_print (" <refmeta>\n"); + g_print (" <refentrytitle role=\"top_of_page\">%s</refentrytitle>\n", interface->name); + g_print (" </refmeta>\n"); + g_print (" <refnamediv>\n"); + g_print (" <refname>%s</refname>\n", interface->name); + g_print (" <refpurpose>%s</refpurpose>\n", interface_summary_doc_string); + g_print (" </refnamediv>\n"); + + /* Synopsis for methods */ + if (interface->num_methods > 0) + { + g_print (" <refsynopsisdiv role=\"synopsis\">\n"); + g_print (" <title role=\"synopsis.title\">Methods</title>\n"); + g_print (" <synopsis>\n"); + indent = 0; + arg_max_len_for_all = 0; + for (n = 0; n < interface->num_methods; n++) + { + const EggDBusInterfaceMethodInfo *method = interface->methods + n; + guint method_name_len; + guint arg_max_len; + + method_name_len = strlen (method->name); + if (method_name_len > indent) + indent = method_name_len; + + arg_max_len = docbook_get_max_arg_len_for_method (method); + if (arg_max_len > arg_max_len_for_all) + arg_max_len_for_all = arg_max_len; + } + for (n = 0; n < interface->num_methods; n++) + { + const EggDBusInterfaceMethodInfo *method = interface->methods + n; + + docbook_print_method_prototype (interface, + method, + indent + 2, + arg_max_len_for_all + 2, + TRUE); + } + g_print (" </synopsis>\n"); + g_print (" </refsynopsisdiv>\n"); + } + + /* Synopsis for signals */ + if (interface->num_signals > 0) + { + g_print (" <refsect1 role=\"signal_proto\">\n"); + g_print (" <title role=\"signal_proto.title\">Signals</title>\n"); + g_print (" <synopsis>\n"); + indent = 0; + arg_max_len_for_all = 0; + for (n = 0; n < interface->num_signals; n++) + { + const EggDBusInterfaceSignalInfo *signal = interface->signals + n; + guint signal_name_len; + guint arg_max_len; + + signal_name_len = strlen (signal->name); + if (signal_name_len > indent) + indent = signal_name_len; + + arg_max_len = docbook_get_max_arg_len_for_signal (signal); + if (arg_max_len > arg_max_len_for_all) + arg_max_len_for_all = arg_max_len; + } + for (n = 0; n < interface->num_signals; n++) + { + const EggDBusInterfaceSignalInfo *signal = interface->signals + n; + + docbook_print_signal_prototype (interface, + signal, + indent + 2, + arg_max_len_for_all + 2, + TRUE); + } + g_print (" </synopsis>\n"); + g_print (" </refsect1>\n"); + } + + /* Synopsis for properties */ + if (interface->num_properties > 0) + { + g_print (" <refsect1 role=\"properties\">\n"); + g_print (" <title role=\"properties.title\">Properties</title>\n"); + g_print (" <synopsis>\n"); + indent = 0; + arg_max_len_for_all = 0; + for (n = 0; n < interface->num_properties; n++) + { + const EggDBusInterfacePropertyInfo *property = interface->properties + n; + guint property_name_len; + + property_name_len = strlen (property->name); + if (property_name_len > indent) + indent = property_name_len; + } + for (n = 0; n < interface->num_properties; n++) + { + const EggDBusInterfacePropertyInfo *property = interface->properties + n; + + docbook_print_property_prototype (interface, + property, + indent + 2, + TRUE); + } + g_print (" </synopsis>\n"); + g_print (" </refsect1>\n"); + } + + /* Description */ + g_print (" <refsect1 role=\"desc\">\n"); + g_print (" <title role=\"desc.title\">Description</title>\n"); + g_print (" <para>\n"); + g_print ("%s\n", interface_doc_string); + g_print (" </para>\n"); + g_print (" </refsect1>\n"); + + /* Details for each method */ + if (interface->num_methods > 0) + { + g_print (" <refsect1 role=\"details\">\n"); + g_print (" <title role=\"details.title\">Method Details</title>\n"); + for (n = 0; n < interface->num_methods; n++) + { + const EggDBusInterfaceMethodInfo *method = interface->methods + n; + guint method_name_len; + guint arg_max_len; + gchar *doc_string; + + method_name_len = strlen (method->name); + + arg_max_len = docbook_get_max_arg_len_for_method (method); + + g_print (" <refsect2>\n"); + g_print (" <title><anchor role=\"function\" id=\"%s.%s\"/>%s ()</title>\n", + interface->name, + method->name, + method->name); + g_print (" <programlisting>\n"); + + docbook_print_method_prototype (interface, + method, + method_name_len + 2, + arg_max_len + 2, + FALSE); + + g_print (" </programlisting>\n"); + g_print (" <para>\n"); + doc_string = get_doc_string (method->annotations, "Method"); + g_print ("%s\n", doc_string); + g_free (doc_string); + g_print (" </para>\n"); + + docbook_print_args (interface, + "IN ", + method->in_args, + method->in_num_args, + "OUT ", + method->out_args, + method->out_num_args); + + g_print (" </refsect2>\n"); + } + g_print (" </refsect1>\n"); + } + + /* Details for each signal */ + if (interface->num_signals > 0) + { + g_print (" <refsect1 role=\"signals\">\n"); + g_print (" <title role=\"signals.title\">Signal Details</title>\n"); + for (n = 0; n < interface->num_signals; n++) + { + const EggDBusInterfaceSignalInfo *signal = interface->signals + n; + guint signal_name_len; + guint arg_max_len; + gchar *doc_string; + + signal_name_len = strlen (signal->name); + + arg_max_len = docbook_get_max_arg_len_for_signal (signal); + + g_print (" <refsect2>\n"); + g_print (" <title><anchor role=\"function\" id=\"%s::%s\"/>The %s () signal</title>\n", + interface->name, + signal->name, + signal->name); + g_print (" <programlisting>\n"); + + docbook_print_signal_prototype (interface, + signal, + signal_name_len + 2, + arg_max_len + 2, + FALSE); + + g_print (" </programlisting>\n"); + g_print (" <para>\n"); + doc_string = get_doc_string (signal->annotations, "Signal"); + g_print ("%s\n", doc_string); + g_free (doc_string); + g_print (" </para>\n"); + + docbook_print_args (interface, + "", + signal->args, + signal->num_args, + NULL, + NULL, + 0); + + g_print (" </refsect2>\n"); + } + g_print (" </refsect1>\n"); + } + + /* Details for each property */ + if (interface->num_properties > 0) + { + g_print (" <refsect1 role=\"property_details\">\n"); + g_print (" <title role=\"property_details.title\">Property Details</title>\n"); + for (n = 0; n < interface->num_properties; n++) + { + const EggDBusInterfacePropertyInfo *property = interface->properties + n; + guint property_name_len; + gchar *doc_string; + + property_name_len = strlen (property->name); + + g_print (" <refsect2>\n"); + g_print (" <title><anchor role=\"function\" id=\"%s:%s\"/>The \"%s\" property</title>\n", + interface->name, + property->name, + property->name); + g_print (" <programlisting>\n"); + + docbook_print_property_prototype (interface, + property, + property_name_len + 2, + FALSE); + + g_print (" </programlisting>\n"); + g_print (" <para>\n"); + doc_string = get_doc_string (property->annotations, "Property"); + g_print ("%s\n", doc_string); + g_free (doc_string); + g_print (" </para>\n"); + + g_print (" </refsect2>\n"); + } + g_print (" </refsect1>\n"); + } + + g_print ("</refentry>\n"); + + ret = TRUE; + + g_free (interface_summary_doc_string); + g_free (interface_doc_string); + + return ret; +} diff --git a/src/eggdbus/docbook.h b/src/eggdbus/docbook.h new file mode 100644 index 0000000..8f68fca --- /dev/null +++ b/src/eggdbus/docbook.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * 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 <davidz@redhat.com> + */ + +#ifndef __DOCBOOK_H +#define __DOCBOOK_H + +#include "eggdbusinterface.h" + +G_BEGIN_DECLS + +gboolean interface_generate_docbook (const EggDBusInterfaceInfo *interface, + GError **error); + +G_END_DECLS + +#endif /* __DOCBOOK_H */ diff --git a/src/eggdbus/eggdbusbindingtool.c b/src/eggdbus/eggdbusbindingtool.c index 0bfb9aa..740fbb8 100644 --- a/src/eggdbus/eggdbusbindingtool.c +++ b/src/eggdbus/eggdbusbindingtool.c @@ -32,6 +32,7 @@ #include "interface.h" #include "struct.h" #include "enum.h" +#include "docbook.h" static char **opt_xml = NULL; static gboolean opt_iface_only = FALSE; diff --git a/src/eggdbus/interface.c b/src/eggdbus/interface.c index dbd3d41..2e74c4d 100644 --- a/src/eggdbus/interface.c +++ b/src/eggdbus/interface.c @@ -3280,773 +3280,3 @@ interface_generate_iface_c_file (const EggDBusInterfaceInfo *interface, return ret; } - -static void -get_type_name_for_sig_iter (DBusSignatureIter *sig_iter, - gchar **out_raw, - gchar **out_name) -{ - GString *ret_raw; - GString *ret; - gchar *s; - gchar *s_raw; - gchar *s1; - gchar *s1_raw; - guint n; - DBusSignatureIter sub_sig_iter; - int cur_type; - - ret_raw = NULL; - ret = g_string_new (NULL); - - cur_type = dbus_signature_iter_get_current_type (sig_iter); - - switch (cur_type) - { - case DBUS_TYPE_BYTE: - g_string_append (ret, "Byte"); - break; - - case DBUS_TYPE_BOOLEAN: - g_string_append (ret, "Boolean"); - break; - - case DBUS_TYPE_INT16: - g_string_append (ret, "Int16"); - break; - - case DBUS_TYPE_UINT16: - g_string_append (ret, "UInt16"); - break; - - case DBUS_TYPE_INT32: - g_string_append (ret, "Int32"); - break; - - case DBUS_TYPE_UINT32: - g_string_append (ret, "UInt32"); - break; - - case DBUS_TYPE_INT64: - g_string_append (ret, "Int64"); - break; - - case DBUS_TYPE_UINT64: - g_string_append (ret, "UInt64"); - break; - - case DBUS_TYPE_DOUBLE: - g_string_append (ret, "Double"); - break; - - case DBUS_TYPE_STRING: - g_string_append (ret, "String"); - break; - - case DBUS_TYPE_OBJECT_PATH: - g_string_append (ret, "ObjectPath"); - break; - - case DBUS_TYPE_SIGNATURE: - g_string_append (ret, "Signature"); - break; - - case DBUS_TYPE_VARIANT: - g_string_append (ret, "Variant"); - break; - - case DBUS_TYPE_DICT_ENTRY: - ret_raw = g_string_new (NULL); - - dbus_signature_iter_recurse (sig_iter, &sub_sig_iter); - get_type_name_for_sig_iter (&sub_sig_iter, &s_raw, &s); - g_assert (dbus_signature_iter_next (&sub_sig_iter) == TRUE); - get_type_name_for_sig_iter (&sub_sig_iter, &s1_raw, &s1); - g_assert (dbus_signature_iter_next (&sub_sig_iter) == FALSE); - g_string_append_printf (ret_raw, "Dict<%s_%s>", s_raw, s1_raw); - g_string_append_printf (ret, "Dict<%s→%s>", s, s1); /* U+2192 RIGHTWARDS ARROW */ - g_free (s_raw); - g_free (s); - g_free (s1_raw); - g_free (s1); - break; - - case DBUS_TYPE_STRUCT: - ret_raw = g_string_new (NULL); - - g_string_append (ret_raw, "["); - g_string_append (ret, "["); - dbus_signature_iter_recurse (sig_iter, &sub_sig_iter); - n = 0; - do - { - get_type_name_for_sig_iter (&sub_sig_iter, &s_raw, &s); - if (n != 0) - { - g_string_append (ret_raw, ","); - g_string_append (ret, ","); - } - g_string_append_printf (ret_raw, "%s", s_raw); - g_string_append_printf (ret, "%s", s); - g_free (s_raw); - g_free (s); - n++; - } - while (dbus_signature_iter_next (&sub_sig_iter)); - g_string_append (ret_raw, "]"); - g_string_append (ret, "]"); - break; - - case DBUS_TYPE_ARRAY: - ret_raw = g_string_new (NULL); - - dbus_signature_iter_recurse (sig_iter, &sub_sig_iter); - get_type_name_for_sig_iter (&sub_sig_iter, &s_raw, &s); - if (g_str_has_prefix (s, "Dict<")) - { - g_string_append (ret_raw, s_raw); - g_string_append (ret, s); - } - else - { - g_string_append_printf (ret_raw, "Array<%s>", s_raw); - g_string_append_printf (ret, "Array<%s>", s); - } - g_free (s); - break; - - default: - g_warning ("Unable to handle %s", dbus_signature_iter_get_signature (sig_iter)); - g_assert_not_reached (); - break; - } - - s = g_string_free (ret, FALSE); - - if (ret_raw != NULL) - s_raw = g_string_free (ret_raw, FALSE); - else - s_raw = g_strdup (s); - - if (out_raw != NULL) - { - *out_raw = s_raw; - s_raw = NULL; - } - - if (out_name != NULL) - { - *out_name = s; - s = NULL; - } - - g_free (s); - g_free (s_raw); -} - -static void -docbook_get_typename_for_signature (const gchar *signature, - gchar **out_name, - gchar **out_link) -{ - DBusSignatureIter iter; - gchar *name; - gchar *name_link; - - name = NULL; - name_link = NULL; - - dbus_signature_iter_init (&iter, signature); - get_type_name_for_sig_iter (&iter, &name, &name_link); - - if (out_name != NULL) - { - *out_name = name; - name = NULL; - } - - if (out_link != NULL) - { - *out_link = name_link; - name_link = NULL; - } - - g_free (name); - g_free (name_link); -} - -static void -docbook_print_arg (const EggDBusInterfaceArgInfo *arg, - const gchar *arg_prefix, - guint arg_max_len) -{ - gchar *arg_type_name; - gchar *arg_type_link; - - docbook_get_typename_for_signature (arg->signature, &arg_type_name, &arg_type_link); - - g_print ("%s%s%*s%s", - arg_prefix, - arg_type_link, - (int) (arg_max_len - strlen (arg_type_name)), "", - arg->name); - - g_free (arg_type_name); - g_free (arg_type_link); -} - -static guint -docbook_get_max_arg_len_for_method (const EggDBusInterfaceMethodInfo *method) -{ - guint n; - guint max_arg_len; - - max_arg_len = 0; - - for (n = 0; n < method->in_num_args; n++) - { - const EggDBusInterfaceArgInfo *arg = method->in_args + n; - gchar *arg_type_name; - guint arg_len; - - docbook_get_typename_for_signature (arg->signature, &arg_type_name, NULL); - arg_len = strlen (arg_type_name); - g_free (arg_type_name); - - if (arg_len > max_arg_len) - max_arg_len = arg_len; - } - - for (n = 0; n < method->out_num_args; n++) - { - const EggDBusInterfaceArgInfo *arg = method->out_args + n; - gchar *arg_type_name; - guint arg_len; - - docbook_get_typename_for_signature (arg->signature, &arg_type_name, NULL); - arg_len = strlen (arg_type_name); - g_free (arg_type_name); - - if (arg_len > max_arg_len) - max_arg_len = arg_len; - } - - return max_arg_len; -} - -static guint -docbook_get_max_arg_len_for_signal (const EggDBusInterfaceSignalInfo *signal) -{ - guint n; - guint max_arg_len; - - max_arg_len = 0; - - for (n = 0; n < signal->num_args; n++) - { - const EggDBusInterfaceArgInfo *arg = signal->args + n; - gchar *arg_type_name; - guint arg_len; - - docbook_get_typename_for_signature (arg->signature, &arg_type_name, NULL); - arg_len = strlen (arg_type_name); - g_free (arg_type_name); - - if (arg_len > max_arg_len) - max_arg_len = arg_len; - } - - return max_arg_len; -} - -static void -docbook_print_method_prototype (const EggDBusInterfaceInfo *interface, - const EggDBusInterfaceMethodInfo *method, - guint indent, - guint arg_max_len, - gboolean use_hyperlink) -{ - guint n; - guint num_printed; - guint first_indent; - - first_indent = indent - strlen (method->name) - 1; - - if (use_hyperlink) - { - g_print ("<link linkend=\"%s.%s\">%s</link>%*s(", - interface->name, - method->name, - method->name, - first_indent, ""); - } - else - { - g_print ("%s%*s(", - method->name, - first_indent, ""); - } - - num_printed = 0; - for (n = 0; n < method->in_num_args; n++) - { - const EggDBusInterfaceArgInfo *arg = method->in_args + n; - - if (num_printed != 0) - g_print (",\n%*s", indent, ""); - - docbook_print_arg (arg, "IN ", arg_max_len); - - num_printed++; - } - - for (n = 0; n < method->out_num_args; n++) - { - const EggDBusInterfaceArgInfo *arg = method->out_args + n; - - if (num_printed != 0) - g_print (",\n%*s", indent, ""); - - docbook_print_arg (arg, "OUT ", arg_max_len); - - num_printed++; - } - - g_print (")\n"); -} - -static void -docbook_print_signal_prototype (const EggDBusInterfaceInfo *interface, - const EggDBusInterfaceSignalInfo *signal, - guint indent, - guint arg_max_len, - gboolean use_hyperlink) -{ - guint n; - guint num_printed; - guint first_indent; - - first_indent = indent - strlen (signal->name) - 1; - - if (use_hyperlink) - { - g_print ("<link linkend=\"%s::%s\">%s</link>%*s(", - interface->name, - signal->name, - signal->name, - first_indent, ""); - } - else - { - g_print ("%s%*s(", - signal->name, - first_indent, ""); - } - - num_printed = 0; - for (n = 0; n < signal->num_args; n++) - { - const EggDBusInterfaceArgInfo *arg = signal->args + n; - - if (num_printed != 0) - g_print (",\n%*s", indent, ""); - - docbook_print_arg (arg, "", arg_max_len); - - num_printed++; - } - - g_print (")\n"); -} - -static void -docbook_print_property_prototype (const EggDBusInterfaceInfo *interface, - const EggDBusInterfacePropertyInfo *property, - guint indent, - gboolean use_hyperlink) -{ - guint first_indent; - gchar *arg_type_link; - - first_indent = indent - strlen (property->name) - 1; - - if (use_hyperlink) - { - g_print ("<link linkend=\"%s:%s\">%s</link>%*s ", - interface->name, - property->name, - property->name, - first_indent, ""); - } - else - { - g_print ("%s%*s ", - property->name, - first_indent, ""); - } - - if ((property->flags & EGG_DBUS_INTERFACE_PROPERTY_INFO_FLAGS_READABLE) && - (property->flags & EGG_DBUS_INTERFACE_PROPERTY_INFO_FLAGS_WRITABLE)) - { - g_print ("readwrite "); - } - else if (property->flags & EGG_DBUS_INTERFACE_PROPERTY_INFO_FLAGS_READABLE) - { - g_print ("readable "); - } - else if (property->flags & EGG_DBUS_INTERFACE_PROPERTY_INFO_FLAGS_WRITABLE) - { - g_print ("writable "); - } - else - { - g_print (" "); - } - - docbook_get_typename_for_signature (property->signature, NULL, &arg_type_link); - - g_print (" %s\n", arg_type_link); - - g_free (arg_type_link); -} - -static void -docbook_print_arg_in_list (const gchar *prefix, - const EggDBusInterfaceArgInfo *arg) -{ - gchar *arg_doc_string; - gchar *arg_type_link; - - arg_doc_string = get_doc_string (arg->annotations, "Argument"); - - docbook_get_typename_for_signature (arg->signature, NULL, &arg_type_link); - - g_print (" <varlistentry>\n"); - g_print (" <term><literal>%s%s <parameter>%s</parameter></literal>:</term>\n", - prefix, - arg_type_link, - arg->name); - g_print (" <listitem>\n"); - g_print (" <para>\n"); - g_print ("%s\n", arg_doc_string); - g_print (" </para>\n"); - g_print (" </listitem>\n"); - g_print (" </varlistentry>\n"); - - g_free (arg_doc_string); - - g_free (arg_type_link); -} - -static void -docbook_print_args (const EggDBusInterfaceInfo *interface, - const gchar *prefix0, - const EggDBusInterfaceArgInfo *args0, - guint num_args0, - const gchar *prefix1, - const EggDBusInterfaceArgInfo *args1, - guint num_args1) -{ - guint n; - - g_print ("<variablelist role=\"params\">\n"); - - for (n = 0; n < num_args0; n++) - { - const EggDBusInterfaceArgInfo *arg = args0 + n; - docbook_print_arg_in_list (prefix0, arg); - } - - for (n = 0; n < num_args1; n++) - { - const EggDBusInterfaceArgInfo *arg = args1 + n; - docbook_print_arg_in_list (prefix1, arg); - } - - g_print ("</variablelist>\n"); -} - -gboolean -interface_generate_docbook (const EggDBusInterfaceInfo *interface, - GError **error) -{ - gboolean ret; - gchar *interface_summary_doc_string; - gchar *interface_doc_string; - guint n; - guint indent; - guint arg_max_len_for_all; - - ret = FALSE; - - interface_summary_doc_string = get_summary_doc_string (interface->annotations, "Interface"); - interface_doc_string = get_doc_string (interface->annotations, "Interface"); - - g_print ("<?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"); - - g_print ("<refentry id=\"%s\">\n", interface->name); - g_print (" <refmeta>\n"); - g_print (" <refentrytitle role=\"top_of_page\">%s</refentrytitle>\n", interface->name); - g_print (" </refmeta>\n"); - g_print (" <refnamediv>\n"); - g_print (" <refname>%s</refname>\n", interface->name); - g_print (" <refpurpose>%s</refpurpose>\n", interface_summary_doc_string); - g_print (" </refnamediv>\n"); - - /* Synopsis for methods */ - if (interface->num_methods > 0) - { - g_print (" <refsynopsisdiv role=\"synopsis\">\n"); - g_print (" <title role=\"synopsis.title\">Methods</title>\n"); - g_print (" <synopsis>\n"); - indent = 0; - arg_max_len_for_all = 0; - for (n = 0; n < interface->num_methods; n++) - { - const EggDBusInterfaceMethodInfo *method = interface->methods + n; - guint method_name_len; - guint arg_max_len; - - method_name_len = strlen (method->name); - if (method_name_len > indent) - indent = method_name_len; - - arg_max_len = docbook_get_max_arg_len_for_method (method); - if (arg_max_len > arg_max_len_for_all) - arg_max_len_for_all = arg_max_len; - } - for (n = 0; n < interface->num_methods; n++) - { - const EggDBusInterfaceMethodInfo *method = interface->methods + n; - - docbook_print_method_prototype (interface, - method, - indent + 2, - arg_max_len_for_all + 2, - TRUE); - } - g_print (" </synopsis>\n"); - g_print (" </refsynopsisdiv>\n"); - } - - /* Synopsis for signals */ - if (interface->num_signals > 0) - { - g_print (" <refsect1 role=\"signal_proto\">\n"); - g_print (" <title role=\"signal_proto.title\">Signals</title>\n"); - g_print (" <synopsis>\n"); - indent = 0; - arg_max_len_for_all = 0; - for (n = 0; n < interface->num_signals; n++) - { - const EggDBusInterfaceSignalInfo *signal = interface->signals + n; - guint signal_name_len; - guint arg_max_len; - - signal_name_len = strlen (signal->name); - if (signal_name_len > indent) - indent = signal_name_len; - - arg_max_len = docbook_get_max_arg_len_for_signal (signal); - if (arg_max_len > arg_max_len_for_all) - arg_max_len_for_all = arg_max_len; - } - for (n = 0; n < interface->num_signals; n++) - { - const EggDBusInterfaceSignalInfo *signal = interface->signals + n; - - docbook_print_signal_prototype (interface, - signal, - indent + 2, - arg_max_len_for_all + 2, - TRUE); - } - g_print (" </synopsis>\n"); - g_print (" </refsect1>\n"); - } - - /* Synopsis for properties */ - if (interface->num_properties > 0) - { - g_print (" <refsect1 role=\"properties\">\n"); - g_print (" <title role=\"properties.title\">Properties</title>\n"); - g_print (" <synopsis>\n"); - indent = 0; - arg_max_len_for_all = 0; - for (n = 0; n < interface->num_properties; n++) - { - const EggDBusInterfacePropertyInfo *property = interface->properties + n; - guint property_name_len; - - property_name_len = strlen (property->name); - if (property_name_len > indent) - indent = property_name_len; - } - for (n = 0; n < interface->num_properties; n++) - { - const EggDBusInterfacePropertyInfo *property = interface->properties + n; - - docbook_print_property_prototype (interface, - property, - indent + 2, - TRUE); - } - g_print (" </synopsis>\n"); - g_print (" </refsect1>\n"); - } - - /* Description */ - g_print (" <refsect1 role=\"desc\">\n"); - g_print (" <title role=\"desc.title\">Description</title>\n"); - g_print (" <para>\n"); - g_print ("%s\n", interface_doc_string); - g_print (" </para>\n"); - g_print (" </refsect1>\n"); - - /* Details for each method */ - if (interface->num_methods > 0) - { - g_print (" <refsect1 role=\"details\">\n"); - g_print (" <title role=\"details.title\">Method Details</title>\n"); - for (n = 0; n < interface->num_methods; n++) - { - const EggDBusInterfaceMethodInfo *method = interface->methods + n; - guint method_name_len; - guint arg_max_len; - gchar *doc_string; - - method_name_len = strlen (method->name); - - arg_max_len = docbook_get_max_arg_len_for_method (method); - - g_print (" <refsect2>\n"); - g_print (" <title><anchor role=\"function\" id=\"%s.%s\"/>%s ()</title>\n", - interface->name, - method->name, - method->name); - g_print (" <programlisting>\n"); - - docbook_print_method_prototype (interface, - method, - method_name_len + 2, - arg_max_len + 2, - FALSE); - - g_print (" </programlisting>\n"); - g_print (" <para>\n"); - doc_string = get_doc_string (method->annotations, "Method"); - g_print ("%s\n", doc_string); - g_free (doc_string); - g_print (" </para>\n"); - - docbook_print_args (interface, - "IN ", - method->in_args, - method->in_num_args, - "OUT ", - method->out_args, - method->out_num_args); - - g_print (" </refsect2>\n"); - } - g_print (" </refsect1>\n"); - } - - /* Details for each signal */ - if (interface->num_signals > 0) - { - g_print (" <refsect1 role=\"signals\">\n"); - g_print (" <title role=\"signals.title\">Signal Details</title>\n"); - for (n = 0; n < interface->num_signals; n++) - { - const EggDBusInterfaceSignalInfo *signal = interface->signals + n; - guint signal_name_len; - guint arg_max_len; - gchar *doc_string; - - signal_name_len = strlen (signal->name); - - arg_max_len = docbook_get_max_arg_len_for_signal (signal); - - g_print (" <refsect2>\n"); - g_print (" <title><anchor role=\"function\" id=\"%s::%s\"/>The %s () signal</title>\n", - interface->name, - signal->name, - signal->name); - g_print (" <programlisting>\n"); - - docbook_print_signal_prototype (interface, - signal, - signal_name_len + 2, - arg_max_len + 2, - FALSE); - - g_print (" </programlisting>\n"); - g_print (" <para>\n"); - doc_string = get_doc_string (signal->annotations, "Signal"); - g_print ("%s\n", doc_string); - g_free (doc_string); - g_print (" </para>\n"); - - docbook_print_args (interface, - "", - signal->args, - signal->num_args, - NULL, - NULL, - 0); - - g_print (" </refsect2>\n"); - } - g_print (" </refsect1>\n"); - } - - /* Details for each property */ - if (interface->num_properties > 0) - { - g_print (" <refsect1 role=\"property_details\">\n"); - g_print (" <title role=\"property_details.title\">Property Details</title>\n"); - for (n = 0; n < interface->num_properties; n++) - { - const EggDBusInterfacePropertyInfo *property = interface->properties + n; - guint property_name_len; - gchar *doc_string; - - property_name_len = strlen (property->name); - - g_print (" <refsect2>\n"); - g_print (" <title><anchor role=\"function\" id=\"%s:%s\"/>The \"%s\" property</title>\n", - interface->name, - property->name, - property->name); - g_print (" <programlisting>\n"); - - docbook_print_property_prototype (interface, - property, - property_name_len + 2, - FALSE); - - g_print (" </programlisting>\n"); - g_print (" <para>\n"); - doc_string = get_doc_string (property->annotations, "Property"); - g_print ("%s\n", doc_string); - g_free (doc_string); - g_print (" </para>\n"); - - g_print (" </refsect2>\n"); - } - g_print (" </refsect1>\n"); - } - - g_print ("</refentry>\n"); - - ret = TRUE; - - g_free (interface_summary_doc_string); - g_free (interface_doc_string); - - return ret; -} - diff --git a/src/eggdbus/interface.h b/src/eggdbus/interface.h index d5e3794..eecb35d 100644 --- a/src/eggdbus/interface.h +++ b/src/eggdbus/interface.h @@ -39,9 +39,6 @@ gboolean interface_generate_iface_c_file (const EggDBusInterfaceInfo *interface const char *h_file_name, GError **error); -gboolean interface_generate_docbook (const EggDBusInterfaceInfo *interface, - GError **error); - G_END_DECLS #endif /* __INTERFACE_H */ |