Example #1
0
    def translate_struct(self, struct):
        def gen_member(member, padder):
            def build_annotation(member):
                if member.size:
                    if member.bound:
                        annotation = 'limited array, size in {}'.format(
                            member.bound)
                    else:
                        annotation = ''
                else:
                    if member.bound:
                        annotation = 'dynamic array, size in {}'.format(
                            member.bound)
                    else:
                        annotation = 'greedy array'
                return annotation

            typename = primitive_types.get(member.type_name, member.type_name)
            if member.is_array:
                annotation = build_annotation(member)
                size = member.size or 1
                if annotation:
                    field = '{0} {1}[{2}]; /// {3}\n'.format(
                        typename, member.name, size, annotation)
                else:
                    field = '{0} {1}[{2}];\n'.format(typename, member.name,
                                                     size)
            else:
                field = '{0} {1};\n'.format(typename, member.name)
            if member.optional:
                field = 'prophy::bool_t has_{0};\n'.format(member.name) + field
            if member.padding is not None and member.padding > 0:
                field += padder.generate_padding(member.padding)
            return field

        def gen_block(members, padder):
            generated = (gen_member(member, padder) for member in members)
            return _indent(''.join(generated), 4)

        def gen_part(index, part, padder):

            generated = STRUCT_DEF_PART_TEMPLATE.format(
                index=index + 2,
                block=gen_block(part, padder),
                align=part[0].alignment)
            return _indent(generated, 4)

        main, parts = model.partition(struct.members)
        padder = _Padder()
        blocks = '\n'.join([gen_block(main, padder)] + [
            gen_part(index, part, padder) for index, part in enumerate(parts)
        ])

        return STRUCT_DEF_TEMPLATE.format(align=struct.alignment,
                                          name=struct.name,
                                          blocks=blocks)
Example #2
0
def _generate_def_struct(struct):
    def gen_member(member, padder):
        def build_annotation(member):
            if member.size:
                if member.bound:
                    annotation = 'limited array, size in {}'.format(
                        member.bound)
                else:
                    annotation = ''
            else:
                if member.bound:
                    annotation = 'dynamic array, size in {}'.format(
                        member.bound)
                else:
                    annotation = 'greedy array'
            return annotation

        typename = primitive_types.get(member.type_, member.type_)
        if member.array:
            annotation = build_annotation(member)
            size = member.size or 1
            if annotation:
                field = '{0} {1}[{2}]; /// {3}\n'.format(
                    typename, member.name, size, annotation)
            else:
                field = '{0} {1}[{2}];\n'.format(typename, member.name, size)
        else:
            field = '{0} {1};\n'.format(typename, member.name)
        if member.optional:
            field = 'prophy::bool_t has_{0};\n'.format(member.name) + field
        if member.padding > 0:
            field += padder.generate_padding(member.padding)
        return field

    def gen_block(members, padder):
        generated = (gen_member(member, padder) for member in members)
        return _indent(''.join(generated), 4)

    def gen_part(index, part, padder):
        generated = 'PROPHY_STRUCT({2}) part{0}\n{{\n{1}}} _{0};\n'.format(
            index + 2, gen_block(part, padder), part[0].alignment)
        return _indent(generated, 4)

    main, parts = model.partition(struct.members)
    padder = _Padder()
    blocks = (
        [gen_block(main, padder)] +
        [gen_part(index, part, padder) for index, part in enumerate(parts)])
    return 'PROPHY_STRUCT(%s) %s\n{\n%s};' % (struct.alignment, struct.name,
                                              '\n'.join(blocks))
Example #3
0
def test_partition_fixed():
    nodes = [
        model.Struct("Fixed", [
            model.StructMember("a", "u8"),
            model.StructMember("b", "u8"),
            model.StructMember("c", "u8")
        ])
    ]

    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)
    main, parts = model.partition(nodes[0].members)

    assert [x.name for x in main] == ["a", "b", "c"]
    assert [[x.name for x in part] for part in parts] == []
