Пример #1
0
def test_cross_reference_array_size_from_includes():
    nodes = [
        model.Include('x', [
            model.Include('y', [
                model.Constant('NUM_HEX', '0xf'),
                model.Constant('NUM_DEC', '3'),
            ]),
            model.Enum('E', [
                model.EnumMember('E1', 'NUM_HEX'),
                model.EnumMember('E3', 'NUM_DEC'),
            ]),
        ]),
        model.Struct('X', [
            model.StructMember('x', 'u32', size='NUM_DEC'),
            model.StructMember('y', 'u32', size='E1'),
            model.StructMember('z', 'u32', size='UNKNOWN'),
            model.StructMember('a', 'u32', size='E3'),
        ])
    ]

    constants = model.cross_reference(nodes)

    assert nodes[1].members[0].numeric_size == 3
    assert nodes[1].members[1].numeric_size == 15
    assert nodes[1].members[2].numeric_size is None
    assert nodes[1].members[3].numeric_size == 3

    assert constants == {
        'E1': 15,
        'E3': 3,
        'NUM_DEC': 3,
        'NUM_HEX': 15,
    }
Пример #2
0
def test_includes_rendering():
    common_include = model.Include("foo", [
        model.Constant("symbol_1", 1),
        model.Constant("number_12", 12),
    ])
    nodes = [
        common_include,
        model.Include("root/ni_knights", [
            model.Include("../root/rabbit", [
                common_include,
                model.Constant("pi", "3.14159"),
                model.Typedef("definition", "things", "r32", "docstring"),
            ]),
            model.Constant("symbol_2", 2),
        ]),
        model.Include("../root/baz_bar", []),
        model.Include(
            "many/numbers",
            [model.Constant("number_%s" % n, n) for n in reversed(range(20))]),
    ]

    ref = """\
from foo import number_12, symbol_1
from ni_knights import definition, pi, symbol_2
from numbers import (
    number_0, number_1, number_10, number_11, number_13, number_14, number_15,
    number_16, number_17, number_18, number_19, number_2, number_3, number_4,
    number_5, number_6, number_7, number_8, number_9
)
"""
    # call twice to check if 'duplication avoidance' machinery in _PythonTranslator.translate_include works ok
    assert serialize(nodes) == ref
    assert serialize(nodes) == ref
Пример #3
0
def test_cross_reference_array_size_from_includes():
    nodes = [
        model.Include('x', [
            model.Include('y', [
                model.Constant('NUM', '3'),
            ]),
            model.Enum('E', [
                model.EnumMember('E1', '1'),
                model.EnumMember('E3', 'NUM')
            ]),
        ]),
        model.Struct('X', [
            model.StructMember('x', 'u32', size = 'NUM'),
            model.StructMember('y', 'u32', size = 'E1'),
            model.StructMember('z', 'u32', size = 'UNKNOWN'),
            model.StructMember('a', 'u32', size = 'E3')
        ])
    ]

    model.cross_reference(nodes)

    assert nodes[1].members[0].numeric_size == 3
    assert nodes[1].members[1].numeric_size == 1
    assert nodes[1].members[2].numeric_size == None
    assert nodes[1].members[3].numeric_size == 3
Пример #4
0
def test_definitions_includes():
    nodes = process([
        model.Include("szydlo", []),
        model.Include("mydlo", []),
        model.Include("powidlo", [])
    ])
    include_translator = _HppIncludesTranslator()
    assert include_translator(nodes, "") == """\
Пример #5
0
def test_definitions_includes():
    nodes = [
        model.Include("szydlo"),
        model.Include("mydlo"),
        model.Include("powidlo")
    ]

    assert generate_definitions(nodes) == """\
Пример #6
0
def test_definitions_includes():
    nodes = process([
        model.Include("szydlo", []),
        model.Include("mydlo", []),
        model.Include("powidlo", [])
    ])

    assert generate_definitions(nodes) == """\
Пример #7
0
def test_includes_rendering():
    nodes = [
        model.Include("szydlo"),
        model.Include("mydlo"),
        model.Include("powidlo")
    ]

    ref = """\
