diff options
author | Olli Salli <olli.salli@collabora.co.uk> | 2008-05-23 16:32:02 +0000 |
---|---|---|
committer | Olli Salli <olli.salli@collabora.co.uk> | 2008-05-23 16:32:02 +0000 |
commit | 66ef4cf859fb6c3ea0fe4325941d51f051709208 (patch) | |
tree | bdf23e68ec1405293e28d208a6f33950ebae382f /tools/libtpcodegen.py | |
parent | b64accc21e6043925b971b82e1760f37a3e57c50 (diff) | |
download | telepathy-glib-66ef4cf859fb6c3ea0fe4325941d51f051709208.tar.gz |
Split libtpcodegen.py from libglibcodegen.py
20080523163202-9db4d-2d2b8ebce0013446abee69a8cbf36a2cad8f2221.gz
Diffstat (limited to 'tools/libtpcodegen.py')
-rw-r--r-- | tools/libtpcodegen.py | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/tools/libtpcodegen.py b/tools/libtpcodegen.py new file mode 100644 index 000000000..624308383 --- /dev/null +++ b/tools/libtpcodegen.py @@ -0,0 +1,182 @@ +"""Library code for language-independent D-Bus-related code generation. + +The master copy of this library is in the telepathy-glib repository - +please make any changes there. +""" + +# Copyright (C) 2006-2008 Collabora Limited +# +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +from string import ascii_letters, digits + + +NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" + +_ASCII_ALNUM = ascii_letters + digits + + +def camelcase_to_lower(s): + out =""; + out += s[0].lower() + last_upper=False + if s[0].isupper(): + last_upper=True + for i in range(1,len(s)): + if s[i].isupper(): + if last_upper: + if (i+1) < len(s) and s[i+1].islower(): + out += "_" + s[i].lower() + else: + out += s[i].lower() + else: + out += "_" + s[i].lower() + last_upper=True + else: + out += s[i] + last_upper=False + return out + + +def camelcase_to_upper(s): + return camelcase_to_lower(s).upper() + + +def cmp_by_name(node1, node2): + return cmp(node1.getAttributeNode("name").nodeValue, + node2.getAttributeNode("name").nodeValue) + + +def escape_as_identifier(identifier): + """Escape the given string to be a valid D-Bus object path or service + name component, using a reversible encoding to ensure uniqueness. + + The reversible encoding is as follows: + + * The empty string becomes '_' + * Otherwise, each non-alphanumeric character is replaced by '_' plus + two lower-case hex digits; the same replacement is carried out on + the first character, if it's a digit + """ + # '' -> '_' + if not identifier: + return '_' + + # A bit of a fast path for strings which are already OK. + # We deliberately omit '_' because, for reversibility, that must also + # be escaped. + if (identifier.strip(_ASCII_ALNUM) == '' and + identifier[0] in ascii_letters): + return identifier + + # The first character may not be a digit + if identifier[0] not in ascii_letters: + ret = ['_%02x' % ord(identifier[0])] + else: + ret = [identifier[0]] + + # Subsequent characters may be digits or ASCII letters + for c in identifier[1:]: + if c in _ASCII_ALNUM: + ret.append(c) + else: + ret.append('_%02x' % ord(c)) + + return ''.join(ret) + + +def get_docstring(element): + docstring = None + for x in element.childNodes: + if x.namespaceURI == NS_TP and x.localName == 'docstring': + docstring = x + if docstring is not None: + docstring = docstring.toxml().replace('\n', ' ').strip() + if docstring.startswith('<tp:docstring>'): + docstring = docstring[14:].lstrip() + if docstring.endswith('</tp:docstring>'): + docstring = docstring[:-15].rstrip() + if docstring in ('<tp:docstring/>', ''): + docstring = '' + return docstring + + +class _SignatureIter: + """Iterator over a D-Bus signature. Copied from dbus-python 0.71 so we + can run genginterface in a limited environment with only Python + (like Scratchbox). + """ + def __init__(self, string): + self.remaining = string + + def next(self): + if self.remaining == '': + raise StopIteration + + signature = self.remaining + block_depth = 0 + block_type = None + end = len(signature) + + for marker in range(0, end): + cur_sig = signature[marker] + + if cur_sig == 'a': + pass + elif cur_sig == '{' or cur_sig == '(': + if block_type == None: + block_type = cur_sig + + if block_type == cur_sig: + block_depth = block_depth + 1 + + elif cur_sig == '}': + if block_type == '{': + block_depth = block_depth - 1 + + if block_depth == 0: + end = marker + break + + elif cur_sig == ')': + if block_type == '(': + block_depth = block_depth - 1 + + if block_depth == 0: + end = marker + break + + else: + if block_depth == 0: + end = marker + break + + end = end + 1 + self.remaining = signature[end:] + return Signature(signature[0:end]) + + +class Signature(str): + """A string, iteration over which is by D-Bus single complete types + rather than characters. + """ + def __iter__(self): + return _SignatureIter(self) + + +def xml_escape(s): + s = s.replace('&', '&').replace("'", ''').replace('"', '"') + return s.replace('<', '<').replace('>', '>') |