Example #4
0
def test_partition_fixed():
    nodes = [
        model.Struct("Fixed", [
            model.StructMember("a", "u8"),
            model.StructMember("b", "u8"),
            model.StructMember("c", "u8")
        ])
    ]

    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)
    main, parts = model.partition(nodes[0].members)

    assert [x.name for x in main] == ["a", "b", "c"]
    assert [[x.name for x in part] for part in parts] == []
Example #5
0
def test_partition_many_arrays_mixed():
    nodes = [
        model.Struct("ManyArraysMixed", [
            model.StructMember("num_of_a", "u8"),
            model.StructMember("num_of_b", "u8"),
            model.StructMember("a", "u8", bound = "num_of_a"),
            model.StructMember("b", "u8", bound = "num_of_b")
        ]),
    ]

    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)
    main, parts = model.partition(nodes[0].members)

    assert [x.name for x in main] == ["num_of_a", "num_of_b", "a"]
    assert [[x.name for x in part] for part in parts] == [["b"]]
Example #6
0
def test_partition_many_arrays_mixed():
    nodes = [
        model.Struct("ManyArraysMixed", [
            model.StructMember("num_of_a", "u8"),
            model.StructMember("num_of_b", "u8"),
            model.StructMember("a", "u8", bound = "num_of_a"),
            model.StructMember("b", "u8", bound = "num_of_b")
        ]),
    ]

    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)
    main, parts = model.partition(nodes[0].members)

    assert [x.name for x in main] == ["num_of_a", "num_of_b", "a"]
    assert [[x.name for x in part] for part in parts] == [["b"]]
Example #7
0
def test_partition_many_dynamic_structs():
    nodes = [
        model.Struct("Dynamic", [
            model.StructMember("num_of_a", "u8"),
            model.StructMember("a", "u8", bound = "num_of_a")
        ]),
        model.Struct("X", [
            model.StructMember("a", "Dynamic"),
            model.StructMember("b", "Dynamic"),
            model.StructMember("c", "Dynamic")
        ])
    ]

    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)
    main, parts = model.partition(nodes[1].members)

    assert [x.name for x in main] == ["a"]
    assert [[x.name for x in part] for part in parts] == [["b"], ["c"]]
Example #8
0
def test_partition_many_dynamic_structs():
    nodes = [
        model.Struct("Dynamic", [
            model.StructMember("num_of_a", "u8"),
            model.StructMember("a", "u8", bound = "num_of_a")
        ]),
        model.Struct("X", [
            model.StructMember("a", "Dynamic"),
            model.StructMember("b", "Dynamic"),
            model.StructMember("c", "Dynamic")
        ])
    ]

    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)
    main, parts = model.partition(nodes[1].members)

    assert [x.name for x in main] == ["a"]
    assert [[x.name for x in part] for part in parts] == [["b"], ["c"]]
Example #9
0
File: cpp.py Project: cislaa/prophy
def _generate_def_struct(struct):
    def gen_member(member):
        def build_annotation(member):
            if member.size:
                if member.bound:
                    annotation = 'limited array, size in {}'.format(member.bound)
                else:
                    annotation = ''
            else:
                if member.bound:
                    annotation = 'dynamic array, size in {}'.format(member.bound)
                else:
                    annotation = 'greedy array'
            return annotation

        typename = primitive_types.get(member.type_, member.type_)
        if member.array:
            annotation = build_annotation(member)
            size = member.size or 1
            if annotation:
                field = '{0} {1}[{2}]; /// {3}\n'.format(typename, member.name, size, annotation)
            else:
                field = '{0} {1}[{2}];\n'.format(typename, member.name, size)
        else:
            field = '{0} {1};\n'.format(typename, member.name)
        if member.optional:
            return 'prophy::bool_t has_{0};\n'.format(member.name) + field
        return field

    def gen_part(i, part):
        generated = 'struct part{0}\n{{\n{1}}} _{0};'.format(
            i + 2,
            _indent(''.join(map(gen_member, part)), 4)
        )
        return _indent(generated, 4)

    main, parts = model.partition(struct.members)
    generated = _indent(''.join(map(gen_member, main)), 4)
    if parts:
        generated += '\n' + '\n\n'.join(map(gen_part, range(len(parts)), parts)) + '\n'

    return 'struct {}\n{{\n{}}};'.format(struct.name, generated)