from szydlo import *
from mydlo import *
from powidlo import *
"""
    assert ref == serialize(nodes)
Пример #8
0
def test_includes_rendering():
    nodes = [
        model.Include("szydlo", []),
        model.Include("root/nowe_mydlo", []),
        model.Include("../root/nowiejsze_powidlo", []),
    ]

    ref = """\
from szydlo import *
from nowe_mydlo import *
from nowiejsze_powidlo import *
"""
    assert ref == serialize(nodes)
Пример #9
0
def test_include_path():
    assert parse('#include "x.prophy"') == [model.Include('x', [])]
    assert parse('#include "noext"') == [model.Include('noext', [])]
    assert parse('#include "102.prophy"') == [model.Include('102', [])]
    assert parse('#include "x/y/z.prophy"') == [model.Include('z', [])]
    assert parse('#include "./x.prophy"') == [model.Include('x', [])]
    assert parse('#include "../x.prophy"') == [model.Include('x', [])]
    assert parse('#include "x.y.z.prophy"') == [model.Include('x.y.z', [])]
    assert parse(' # include  "x.prophy" ') == [model.Include('x', [])]
    assert parse('\n#\ninclude\n"x.prophy"\n') == [model.Include('x', [])]
Пример #10
0
def make_include(elem, process_file, warn):
    path = elem.get("href")
    try:
        nodes = process_file(path)
    except (CyclicIncludeError, FileNotFoundError) as e:
        if warn:
            warn(str(e))
        nodes = []
    return model.Include(os.path.splitext(path)[0], nodes)
Пример #11
0
def make_include(xml_elem, process_file, warn):
    if "include" in xml_elem.tag:
        path = xml_elem.get("href")
        try:
            nodes = process_file(path)
        except (CyclicIncludeError, FileNotFoundError) as e:
            if warn:
                warn(str(e))
            nodes = []
        return model.Include(os.path.splitext(path)[0],
                             nodes,
                             docstring=get_docstr(xml_elem))
Пример #12
0
def test_cross_symbols_from_includes():
    nodes = [
        model.Include('x', [
            model.Include('y', [
                model.Typedef('ala', 'u32')
            ]),
            model.Struct('ola', [
                model.StructMember('a', 'ala'),
            ])
        ]),
        model.Struct('ula', [
            model.StructMember('a', 'ola'),
            model.StructMember('b', 'ala'),
        ])
    ]

    model.cross_reference(nodes)

    assert nodes[1].members[0].definition.name == 'ola'
    assert nodes[1].members[1].definition.name == 'ala'
    # cross-reference only needs to link definitions of first level of nodes
    assert nodes[0].nodes[1].members[0].definition == None
Пример #13
0
def test_cross_reference_quadratic_complexity_include_performance_bug():
    """
    If type and numeric definitions from includes are processed each time,
    compilation times can skyrocket...
    """
    FACTOR = 10

    nodes = [model.Constant('X', 42), model.Typedef('Y', 'u8')] * FACTOR
    for i in range(FACTOR):
        nodes = [model.Include('inc%s' % i, nodes)] * FACTOR
    nodes.append(model.Struct('Z', [model.StructMember('x', 'u8', size='X')]))
    """This line will kill your cpu if cross-referencing algorithm is quadratic"""
    model.cross_reference(nodes)

    assert nodes[-1].members[0].numeric_size == 42
Пример #14
0
def test_evaluate_sizes_with_include():
    nodes = process([
        model.Include('input', [
            model.Enum('E', [
                model.EnumMember('E1', '1')
            ])
        ]),
        model.Struct('X', [
            model.StructMember('x', 'E'),
            model.StructMember('y', 'i8'),
        ])
    ])
    assert list(map(get_size_alignment_padding, get_members_and_node(nodes[1]))) == [
        (4, 4, 0),
        (1, 1, 3),
        (8, 4)
    ]
Пример #15
0
def test_python_translator_1():
    ih = []
    th = []
    for x in range(20, 200, 60):
        ih.append(
            model.Include("test_include_" + str(x),
                          [model.Constant("n_%s" % x, x, "doc")]))
        th.append(
            model.Typedef("td_elem_name_" + str(x), "td_elem_val_" + str(x)))
        th.append(
            model.Typedef("td_elem_name_" + str(x), "i_td_elem_val_" + str(x)))
        th.append(
            model.Typedef("td_elem_name_" + str(x), "u_td_elem_val_" + str(x)))

    enum = []
    for x in range(1, 100, 30):
        enum.append((model.EnumMember("elem_" + str(x), "val_" + str(x))))

    name = "MAC_L2CallConfigResp"
    members = [model.StructMember('messageResult', 'SMessageResult')]
    msg_h = model.Struct(name, members)

    nodes = []
    nodes += ih
    nodes += [
        model.Constant("C_A", "5"),
        model.Constant("C_B", "5"),
        model.Constant("C_C", "C_B + C_A")
    ]
    nodes += th
    nodes += [model.Enum("test", enum)]
    nodes += [msg_h]

    python_translator = _PythonTranslator()
    output = python_translator(nodes, "")

    ref = """\
