]> git.0d.be Git - empathy.git/blob - tools/libglibcodegen.py
Merge branch 'tp-tube'
[empathy.git] / tools / libglibcodegen.py
1 """Library code for GLib/D-Bus-related code generation.
2
3 The master copy of this library is in the telepathy-glib repository -
4 please make any changes there.
5 """
6
7 # Copyright (C) 2006-2008 Collabora Limited
8 #
9 # This library is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU Lesser General Public
11 # License as published by the Free Software Foundation; either
12 # version 2.1 of the License, or (at your option) any later version.
13 #
14 # This library is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 # Lesser General Public License for more details.
18 #
19 # You should have received a copy of the GNU Lesser General Public
20 # License along with this library; if not, write to the Free Software
21 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22
23
24 from libtpcodegen import NS_TP, \
25                          Signature, \
26                          camelcase_to_lower, \
27                          camelcase_to_upper, \
28                          cmp_by_name, \
29                          escape_as_identifier, \
30                          get_by_path, \
31                          get_descendant_text, \
32                          get_docstring, \
33                          xml_escape
34
35 def dbus_gutils_wincaps_to_uscore(s):
36     """Bug-for-bug compatible Python port of _dbus_gutils_wincaps_to_uscore
37     which gets sequences of capital letters wrong in the same way.
38     (e.g. in Telepathy, SendDTMF -> send_dt_mf)
39     """
40     ret = ''
41     for c in s:
42         if c >= 'A' and c <= 'Z':
43             length = len(ret)
44             if length > 0 and (length < 2 or ret[length-2] != '_'):
45                 ret += '_'
46             ret += c.lower()
47         else:
48             ret += c
49     return ret
50
51
52 def signal_to_marshal_type(signal):
53     """
54     return a list of strings indicating the marshalling type for this signal.
55     """
56
57     mtype=[]
58     for i in signal.getElementsByTagName("arg"):
59         name =i.getAttribute("name")
60         type = i.getAttribute("type")
61         mtype.append(type_to_gtype(type)[2])
62
63     return mtype
64
65
66 _glib_marshallers = ['VOID', 'BOOLEAN', 'CHAR', 'UCHAR', 'INT',
67         'STRING', 'UINT', 'LONG', 'ULONG', 'ENUM', 'FLAGS', 'FLOAT',
68         'DOUBLE', 'STRING', 'PARAM', 'BOXED', 'POINTER', 'OBJECT',
69         'UINT_POINTER']
70
71
72 def signal_to_marshal_name(signal, prefix):
73
74     mtype = signal_to_marshal_type(signal)
75     if len(mtype):
76         name = '_'.join(mtype)
77     else:
78         name = 'VOID'
79
80     if name in _glib_marshallers:
81         return 'g_cclosure_marshal_VOID__' + name
82     else:
83         return prefix + '_marshal_VOID__' + name
84
85
86 def method_to_glue_marshal_name(method, prefix):
87
88     mtype = []
89     for i in method.getElementsByTagName("arg"):
90         if i.getAttribute("direction") != "out":
91             type = i.getAttribute("type")
92             mtype.append(type_to_gtype(type)[2])
93
94     mtype.append('POINTER')
95
96     name = '_'.join(mtype)
97
98     if name in _glib_marshallers:
99         return 'g_cclosure_marshal_VOID__' + name
100     else:
101         return prefix + '_marshal_VOID__' + name
102
103
104 def type_to_gtype(s):
105     if s == 'y': #byte
106         return ("guchar ", "G_TYPE_UCHAR","UCHAR", False)
107     elif s == 'b': #boolean
108         return ("gboolean ", "G_TYPE_BOOLEAN","BOOLEAN", False)
109     elif s == 'n': #int16
110         return ("gint ", "G_TYPE_INT","INT", False)
111     elif s == 'q': #uint16
112         return ("guint ", "G_TYPE_UINT","UINT", False)
113     elif s == 'i': #int32
114         return ("gint ", "G_TYPE_INT","INT", False)
115     elif s == 'u': #uint32
116         return ("guint ", "G_TYPE_UINT","UINT", False)
117     elif s == 'x': #int64
118         return ("gint64 ", "G_TYPE_INT64","INT64", False)
119     elif s == 't': #uint64
120         return ("guint64 ", "G_TYPE_UINT64","UINT64", False)
121     elif s == 'd': #double
122         return ("gdouble ", "G_TYPE_DOUBLE","DOUBLE", False)
123     elif s == 's': #string
124         return ("gchar *", "G_TYPE_STRING", "STRING", True)
125     elif s == 'g': #signature - FIXME
126         return ("gchar *", "DBUS_TYPE_G_SIGNATURE", "STRING", True)
127     elif s == 'o': #object path
128         return ("gchar *", "DBUS_TYPE_G_OBJECT_PATH", "BOXED", True)
129     elif s == 'v':  #variant
130         return ("GValue *", "G_TYPE_VALUE", "BOXED", True)
131     elif s == 'as':  #array of strings
132         return ("gchar **", "G_TYPE_STRV", "BOXED", True)
133     elif s == 'ay': #byte array
134         return ("GArray *",
135             "dbus_g_type_get_collection (\"GArray\", G_TYPE_UCHAR)", "BOXED",
136             True)
137     elif s == 'au': #uint array
138         return ("GArray *", "DBUS_TYPE_G_UINT_ARRAY", "BOXED", True)
139     elif s == 'ai': #int array
140         return ("GArray *", "DBUS_TYPE_G_INT_ARRAY", "BOXED", True)
141     elif s == 'ax': #int64 array
142         return ("GArray *", "DBUS_TYPE_G_INT64_ARRAY", "BOXED", True)
143     elif s == 'at': #uint64 array
144         return ("GArray *", "DBUS_TYPE_G_UINT64_ARRAY", "BOXED", True)
145     elif s == 'ad': #double array
146         return ("GArray *", "DBUS_TYPE_G_DOUBLE_ARRAY", "BOXED", True)
147     elif s == 'ab': #boolean array
148         return ("GArray *", "DBUS_TYPE_G_BOOLEAN_ARRAY", "BOXED", True)
149     elif s == 'ao': #object path array
150         return ("GPtrArray *",
151                 'dbus_g_type_get_collection ("GPtrArray",'
152                 ' DBUS_TYPE_G_OBJECT_PATH)',
153                 "BOXED", True)
154     elif s == 'a{ss}': #hash table of string to string
155         return ("GHashTable *", "DBUS_TYPE_G_STRING_STRING_HASHTABLE", "BOXED", False)
156     elif s[:2] == 'a{':  #some arbitrary hash tables
157         if s[2] not in ('y', 'b', 'n', 'q', 'i', 'u', 's', 'o', 'g'):
158             raise Exception, "can't index a hashtable off non-basic type " + s
159         first = type_to_gtype(s[2])
160         second = type_to_gtype(s[3:-1])
161         return ("GHashTable *", "(dbus_g_type_get_map (\"GHashTable\", " + first[1] + ", " + second[1] + "))", "BOXED", False)
162     elif s[:2] in ('a(', 'aa'): # array of structs or arrays, recurse
163         gtype = type_to_gtype(s[1:])[1]
164         return ("GPtrArray *", "(dbus_g_type_get_collection (\"GPtrArray\", "+gtype+"))", "BOXED", True)
165     elif s[:1] == '(': #struct
166         gtype = "(dbus_g_type_get_struct (\"GValueArray\", "
167         for subsig in Signature(s[1:-1]):
168             gtype = gtype + type_to_gtype(subsig)[1] + ", "
169         gtype = gtype + "G_TYPE_INVALID))"
170         return ("GValueArray *", gtype, "BOXED", True)
171
172     # we just don't know ..
173     raise Exception, "don't know the GType for " + s