Example #10
0
File: cpp.py Project: cislaa/prophy
def _generate_swap_struct(struct):
    def gen_member(member, delimiters = []):
        if member.array:
            is_dynamic = member.kind == model.Kind.DYNAMIC
            swap_mode = 'dynamic' if is_dynamic else 'fixed'
            if member.bound:
                bound = member.bound
                if member.bound not in delimiters:
                    bound = 'payload->' + bound
                return 'swap_n_{0}({1}, {2})'.format(
                    swap_mode, _member_access_statement(member), bound)
            elif not member.bound and member.size:
                return 'swap_n_{0}({1}, {2})'.format(
                    swap_mode, _member_access_statement(member), member.size)
        else:
            if member.optional:
                preamble = 'swap(&payload->has_{0});\nif (payload->has_{0}) '.format(member.name)
            else:
                preamble = ''
            return preamble + 'swap({0})'.format(_member_access_statement(member))

    def gen_last_member(name, last_mem, delimiters = []):
        if last_mem.kind == model.Kind.UNLIMITED or last_mem.greedy:
            return 'return cast<{0}*>({1});\n'.format(
                name,
                _member_access_statement(last_mem)
            )
        elif last_mem.kind == model.Kind.DYNAMIC or last_mem.dynamic:
            return 'return cast<{0}*>({1});\n'.format(
                name,
                gen_member(last_mem, delimiters)
            )
        else:
            return gen_member(last_mem) + ';\n' + 'return payload + 1;\n'

    def gen_main(main, parts):
        all_names = {mem.name: 'payload' for mem in main}
        for i, part in enumerate(parts):
            all_names.update({mem.name: 'part{0}'.format(i + 2) for mem in part})

        def get_missing(part_number):
            part = parts[part_number]
            names = [mem.name for mem in part]
            return [(all_names[mem.bound], mem.bound)
                    for mem in part
                    if mem.bound and mem.bound not in names]

        def gen_missing(part_number):
            return ''.join(', {0}->{1}'.format(x[0], x[1]) for x in get_missing(part_number))

        members = ''.join(gen_member(mem) + ';\n' for mem in main[:-1])
        if parts:
            for i, part in enumerate(parts):
                members += '{0}::part{1}* part{1} = cast<{0}::part{1}*>({2});\n'.format(
                    struct.name,
                    i + 2,
                    'swap(part{0}{1})'.format(i + 1, gen_missing(i - 1)) if i else gen_member(main[-1])
                )
            members += 'return cast<{0}*>(swap(part{1}{2}));\n'.format(struct.name, i + 2, gen_missing(i))
        elif main:
            members += gen_last_member(struct.name, main[-1])
        else:
            members += 'return payload + 1;\n'
        return ('template <>\n'
                '{0}* swap<{0}>({0}* payload)\n'
                '{{\n'
                '{1}'
                '}}\n').format(struct.name, _indent(members, 4))

    def gen_part(part_number, part):
        names = [mem.name for mem in part]
        delimiters = [mem.bound for mem in part if mem.bound and mem.bound not in names]
        members = ''.join(gen_member(mem, delimiters) + ';\n' for mem in part[:-1])
        members += gen_last_member(struct.name + '::part{0}'.format(part_number), part[-1], delimiters)
        return ('inline {0}::part{1}* swap({0}::part{1}* payload{3})\n'
                '{{\n'
                '{2}}}\n').format(struct.name,
                                  part_number,
                                  _indent(members, 4),
                                  ''.join(', size_t {0}'.format(x) for x in delimiters))

    main, parts = model.partition(struct.members)
    return '\n'.join([gen_part(i + 2, part) for i, part in enumerate(parts)] +
                     [gen_main(main, parts)])
