| # -*- Mode: Python -*- |
| |
| # GDBus - GLib D-Bus Library |
| # |
| # Copyright (C) 2008-2011 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.1 of the License, or (at your option) any later version. |
| # |
| # This library is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| # Lesser General Public License for more details. |
| # |
| # You should have received a copy of the GNU Lesser General |
| # Public License along with this library; if not, see <http://www.gnu.org/licenses/>. |
| # |
| # Author: David Zeuthen <davidz@redhat.com> |
| |
| from . import utils |
| from .utils import print_error |
| |
| |
| class Annotation: |
| def __init__(self, key, value): |
| self.key = key |
| self.value = value |
| self.annotations = [] |
| self.since = "" |
| |
| def post_process(self, interface_prefix, cns, cns_upper, cns_lower, container): |
| key = self.key |
| overridden_key = utils.lookup_annotation( |
| self.annotations, "org.gtk.GDBus.C.Name" |
| ) |
| if utils.is_ugly_case(overridden_key): |
| self.key_lower = overridden_key.lower() |
| else: |
| if overridden_key: |
| key = overridden_key |
| self.key_lower = ( |
| utils.camel_case_to_uscore(key) |
| .lower() |
| .replace("-", "_") |
| .replace(".", "_") |
| ) |
| |
| if len(self.since) == 0: |
| self.since = utils.lookup_since(self.annotations) |
| if len(self.since) == 0: |
| self.since = container.since |
| |
| for a in self.annotations: |
| a.post_process(interface_prefix, cns, cns_upper, cns_lower, self) |
| |
| |
| class Arg: |
| def __init__(self, name, signature): |
| self.name = name |
| self.signature = signature |
| self.annotations = [] |
| self.doc_string = "" |
| self.since = "" |
| |
| def post_process(self, interface_prefix, cns, cns_upper, cns_lower, arg_number): |
| if len(self.doc_string) == 0: |
| self.doc_string = utils.lookup_docs(self.annotations) |
| if len(self.since) == 0: |
| self.since = utils.lookup_since(self.annotations) |
| |
| if self.name is None: |
| self.name = "unnamed_arg%d" % arg_number |
| # default to GVariant |
| self.ctype_in_g = "GVariant *" |
| self.ctype_in = "GVariant *" |
| self.ctype_in_dup = "GVariant *" |
| self.ctype_out = "GVariant **" |
| self.gtype = "G_TYPE_VARIANT" |
| self.free_func = "g_variant_unref" |
| self.format_in = "@" + self.signature |
| self.format_out = "@" + self.signature |
| self.gvariant_get = "XXX" |
| self.gvalue_get = "g_value_get_variant" |
| self.array_annotation = "" |
| |
| if not utils.lookup_annotation( |
| self.annotations, "org.gtk.GDBus.C.ForceGVariant" |
| ): |
| if self.signature == "b": |
| self.ctype_in_g = "gboolean " |
| self.ctype_in = "gboolean " |
| self.ctype_out = "gboolean *" |
| self.gtype = "G_TYPE_BOOLEAN" |
| self.free_func = None |
| self.format_in = "b" |
| self.format_out = "b" |
| self.gvariant_get = "g_variant_get_boolean" |
| self.gvalue_get = "g_value_get_boolean" |
| elif self.signature == "y": |
| self.ctype_in_g = "guchar " |
| self.ctype_in = "guchar " |
| self.ctype_out = "guchar *" |
| self.gtype = "G_TYPE_UCHAR" |
| self.free_func = None |
| self.format_in = "y" |
| self.format_out = "y" |
| self.gvariant_get = "g_variant_get_byte" |
| self.gvalue_get = "g_value_get_uchar" |
| elif self.signature == "n": |
| self.ctype_in_g = "gint " |
| self.ctype_in = "gint16 " |
| self.ctype_out = "gint16 *" |
| self.gtype = "G_TYPE_INT" |
| self.free_func = None |
| self.format_in = "n" |
| self.format_out = "n" |
| self.gvariant_get = "g_variant_get_int16" |
| self.gvalue_get = "g_value_get_int" |
| elif self.signature == "q": |
| self.ctype_in_g = "guint " |
| self.ctype_in = "guint16 " |
| self.ctype_out = "guint16 *" |
| self.gtype = "G_TYPE_UINT" |
| self.free_func = None |
| self.format_in = "q" |
| self.format_out = "q" |
| self.gvariant_get = "g_variant_get_uint16" |
| self.gvalue_get = "g_value_get_uint" |
| elif self.signature == "i": |
| self.ctype_in_g = "gint " |
| self.ctype_in = "gint " |
| self.ctype_out = "gint *" |
| self.gtype = "G_TYPE_INT" |
| self.free_func = None |
| self.format_in = "i" |
| self.format_out = "i" |
| self.gvariant_get = "g_variant_get_int32" |
| self.gvalue_get = "g_value_get_int" |
| elif self.signature == "u": |
| self.ctype_in_g = "guint " |
| self.ctype_in = "guint " |
| self.ctype_out = "guint *" |
| self.gtype = "G_TYPE_UINT" |
| self.free_func = None |
| self.format_in = "u" |
| self.format_out = "u" |
| self.gvariant_get = "g_variant_get_uint32" |
| self.gvalue_get = "g_value_get_uint" |
| elif self.signature == "x": |
| self.ctype_in_g = "gint64 " |
| self.ctype_in = "gint64 " |
| self.ctype_out = "gint64 *" |
| self.gtype = "G_TYPE_INT64" |
| self.free_func = None |
| self.format_in = "x" |
| self.format_out = "x" |
| self.gvariant_get = "g_variant_get_int64" |
| self.gvalue_get = "g_value_get_int64" |
| elif self.signature == "t": |
| self.ctype_in_g = "guint64 " |
| self.ctype_in = "guint64 " |
| self.ctype_out = "guint64 *" |
| self.gtype = "G_TYPE_UINT64" |
| self.free_func = None |
| self.format_in = "t" |
| self.format_out = "t" |
| self.gvariant_get = "g_variant_get_uint64" |
| self.gvalue_get = "g_value_get_uint64" |
| elif self.signature == "d": |
| self.ctype_in_g = "gdouble " |
| self.ctype_in = "gdouble " |
| self.ctype_out = "gdouble *" |
| self.gtype = "G_TYPE_DOUBLE" |
| self.free_func = None |
| self.format_in = "d" |
| self.format_out = "d" |
| self.gvariant_get = "g_variant_get_double" |
| self.gvalue_get = "g_value_get_double" |
| elif self.signature == "s": |
| self.ctype_in_g = "const gchar *" |
| self.ctype_in = "const gchar *" |
| self.ctype_in_dup = "gchar *" |
| self.ctype_out = "gchar **" |
| self.gtype = "G_TYPE_STRING" |
| self.free_func = "g_free" |
| self.format_in = "s" |
| self.format_out = "s" |
| self.gvariant_get = "g_variant_get_string" |
| self.gvalue_get = "g_value_get_string" |
| elif self.signature == "o": |
| self.ctype_in_g = "const gchar *" |
| self.ctype_in = "const gchar *" |
| self.ctype_in_dup = "gchar *" |
| self.ctype_out = "gchar **" |
| self.gtype = "G_TYPE_STRING" |
| self.free_func = "g_free" |
| self.format_in = "o" |
| self.format_out = "o" |
| self.gvariant_get = "g_variant_get_string" |
| self.gvalue_get = "g_value_get_string" |
| elif self.signature == "g": |
| self.ctype_in_g = "const gchar *" |
| self.ctype_in = "const gchar *" |
| self.ctype_in_dup = "gchar *" |
| self.ctype_out = "gchar **" |
| self.gtype = "G_TYPE_STRING" |
| self.free_func = "g_free" |
| self.format_in = "g" |
| self.format_out = "g" |
| self.gvariant_get = "g_variant_get_string" |
| self.gvalue_get = "g_value_get_string" |
| elif self.signature == "ay": |
| self.ctype_in_g = "const gchar *" |
| self.ctype_in = "const gchar *" |
| self.ctype_in_dup = "gchar *" |
| self.ctype_out = "gchar **" |
| self.gtype = "G_TYPE_STRING" |
| self.free_func = "g_free" |
| self.format_in = "^ay" |
| self.format_out = "^ay" |
| self.gvariant_get = "g_variant_get_bytestring" |
| self.gvalue_get = "g_value_get_string" |
| elif self.signature == "as": |
| self.ctype_in_g = "const gchar *const *" |
| self.ctype_in = "const gchar *const *" |
| self.ctype_in_dup = "gchar **" |
| self.ctype_out = "gchar ***" |
| self.gtype = "G_TYPE_STRV" |
| self.free_func = "g_strfreev" |
| self.format_in = "^as" |
| self.format_out = "^as" |
| self.gvariant_get = "g_variant_get_strv" |
| self.gvalue_get = "g_value_get_boxed" |
| self.array_annotation = "(array zero-terminated=1)" |
| elif self.signature == "ao": |
| self.ctype_in_g = "const gchar *const *" |
| self.ctype_in = "const gchar *const *" |
| self.ctype_in_dup = "gchar **" |
| self.ctype_out = "gchar ***" |
| self.gtype = "G_TYPE_STRV" |
| self.free_func = "g_strfreev" |
| self.format_in = "^ao" |
| self.format_out = "^ao" |
| self.gvariant_get = "g_variant_get_objv" |
| self.gvalue_get = "g_value_get_boxed" |
| self.array_annotation = "(array zero-terminated=1)" |
| elif self.signature == "aay": |
| self.ctype_in_g = "const gchar *const *" |
| self.ctype_in = "const gchar *const *" |
| self.ctype_in_dup = "gchar **" |
| self.ctype_out = "gchar ***" |
| self.gtype = "G_TYPE_STRV" |
| self.free_func = "g_strfreev" |
| self.format_in = "^aay" |
| self.format_out = "^aay" |
| self.gvariant_get = "g_variant_get_bytestring_array" |
| self.gvalue_get = "g_value_get_boxed" |
| self.array_annotation = "(array zero-terminated=1)" |
| |
| for a in self.annotations: |
| a.post_process(interface_prefix, cns, cns_upper, cns_lower, self) |
| |
| |
| class Method: |
| def __init__(self, name, h_type_implies_unix_fd=True): |
| self.name = name |
| self.h_type_implies_unix_fd = h_type_implies_unix_fd |
| self.in_args = [] |
| self.out_args = [] |
| self.annotations = [] |
| self.doc_string = "" |
| self.since = "" |
| self.deprecated = False |
| self.unix_fd = False |
| |
| def post_process( |
| self, interface_prefix, cns, cns_upper, cns_lower, containing_iface |
| ): |
| if len(self.doc_string) == 0: |
| self.doc_string = utils.lookup_docs(self.annotations) |
| if len(self.since) == 0: |
| self.since = utils.lookup_since(self.annotations) |
| if len(self.since) == 0: |
| self.since = containing_iface.since |
| |
| name = self.name |
| overridden_name = utils.lookup_annotation( |
| self.annotations, "org.gtk.GDBus.C.Name" |
| ) |
| if utils.is_ugly_case(overridden_name): |
| self.name_lower = overridden_name.lower() |
| else: |
| if overridden_name: |
| name = overridden_name |
| self.name_lower = utils.camel_case_to_uscore(name).lower().replace("-", "_") |
| self.name_hyphen = self.name_lower.replace("_", "-") |
| |
| arg_count = 0 |
| for a in self.in_args: |
| a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count) |
| arg_count += 1 |
| if self.h_type_implies_unix_fd and "h" in a.signature: |
| self.unix_fd = True |
| |
| for a in self.out_args: |
| a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count) |
| arg_count += 1 |
| if self.h_type_implies_unix_fd and "h" in a.signature: |
| self.unix_fd = True |
| |
| if ( |
| utils.lookup_annotation(self.annotations, "org.freedesktop.DBus.Deprecated") |
| == "true" |
| ): |
| self.deprecated = True |
| |
| if utils.lookup_annotation(self.annotations, "org.gtk.GDBus.C.UnixFD"): |
| self.unix_fd = True |
| |
| for a in self.annotations: |
| a.post_process(interface_prefix, cns, cns_upper, cns_lower, self) |
| |
| |
| class Signal: |
| def __init__(self, name): |
| self.name = name |
| self.args = [] |
| self.annotations = [] |
| self.doc_string = "" |
| self.since = "" |
| self.deprecated = False |
| |
| def post_process( |
| self, interface_prefix, cns, cns_upper, cns_lower, containing_iface |
| ): |
| if len(self.doc_string) == 0: |
| self.doc_string = utils.lookup_docs(self.annotations) |
| if len(self.since) == 0: |
| self.since = utils.lookup_since(self.annotations) |
| if len(self.since) == 0: |
| self.since = containing_iface.since |
| |
| name = self.name |
| overridden_name = utils.lookup_annotation( |
| self.annotations, "org.gtk.GDBus.C.Name" |
| ) |
| if utils.is_ugly_case(overridden_name): |
| self.name_lower = overridden_name.lower() |
| else: |
| if overridden_name: |
| name = overridden_name |
| self.name_lower = utils.camel_case_to_uscore(name).lower().replace("-", "_") |
| self.name_hyphen = self.name_lower.replace("_", "-") |
| |
| arg_count = 0 |
| for a in self.args: |
| a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count) |
| arg_count += 1 |
| |
| if ( |
| utils.lookup_annotation(self.annotations, "org.freedesktop.DBus.Deprecated") |
| == "true" |
| ): |
| self.deprecated = True |
| |
| for a in self.annotations: |
| a.post_process(interface_prefix, cns, cns_upper, cns_lower, self) |
| |
| |
| class Property: |
| def __init__(self, name, signature, access): |
| self.name = name |
| self.signature = signature |
| self.access = access |
| self.annotations = [] |
| self.arg = Arg("value", self.signature) |
| self.arg.annotations = self.annotations |
| self.readable = False |
| self.writable = False |
| if self.access == "readwrite": |
| self.readable = True |
| self.writable = True |
| elif self.access == "read": |
| self.readable = True |
| elif self.access == "write": |
| self.writable = True |
| else: |
| print_error('Invalid access type "{}"'.format(self.access)) |
| self.doc_string = "" |
| self.since = "" |
| self.deprecated = False |
| self.emits_changed_signal = True |
| |
| def post_process( |
| self, interface_prefix, cns, cns_upper, cns_lower, containing_iface |
| ): |
| if len(self.doc_string) == 0: |
| self.doc_string = utils.lookup_docs(self.annotations) |
| if len(self.since) == 0: |
| self.since = utils.lookup_since(self.annotations) |
| if len(self.since) == 0: |
| self.since = containing_iface.since |
| |
| name = self.name |
| overridden_name = utils.lookup_annotation( |
| self.annotations, "org.gtk.GDBus.C.Name" |
| ) |
| if utils.is_ugly_case(overridden_name): |
| self.name_lower = overridden_name.lower() |
| else: |
| if overridden_name: |
| name = overridden_name |
| self.name_lower = utils.camel_case_to_uscore(name).lower().replace("-", "_") |
| self.name_hyphen = self.name_lower.replace("_", "-") |
| # don't clash with the GType getter, e.g.: |
| # GType foo_bar_get_type (void); G_GNUC_CONST |
| if self.name_lower == "type": |
| self.name_lower = "type_" |
| |
| # recalculate arg |
| self.arg.annotations = self.annotations |
| self.arg.post_process(interface_prefix, cns, cns_upper, cns_lower, 0) |
| |
| if ( |
| utils.lookup_annotation(self.annotations, "org.freedesktop.DBus.Deprecated") |
| == "true" |
| ): |
| self.deprecated = True |
| |
| for a in self.annotations: |
| a.post_process(interface_prefix, cns, cns_upper, cns_lower, self) |
| |
| # FIXME: for now we only support 'false' and 'const' on the signal itself, |
| # see #674913 and |
| # http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format |
| # for details |
| if utils.lookup_annotation( |
| self.annotations, "org.freedesktop.DBus.Property.EmitsChangedSignal" |
| ) in ("false", "const"): |
| self.emits_changed_signal = False |
| |
| |
| class Interface: |
| def __init__(self, name): |
| self.name = name |
| self.methods = [] |
| self.signals = [] |
| self.properties = [] |
| self.annotations = [] |
| self.doc_string = "" |
| self.doc_string_brief = "" |
| self.since = "" |
| self.deprecated = False |
| |
| def post_process(self, interface_prefix, c_namespace): |
| if len(self.doc_string) == 0: |
| self.doc_string = utils.lookup_docs(self.annotations) |
| if len(self.doc_string_brief) == 0: |
| self.doc_string_brief = utils.lookup_brief_docs(self.annotations) |
| if len(self.since) == 0: |
| self.since = utils.lookup_since(self.annotations) |
| |
| if len(c_namespace) > 0: |
| if utils.is_ugly_case(c_namespace): |
| cns = c_namespace.replace("_", "") |
| cns_upper = c_namespace.upper() + "_" |
| cns_lower = c_namespace.lower() + "_" |
| else: |
| cns = c_namespace |
| cns_upper = utils.camel_case_to_uscore(c_namespace).upper() + "_" |
| cns_lower = utils.camel_case_to_uscore(c_namespace).lower() + "_" |
| else: |
| cns = "" |
| cns_upper = "" |
| cns_lower = "" |
| |
| overridden_name = utils.lookup_annotation( |
| self.annotations, "org.gtk.GDBus.C.Name" |
| ) |
| if utils.is_ugly_case(overridden_name): |
| name = overridden_name.replace("_", "") |
| name_with_ns = cns + name |
| self.name_without_prefix = name |
| self.camel_name = name_with_ns |
| self.ns_upper = cns_upper |
| self.name_lower = cns_lower + overridden_name.lower() |
| self.name_upper = overridden_name.upper() |
| |
| # print_error('handle Ugly_Case "{}"'.format(overridden_name)) |
| else: |
| if overridden_name: |
| name = overridden_name |
| else: |
| name = self.name |
| if name.startswith(interface_prefix): |
| name = name[len(interface_prefix) :] |
| self.name_without_prefix = name |
| name = utils.strip_dots(name) |
| name_with_ns = utils.strip_dots(cns + "." + name) |
| self.camel_name = name_with_ns |
| self.ns_upper = cns_upper |
| self.name_lower = cns_lower + utils.camel_case_to_uscore(name) |
| self.name_upper = utils.camel_case_to_uscore(name).upper() |
| |
| self.name_hyphen = self.name_upper.lower().replace("_", "-") |
| |
| if ( |
| utils.lookup_annotation(self.annotations, "org.freedesktop.DBus.Deprecated") |
| == "true" |
| ): |
| self.deprecated = True |
| |
| for m in self.methods: |
| m.post_process(interface_prefix, cns, cns_upper, cns_lower, self) |
| |
| for s in self.signals: |
| s.post_process(interface_prefix, cns, cns_upper, cns_lower, self) |
| |
| for p in self.properties: |
| p.post_process(interface_prefix, cns, cns_upper, cns_lower, self) |
| |
| for a in self.annotations: |
| a.post_process(interface_prefix, cns, cns_upper, cns_lower, self) |