Beispiel #1
0
    def findUniqueChild(self, tag):
        """Returns the single child with the given nodeName.

        Raises Error if there is no such child or there is more than
        one."""
        seq = self.findAllChildren(tag)
        try:
            node = seq.next()
        except StopIteration:
            raise Error('No child found where one was expected', tag)
        for it in seq:
            raise Error('Many children found where only one was expected', tag)
        return node
Beispiel #2
0
    def __find(self, xpath):
        retries = [xpath.split('/')]
        while retries:
            tags, elts, roots = retries.pop(), self.nodes, (self.base.root, )
            for selector in tags:
                tag, attrs = _parseXPath(selector)
                elts = tuple(
                    _iterateEach(e.findAllChildren(tag, attrs) for e in elts))
                if not elts:
                    break

            else:  # Found matching elements
                # Possibly filter elts to prefer the least drafty ?
                for elt in elts:
                    yield elt

            # Process roots separately: otherwise the alias-processing
            # is excessive.
            for i, selector in enumerate(tags):
                tag, attrs = _parseXPath(selector)

                for alias in tuple(
                        _iterateEach(
                            r.findAllChildren('alias', allDull=True)
                            for r in roots)):
                    if alias.dom.attributes['source'].nodeValue == 'locale':
                        replace = alias.dom.attributes['path'].nodeValue.split(
                            '/')
                        retries.append(
                            self.__xpathJoin(tags[:i], replace, tags[i:]))

                roots = tuple(
                    _iterateEach(r.findAllChildren(tag, attrs) for r in roots))
                if not roots:
                    if retries:  # Let outer loop fall back on an alias path:
                        break
                    sought = '/'.join(tags)
                    if sought != xpath:
                        sought += f' (for {xpath})'
                    raise Error(
                        f'All lack child {selector} for {sought} in {self.name}'
                    )

            else:  # Found matching elements
                for elt in roots:
                    yield elt

        sought = '/'.join(tags)
        if sought != xpath:
            sought += f' (for {xpath})'
        raise Error(f'No {sought} in {self.name}')
Beispiel #3
0
    def __enum(self, name, book, alias, suffix=None):
        assert book

        if suffix is None:
            suffix = name

        out, dupes = self.writer.write, self.__dupes
        out('    enum {} : ushort {{\n'.format(name))
        for key, value in book.items():
            member = value[0].replace('-', ' ')
            if name == 'Script':
                # Don't .capitalize() as some names are already camel-case (see enumdata.py):
                member = ''.join(word[0].upper() + word[1:]
                                 for word in member.split())
                if not member.endswith('Script'):
                    member += 'Script'
                if member in dupes:
                    raise Error('The script name "{}" is messy'.format(member))
            else:
                member = ''.join(member.split())
                member = member + suffix if member in dupes else member
            out('        {} = {},\n'.format(member, key))

        out('\n        ' +
            ',\n        '.join('{} = {}'.format(*pair)
                               for pair in sorted(alias.items())) +
            ',\n\n        Last{} = {}'.format(suffix, member))

        # for "LastCountry = LastTerritory"
        # ### Qt 7: Remove
        if suffix != name:
            out(',\n        Last{} = Last{}'.format(name, suffix))

        out('\n    };\n')
Beispiel #4
0
    def tagCodes(self):
        """Yields four tag codes

        The tag codes are language, script, country and variant; an
        empty value for any of them indicates that no value was
        provided.  The values are obtained from the primary file's
        top-level <identity> element.  An Error is raised if any
        top-level <alias> element of this file has a non-empty source
        attribute; that attribute value is mentioned in the error's
        message."""
        root = self.nodes[0]
        for alias in root.findAllChildren('alias', allDull=True):
            try:
                source = alias.dom.attributes['source'].nodeValue
            except (KeyError, AttributeError):
                pass
            else:
                raise Error('Alias to {}'.format(source))

        ids = root.findUniqueChild('identity')
        for code in ('language', 'script', 'territory', 'variant'):
            for node in ids.findAllChildren(code, allDull=True):
                try:
                    yield node.dom.attributes['type'].nodeValue
                except (KeyError, AttributeError):
                    pass
                else:
                    break # only want one value for each code
            else: # No value for this code, use empty
                yield ''