Example #11
0
def _generate_swap_struct(struct):
    def gen_member(member, delimiters=[]):
        if member.array:
            is_dynamic = member.kind == model.Kind.DYNAMIC
            swap_mode = 'dynamic' if is_dynamic else 'fixed'
            if member.bound:
                bound = member.bound
                if member.bound not in delimiters:
                    bound = 'payload->' + bound
                return 'swap_n_{0}({1}, {2})'.format(
                    swap_mode, _member_access_statement(member), bound)
            elif not member.bound and member.size:
                return 'swap_n_{0}({1}, {2})'.format(
                    swap_mode, _member_access_statement(member), member.size)
        else:
            if member.optional:
                preamble = 'swap(&payload->has_{0});\nif (payload->has_{0}) '.format(
                    member.name)
            else:
                preamble = ''
            return preamble + 'swap({0})'.format(
                _member_access_statement(member))

    def gen_last_member(name, last_mem, delimiters=[]):
        if last_mem.kind == model.Kind.UNLIMITED or last_mem.greedy:
            return 'return cast<{0}*>({1});\n'.format(
                name, _member_access_statement(last_mem))
        elif last_mem.kind == model.Kind.DYNAMIC or last_mem.dynamic:
            return 'return cast<{0}*>({1});\n'.format(
                name, gen_member(last_mem, delimiters))
        else:
            return gen_member(last_mem) + ';\n' + 'return payload + 1;\n'

    def gen_main(main, parts):
        all_names = {mem.name: 'payload' for mem in main}
        for i, part in enumerate(parts):
            all_names.update(
                {mem.name: 'part{0}'.format(i + 2)
                 for mem in part})

        def get_missing(part_number):
            part = parts[part_number]
            names = [mem.name for mem in part]
            return [(all_names[mem.bound], mem.bound) for mem in part
                    if mem.bound and mem.bound not in names]

        def gen_missing(part_number):
            return ''.join(', {0}->{1}'.format(x[0], x[1])
                           for x in get_missing(part_number))

        members = ''.join(gen_member(mem) + ';\n' for mem in main[:-1])
        if parts:
            for i, part in enumerate(parts):
                members += '{0}::part{1}* part{1} = cast<{0}::part{1}*>({2});\n'.format(
                    struct.name, i + 2,
                    'swap(part{0}{1})'.format(i + 1, gen_missing(i - 1))
                    if i else gen_member(main[-1]))
            members += 'return cast<{0}*>(swap(part{1}{2}));\n'.format(
                struct.name, i + 2, gen_missing(i))
        elif main:
            members += gen_last_member(struct.name, main[-1])
        else:
            members += 'return payload + 1;\n'
        return ('template <>\n'
                '{0}* swap<{0}>({0}* payload)\n'
                '{{\n'
                '{1}'
                '}}\n').format(struct.name, _indent(members, 4))

    def gen_part(part_number, part):
        names = [mem.name for mem in part]
        delimiters = [
            mem.bound for mem in part if mem.bound and mem.bound not in names
        ]
        members = ''.join(
            gen_member(mem, delimiters) + ';\n' for mem in part[:-1])
        members += gen_last_member(
            struct.name + '::part{0}'.format(part_number), part[-1],
            delimiters)
        return ('inline {0}::part{1}* swap({0}::part{1}* payload{3})\n'
                '{{\n'
                '{2}}}\n').format(
                    struct.name, part_number, _indent(members, 4),
                    ''.join(', size_t {0}'.format(x) for x in delimiters))

    main, parts = model.partition(struct.members)
    return '\n'.join([gen_part(i + 2, part) for i, part in enumerate(parts)] +
                     [gen_main(main, parts)])