# -*- encoding: utf-8 -*-
# This file has been generated by prophyc.

import sys

import prophy

if sys.version_info < (3,):
    from test_include_20 import n_20
else:
    from .test_include_20 import n_20
if sys.version_info < (3,):
    from test_include_80 import n_80
else:
    from .test_include_80 import n_80
if sys.version_info < (3,):
    from test_include_140 import n_140
else:
    from .test_include_140 import n_140

C_A = 5
C_B = 5
C_C = C_B + C_A

td_elem_name_20 = td_elem_val_20
td_elem_name_20 = i_td_elem_val_20
td_elem_name_20 = u_td_elem_val_20
td_elem_name_80 = td_elem_val_80
td_elem_name_80 = i_td_elem_val_80
td_elem_name_80 = u_td_elem_val_80
td_elem_name_140 = td_elem_val_140
td_elem_name_140 = i_td_elem_val_140
td_elem_name_140 = u_td_elem_val_140


class test(prophy.with_metaclass(prophy.enum_generator, prophy.enum)):
    _enumerators = [
        ('elem_1', val_1),
        ('elem_31', val_31),
        ('elem_61', val_61),
        ('elem_91', val_91),
    ]


elem_1 = val_1
elem_31 = val_31
elem_61 = val_61
elem_91 = val_91


class MAC_L2CallConfigResp(prophy.with_metaclass(prophy.struct_generator, prophy.struct)):
    _descriptor = [
        ('messageResult', SMessageResult),
    ]