Beispiel #5
0
    def __enum(self, name, book, alias, suffix=None):
        assert book

        if suffix is None:
            suffix = name

        out, dupes = self.writer.write, self.__dupes
        out(f'    enum {name} : ushort {{\n')
        for key, value in book.items():
            member = value[0].replace('-', ' ')
            if name == 'Script':
                # Don't .capitalize() as some names are already camel-case (see enumdata.py):
                member = ''.join(word[0].upper() + word[1:]
                                 for word in member.split())
                if not member.endswith('Script'):
                    member += 'Script'
                if member in dupes:
                    raise Error(f'The script name "{member}" is messy')
            else:
                member = ''.join(member.split())
                member = member + suffix if member in dupes else member
            out(f'        {member} = {key},\n')

        out('\n        ' +
            ',\n        '.join(f'{k} = {v}'
                               for k, v in sorted(alias.items())) +
            f',\n\n        Last{suffix} = {member}')

        # for "LastCountry = LastTerritory"
        # ### Qt 7: Remove
        if suffix != name:
            out(f',\n        Last{name} = Last{suffix}')

        out('\n    };\n')
Beispiel #6
0
    def __firstChildElt(cls, parent, name):
        child = parent.firstChild
        while child:
            if cls.__isNodeNamed(child, name):
                return child
            child = child.nextSibling

        raise Error('No {} child found'.format(name))
    def append(self, s):
        if s in self.hash:
            return self.hash[s]

        lst = unicode2hex(s)
        index = len(self.data)
        if index > 0xffff:
            raise Error('Data index {} is too big for uint16!'.format(index))
        size = len(lst)
        if size >= 0xffff:
            raise Error('Data is too big ({}) for uint16 size!'.format(size))
        token = None
        try:
            token = StringDataToken(index, size)
        except Error as e:
            e.message += '(on data "{}")'.format(s)
            raise
        self.hash[s] = token
        self.data += lst
        return token
Beispiel #8
0
    def append(self, s):
        s = s + '\0'
        if s in self.hash:
            return self.hash[s]

        lst = unicode2hex(s)
        index = len(self.data)
        if index > 0xffff:
            raise Error('Index ({}) outside the uint16 range !'.format(index))
        self.hash[s] = index
        self.data += lst
        return index
Beispiel #9
0
    def __enum(self, name, book, alias):
        assert book
        out, dupes = self.writer.write, self.__dupes
        out('    enum {} : ushort {{\n'.format(name))
        for key, value in book.items():
            member = value[0]
            if name == 'Script':
                # Don't .capitalize() as some names are already camel-case (see enumdata.py):
                member = ''.join(word[0].upper() + word[1:] for word in member.split())
                if not member.endswith('Script'):
                    member += 'Script'
                if member in dupes:
                    raise Error('The script name "{}" is messy'.format(member))
            else:
                member = ''.join(member.split())
                member = member + name if member in dupes else member
            out('        {} = {},\n'.format(member, key))

        out('\n        '
            + ',\n        '.join('{} = {}'.format(*pair)
                                 for pair in sorted(alias.items()))
            + ',\n\n        Last{} = {}\n    }};\n'.format(name, member))
 def __init__(self, index, length):
     if index > 0xFFFF or length > 0xFFFF:
         raise Error("Position exceeds ushort range: {},{}".format(
             index, length))
     self.index = index
     self.length = length
Beispiel #11
0
def ordStr(c):
    if len(c) == 1:
        return str(ord(c))
    raise Error('Unable to handle value "{}"'.format(addEscapes(c)))
Beispiel #12
0
 def __complain(text):
     raise Error('Attempted to write data after closing :-(')