File indexing completed on 2024-04-21 05:01:51

0001 """Library code for GLib/D-Bus-related code generation.
0002 
0003 The master copy of this library is in the telepathy-glib repository -
0004 please make any changes there.
0005 """
0006 
0007 # Copyright (C) 2006-2008 Collabora Limited
0008 #
0009 # This library is free software; you can redistribute it and/or
0010 # modify it under the terms of the GNU Lesser General Public
0011 # License as published by the Free Software Foundation; either
0012 # version 2.1 of the License, or (at your option) any later version.
0013 #
0014 # This library is distributed in the hope that it will be useful,
0015 # but WITHOUT ANY WARRANTY; without even the implied warranty of
0016 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017 # Lesser General Public License for more details.
0018 #
0019 # You should have received a copy of the GNU Lesser General Public
0020 # License along with this library; if not, write to the Free Software
0021 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
0022 
0023 
0024 from libtpcodegen import NS_TP, \
0025                          Signature, \
0026                          cmp_by_name, \
0027                          escape_as_identifier, \
0028                          get_by_path, \
0029                          get_descendant_text, \
0030                          get_docstring, \
0031                          xml_escape, \
0032                          get_deprecated
0033 
0034 def dbus_gutils_wincaps_to_uscore(s):
0035     """Bug-for-bug compatible Python port of _dbus_gutils_wincaps_to_uscore
0036     which gets sequences of capital letters wrong in the same way.
0037     (e.g. in Telepathy, SendDTMF -> send_dt_mf)
0038     """
0039     ret = ''
0040     for c in s:
0041         if c >= 'A' and c <= 'Z':
0042             length = len(ret)
0043             if length > 0 and (length < 2 or ret[length-2] != '_'):
0044                 ret += '_'
0045             ret += c.lower()
0046         else:
0047             ret += c
0048     return ret
0049 
0050 
0051 def signal_to_marshal_type(signal):
0052     """
0053     return a list of strings indicating the marshalling type for this signal.
0054     """
0055 
0056     mtype=[]
0057     for i in signal.getElementsByTagName("arg"):
0058         name =i.getAttribute("name")
0059         type = i.getAttribute("type")
0060         mtype.append(type_to_gtype(type)[2])
0061 
0062     return mtype
0063 
0064 
0065 _glib_marshallers = ['VOID', 'BOOLEAN', 'CHAR', 'UCHAR', 'INT',
0066         'STRING', 'UINT', 'LONG', 'ULONG', 'ENUM', 'FLAGS', 'FLOAT',
0067         'DOUBLE', 'STRING', 'PARAM', 'BOXED', 'POINTER', 'OBJECT',
0068         'UINT_POINTER']
0069 
0070 
0071 def signal_to_marshal_name(signal, prefix):
0072 
0073     mtype = signal_to_marshal_type(signal)
0074     if len(mtype):
0075         name = '_'.join(mtype)
0076     else:
0077         name = 'VOID'
0078 
0079     if name in _glib_marshallers:
0080         return 'g_cclosure_marshal_VOID__' + name
0081     else:
0082         return prefix + '_marshal_VOID__' + name
0083 
0084 
0085 def method_to_glue_marshal_name(method, prefix):
0086 
0087     mtype = []
0088     for i in method.getElementsByTagName("arg"):
0089         if i.getAttribute("direction") != "out":
0090             type = i.getAttribute("type")
0091             mtype.append(type_to_gtype(type)[2])
0092 
0093     mtype.append('POINTER')
0094 
0095     name = '_'.join(mtype)
0096 
0097     if name in _glib_marshallers:
0098         return 'g_cclosure_marshal_VOID__' + name
0099     else:
0100         return prefix + '_marshal_VOID__' + name
0101 
0102 
0103 def type_to_gtype(s):
0104     if s == 'y': #byte
0105         return ("guchar ", "G_TYPE_UCHAR","UCHAR", False)
0106     elif s == 'b': #boolean
0107         return ("gboolean ", "G_TYPE_BOOLEAN","BOOLEAN", False)
0108     elif s == 'n': #int16
0109         return ("gint ", "G_TYPE_INT","INT", False)
0110     elif s == 'q': #uint16
0111         return ("guint ", "G_TYPE_UINT","UINT", False)
0112     elif s == 'i': #int32
0113         return ("gint ", "G_TYPE_INT","INT", False)
0114     elif s == 'u': #uint32
0115         return ("guint ", "G_TYPE_UINT","UINT", False)
0116     elif s == 'x': #int64
0117         return ("gint64 ", "G_TYPE_INT64","INT64", False)
0118     elif s == 't': #uint64
0119         return ("guint64 ", "G_TYPE_UINT64","UINT64", False)
0120     elif s == 'd': #double
0121         return ("gdouble ", "G_TYPE_DOUBLE","DOUBLE", False)
0122     elif s == 's': #string
0123         return ("gchar *", "G_TYPE_STRING", "STRING", True)
0124     elif s == 'g': #signature - FIXME
0125         return ("gchar *", "DBUS_TYPE_G_SIGNATURE", "STRING", True)
0126     elif s == 'o': #object path
0127         return ("gchar *", "DBUS_TYPE_G_OBJECT_PATH", "BOXED", True)
0128     elif s == 'v':  #variant
0129         return ("GValue *", "G_TYPE_VALUE", "BOXED", True)
0130     elif s == 'as':  #array of strings
0131         return ("gchar **", "G_TYPE_STRV", "BOXED", True)
0132     elif s == 'ay': #byte array
0133         return ("GArray *",
0134             "dbus_g_type_get_collection (\"GArray\", G_TYPE_UCHAR)", "BOXED",
0135             True)
0136     elif s == 'au': #uint array
0137         return ("GArray *", "DBUS_TYPE_G_UINT_ARRAY", "BOXED", True)
0138     elif s == 'ai': #int array
0139         return ("GArray *", "DBUS_TYPE_G_INT_ARRAY", "BOXED", True)
0140     elif s == 'ax': #int64 array
0141         return ("GArray *", "DBUS_TYPE_G_INT64_ARRAY", "BOXED", True)
0142     elif s == 'at': #uint64 array
0143         return ("GArray *", "DBUS_TYPE_G_UINT64_ARRAY", "BOXED", True)
0144     elif s == 'ad': #double array
0145         return ("GArray *", "DBUS_TYPE_G_DOUBLE_ARRAY", "BOXED", True)
0146     elif s == 'ab': #boolean array
0147         return ("GArray *", "DBUS_TYPE_G_BOOLEAN_ARRAY", "BOXED", True)
0148     elif s == 'ao': #object path array
0149         return ("GPtrArray *",
0150                 'dbus_g_type_get_collection ("GPtrArray",'
0151                 ' DBUS_TYPE_G_OBJECT_PATH)',
0152                 "BOXED", True)
0153     elif s == 'a{ss}': #hash table of string to string
0154         return ("GHashTable *", "DBUS_TYPE_G_STRING_STRING_HASHTABLE", "BOXED", False)
0155     elif s[:2] == 'a{':  #some arbitrary hash tables
0156         if s[2] not in ('y', 'b', 'n', 'q', 'i', 'u', 's', 'o', 'g'):
0157             raise Exception("can't index a hashtable off non-basic type " + s)
0158         first = type_to_gtype(s[2])
0159         second = type_to_gtype(s[3:-1])
0160         return ("GHashTable *", "(dbus_g_type_get_map (\"GHashTable\", " + first[1] + ", " + second[1] + "))", "BOXED", False)
0161     elif s[:2] in ('a(', 'aa'): # array of structs or arrays, recurse
0162         gtype = type_to_gtype(s[1:])[1]
0163         return ("GPtrArray *", "(dbus_g_type_get_collection (\"GPtrArray\", "+gtype+"))", "BOXED", True)
0164     elif s[:1] == '(': #struct
0165         gtype = "(dbus_g_type_get_struct (\"GValueArray\", "
0166         for subsig in Signature(s[1:-1]):
0167             gtype = gtype + type_to_gtype(subsig)[1] + ", "
0168         gtype = gtype + "G_TYPE_INVALID))"
0169         return ("GValueArray *", gtype, "BOXED", True)
0170 
0171     # we just don't know ..
0172     raise Exception("don't know the GType for " + s)
0173 
0174 def move_into_gvalue(gvaluep, gtype, marshaller, name):
0175     if gtype == 'G_TYPE_STRING':
0176         return 'g_value_take_string (%s, %s);' % (gvaluep, name)
0177     elif marshaller == 'BOXED':
0178         return 'g_value_take_boxed (%s, %s);' % (gvaluep, name)
0179     elif gtype == 'G_TYPE_UCHAR':
0180         return 'g_value_set_uchar (%s, %s);' % (gvaluep, name)
0181     elif gtype == 'G_TYPE_BOOLEAN':
0182         return 'g_value_set_boolean (%s, %s);' % (gvaluep, name)
0183     elif gtype == 'G_TYPE_INT':
0184         return 'g_value_set_int (%s, %s);' % (gvaluep, name)
0185     elif gtype == 'G_TYPE_UINT':
0186         return 'g_value_set_uint (%s, %s);' % (gvaluep, name)
0187     elif gtype == 'G_TYPE_INT64':
0188         return 'g_value_set_int (%s, %s);' % (gvaluep, name)
0189     elif gtype == 'G_TYPE_UINT64':
0190         return 'g_value_set_uint64 (%s, %s);' % (gvaluep, name)
0191     elif gtype == 'G_TYPE_DOUBLE':
0192         return 'g_value_set_double (%s, %s);' % (gvaluep, name)
0193     else:
0194         raise AssertionError("Don't know how to put %s in a GValue" % gtype)
0195 
0196 def copy_into_gvalue(gvaluep, gtype, marshaller, name):
0197     if gtype == 'G_TYPE_STRING':
0198         return 'g_value_set_string (%s, %s);' % (gvaluep, name)
0199     elif marshaller == 'BOXED':
0200         return 'g_value_set_boxed (%s, %s);' % (gvaluep, name)
0201     elif gtype == 'G_TYPE_UCHAR':
0202         return 'g_value_set_uchar (%s, %s);' % (gvaluep, name)
0203     elif gtype == 'G_TYPE_BOOLEAN':
0204         return 'g_value_set_boolean (%s, %s);' % (gvaluep, name)
0205     elif gtype == 'G_TYPE_INT':
0206         return 'g_value_set_int (%s, %s);' % (gvaluep, name)
0207     elif gtype == 'G_TYPE_UINT':
0208         return 'g_value_set_uint (%s, %s);' % (gvaluep, name)
0209     elif gtype == 'G_TYPE_INT64':
0210         return 'g_value_set_int (%s, %s);' % (gvaluep, name)
0211     elif gtype == 'G_TYPE_UINT64':
0212         return 'g_value_set_uint64 (%s, %s);' % (gvaluep, name)
0213     elif gtype == 'G_TYPE_DOUBLE':
0214         return 'g_value_set_double (%s, %s);' % (gvaluep, name)
0215     else:
0216         raise AssertionError("Don't know how to put %s in a GValue" % gtype)