"""
    assert output == ref
Пример #16
0
def test_bad_attribute():
    a = model.Include("this", [])
    expected_message = "Use of value property is forbidden for Include. Use 'Include.members' instead."
    with pytest.raises(model.ModelError, match=expected_message):
        a.value
Пример #17
0
def larger_model(lorem_with_breaks):
    return [
        model.Typedef('a', 'i16'),
        model.Typedef('c', 'a'),
        model.Include('some_defs', [
            model.Struct('IncludedStruct', [
                model.StructMember(
                    'member1', 'r32', docstring='doc for member1'),
                model.StructMember(
                    'member2', 'u64', docstring='docstring for member1')
            ]),
            model.Typedef('c', 'a'),
        ]),
        model.Include('cplx', [
            model.Struct('cint16_t', [
                model.StructMember('re', 'i16', docstring='real'),
                model.StructMember('im', 'i16', docstring='imaginary')
            ]),
            model.Struct('cint32_t', [
                model.StructMember('re', 'i32', docstring='real'),
                model.StructMember('im', 'i32', docstring='imaginary')
            ]),
        ]),
        model.Union('the_union', [
            model.UnionMember('a', 'IncludedStruct', 0),
            model.UnionMember(
                'field_with_a_long_name',
                'cint16_t', 1, docstring="Shorter"),
            model.UnionMember('field_with_a_longer_name',
                              'cint32_t',
                              2,
                              docstring="Longer description"),
            model.UnionMember('other',
                              'i32',
                              4090,
                              docstring='This one has larger discriminator'),
        ], "spec for that union"),
        model.Enum(
            'E1', [
                model.EnumMember('E1_A', '0', 'enum1 constant value A'),
                model.EnumMember('E1_B_has_a_long_name', '1',
                                 'enum1 constant va3lue B'),
                model.EnumMember('E1_C_desc', '2', lorem_with_breaks[:150]),
            ],
            "Enumerator is a model type that is not supposed to be serialized. Its definition represents yet another "
            "syntax variation for typing a constant. Of course elements of it's type are serializable "
            "(as int32)"),
        model.Enum('E2', [
            model.EnumMember('E2_A', '0', "Short\nmultiline\ndoc"),
        ]),
        model.Constant('CONST_A', '6'),
        model.Constant('CONST_B', '0'),
        model.Struct('StructMemberKinds', [
            model.StructMember('member_without_docstring', 'i16'),
            model.StructMember('ext_size',
                               'i16',
                               docstring='arbitrary sizer for dynamic arrays'),
            model.StructMember('optional_element',
                               'cint16_t',
                               optional=True,
                               docstring='optional array'),
            model.StructMember('fixed_array',
                               'cint16_t',
                               size=3,
                               docstring='Array with static size.'),
            model.StructMember('samples',
                               'cint16_t',
                               bound='ext_size',
                               docstring='dynamic (ext.sized) array'),
            model.StructMember('limited_array',
                               'r64',
                               size=4,
                               bound='ext_size',
                               docstring='Has statically '
                               'evaluable maximum size.'),
            model.StructMember('greedy',
                               'cint16_t',
                               greedy=True,
                               docstring='Represents array of arbitrary '
                               'number of elements. Buffer size '
                               'must be multiply of element size.'),
        ], lorem_with_breaks[:400]),
    ]
Пример #18
0
def make_include(elem):
    return model.Include(elem.get("href").split('.')[0])
Пример #19
0
def test_of_PythonGenerator():
    ih = []
    th = []
    for x in range(20, 200, 60):
        ih.append(model.Include("test_include_" + str(x)))
        th.append(
            model.Typedef("td_elem_name_" + str(x), "td_elem_val_" + str(x)))
        th.append(
            model.Typedef("td_elem_name_" + str(x), "i_td_elem_val_" + str(x)))
        th.append(
            model.Typedef("td_elem_name_" + str(x), "u_td_elem_val_" + str(x)))

    enum = []
    for x in range(1, 100, 30):
        enum.append(("elem_" + str(x), "val_" + str(x)))

    name = "MAC_L2CallConfigResp"
    members = [model.StructMember('messageResult', 'SMessageResult')]
    msg_h = model.Struct(name, members)

    nodes = []
    nodes += ih
    nodes += [
        model.Constant("C_A", "5"),
        model.Constant("C_B", "5"),
        model.Constant("C_C", "C_B + C_A")
    ]
    nodes += th
    nodes += [model.Enum("test", enum)]
    nodes += [msg_h]

    ps = PythonGenerator()
    output = ps.serialize_string(nodes)

    ref = """\
import prophy

from test_include_20 import *
from test_include_80 import *
from test_include_140 import *

C_A = 5
C_B = 5
C_C = C_B + C_A

td_elem_name_20 = td_elem_val_20
td_elem_name_20 = i_td_elem_val_20
td_elem_name_20 = u_td_elem_val_20
td_elem_name_80 = td_elem_val_80
td_elem_name_80 = i_td_elem_val_80
td_elem_name_80 = u_td_elem_val_80
td_elem_name_140 = td_elem_val_140
td_elem_name_140 = i_td_elem_val_140
td_elem_name_140 = u_td_elem_val_140

class test(prophy.enum):
    __metaclass__ = prophy.enum_generator
    _enumerators  = [('elem_1', val_1),
                     ('elem_31', val_31),
                     ('elem_61', val_61),
                     ('elem_91', val_91)]

elem_1 = val_1
elem_31 = val_31
elem_61 = val_61
elem_91 = val_91

class MAC_L2CallConfigResp(prophy.struct):
    __metaclass__ = prophy.struct_generator
    _descriptor = [('messageResult', SMessageResult)]
"""
    assert ref == output