Пример #1
0
def test_cross_reference_structs():
    nodes = [
        model.Struct("A", [
            model.StructMember("a", "u8")
        ]),
        model.Struct("B", [
            model.StructMember("a", "A"),
            model.StructMember("b", "u8")
        ]),
        model.Struct("C", [
            model.StructMember("a", "A"),
            model.StructMember("b", "B"),
            model.StructMember("c", "NON_EXISTENT")
        ]),
        model.Struct("D", [
            model.StructMember("a", "A"),
            model.StructMember("b", "B"),
            model.StructMember("c", "C")
        ])
    ]

    model.cross_reference(nodes)

    definition_names = [[x.definition.name if x.definition else None for x in y.members] for y in nodes]
    assert definition_names == [
        [None],
        ['A', None],
        ['A', 'B', None],
        ['A', 'B', 'C']
    ]
Пример #2
0
def test_evaluate_kinds_arrays():
    nodes = [
        model.Struct("A", [
            model.StructMember("a", "u8"),
            model.StructMember("b", "u8", optional = True),
            model.StructMember("c", "u8", size = "5"),
            model.StructMember("d_len", "u8"),
            model.StructMember("d", "u8", bound = "d_len", size = "5"),
            model.StructMember("e_len", "u8"),
            model.StructMember("e", "u8", bound = "e_len"),
            model.StructMember("f", "u8", unlimited = True)
        ])
    ]

    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)

    assert [x.kind for x in nodes[0].members] == [
        model.Kind.FIXED,
        model.Kind.FIXED,
        model.Kind.FIXED,
        model.Kind.FIXED,
        model.Kind.FIXED,
        model.Kind.FIXED,
        model.Kind.FIXED,
        model.Kind.FIXED,
    ]
Пример #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_evaluate_kinds_struct_records():
    nodes = [
        model.Struct("Fix", [
            model.StructMember("a", "u8")
        ]),
        model.Struct("Dyn", [
            model.StructMember("a_len", "u8"),
            model.StructMember("a", "u8", bound = "a_len")
        ]),
        model.Struct("X", [
            model.StructMember("a", "Dyn"),
            model.StructMember("b_len", "u8"),
            model.StructMember("b", "Fix", bound = "b_len"),
            model.StructMember("c", "Fix", unlimited = True)
        ])
    ]

    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)

    assert [x.kind for x in nodes] == [
        model.Kind.FIXED,
        model.Kind.DYNAMIC,
        model.Kind.UNLIMITED,
    ]

    assert [x.kind for x in nodes[2].members] == [
        model.Kind.DYNAMIC,
        model.Kind.FIXED,
        model.Kind.FIXED,
        model.Kind.FIXED,
    ]
Пример #5
0
def test_cross_reference_expression_as_array_size():
    nodes = [
        model.Struct('X', [
            model.StructMember('x', 'u32', size = '2 * 3'),
        ])
    ]

    model.cross_reference(nodes)

    assert nodes[0].members[0].numeric_size == 6
Пример #6
0
def test_cross_reference_numeric_size_of_expression():
    nodes = [
        model.Constant('A', 12),
        model.Constant('B', 15),
        model.Constant('C', 'A*B'),
        model.Struct('X', [
            model.StructMember('x', 'u32', size = 'C'),
        ])
    ]

    model.cross_reference(nodes)

    assert nodes[3].members[0].numeric_size == 180
Пример #7
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] == []
Пример #8
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,
    }
Пример #9
0
def test_cross_reference_typedef():
    nodes = [
        model.Struct("A", [model.StructMember("a", "u8")]),
        model.Typedef("B", "A"),
        model.Struct(
            "C", [model.StructMember("a", "A"),
                  model.StructMember("b", "B")]),
        model.Typedef("D", "B")
    ]

    model.cross_reference(nodes)

    assert nodes[1].definition.name == "A"
    assert nodes[2].members[1].definition.definition.name == "A"
    assert nodes[3].definition.name == "B"
    assert nodes[3].definition.definition.name == "A"
Пример #10
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"]]
Пример #11
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
Пример #12
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
Пример #13
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"]]
Пример #14
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"]]
Пример #15
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"]]
Пример #16
0
def test_cross_reference_typedef():
    nodes = [
        model.Struct("A", [
            model.StructMember("a", "u8")
        ]),
        model.Typedef("B", "A"),
        model.Struct("C", [
            model.StructMember("a", "A"),
            model.StructMember("b", "B")
        ]),
        model.Typedef("D", "B")
    ]

    model.cross_reference(nodes)

    assert nodes[1].definition.name == "A"
    assert nodes[2].members[1].definition.definition.name == "A"
    assert nodes[3].definition.name == "B"
    assert nodes[3].definition.definition.name == "A"
Пример #17
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
Пример #18
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
Пример #19
0
def test_cross_reference_numeric_size_of_expression():
    nodes = [
        model.Constant('A', 12),
        model.Constant('B', 15),
        model.Constant('C', 'A*B'),
        model.Struct('X', [
            model.StructMember('x', 'u32', size='C'),
        ]),
    ]

    constants = model.cross_reference(nodes)

    assert nodes[3].members[0].numeric_size == 180
    assert constants == {'A': 12, 'B': 15, 'C': 180}
Пример #20
0
def test_cross_reference_structs():
    nodes = [
        model.Struct("A", [
            model.StructMember("a", "u8"),
        ]),
        model.Struct("B", [
            model.StructMember("a", "A"),
            model.StructMember("b", "u8"),
        ]),
        model.Struct("C", [
            model.StructMember("a", "A"),
            model.StructMember("b", "B"),
            model.StructMember("c", "NON_EXISTENT"),
        ]),
        model.Struct("D", [
            model.StructMember("a", "A"),
            model.StructMember("b", "B"),
            model.StructMember("c", "C"),
        ])
    ]

    constants = model.cross_reference(nodes)

    assert [n.name for n in nodes] == ['A', 'B', 'C', 'D']
    definition_names = [[
        x.definition.name if x.definition else None for x in y.members
    ] for y in nodes]
    assert definition_names == [
        [None],
        ['A', None],
        ['A', 'B', None],
        ['A', 'B', 'C'],
    ]
    assert [tuple(n.dependencies()) for n in nodes] == [
        ('u8', ),
        ('A', 'u8'),
        ('A', 'B', 'NON_EXISTENT'),
        ('A', 'B', 'C'),
    ]
    assert constants == {}
Пример #21
0
def test_cross_reference_typedef_warnings():
    nodes = [model.Typedef('X', 'Unknown')]
    warn = WarnFake()
    model.cross_reference(nodes, warn)
    assert warn.msgs == ["type 'Unknown' not found"]
Пример #22
0
def test_cross_reference_no_warning_about_primitive_types():
    warn = WarnFake()
    model.cross_reference([model.Typedef('X', 'u8')], warn)
    model.cross_reference([model.Typedef('X', 'u16')], warn)
    model.cross_reference([model.Typedef('X', 'u32')], warn)
    model.cross_reference([model.Typedef('X', 'u64')], warn)
    model.cross_reference([model.Typedef('X', 'i8')], warn)
    model.cross_reference([model.Typedef('X', 'i16')], warn)
    model.cross_reference([model.Typedef('X', 'i32')], warn)
    model.cross_reference([model.Typedef('X', 'i64')], warn)
    model.cross_reference([model.Typedef('X', 'r32')], warn)
    model.cross_reference([model.Typedef('X', 'r64')], warn)
    model.cross_reference([model.Typedef('X', 'byte')], warn)
    assert warn.msgs == []
Пример #23
0
def test_cross_reference_union_warnings():
    nodes = [model.Union('X', [model.UnionMember('x', 'TypeUnknown', '42')])]
    warn = WarnFake()
    model.cross_reference(nodes, warn)
    assert warn.msgs == ["type 'TypeUnknown' not found"]
Пример #24
0
def test_cross_reference_struct_warnings():
    nodes = [model.Struct('X', [model.StructMember('x', 'TypeUnknown', size = '12 + NumUnknown')])]
    warn = WarnFake()
    model.cross_reference(nodes, warn)
    assert warn.msgs == ["type 'TypeUnknown' not found", "numeric constant 'NumUnknown' not found"]
Пример #25
0
def test_cross_reference_typedef_warnings():
    nodes = [model.Typedef('X', 'Unknown')]
    warn = WarnFake()
    model.cross_reference(nodes, warn)
    assert warn.msgs == ["type 'Unknown' not found"]
Пример #26
0
def process_nodes(nodes):
    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)
Пример #27
0
def test_cross_reference_union_warnings():
    nodes = [model.Union('X', [model.UnionMember('x', 'TypeUnknown', '42')])]
    warn = WarnFake()
    model.cross_reference(nodes, warn)
    assert warn.msgs == ["type 'TypeUnknown' not found"]
Пример #28
0
def test_evaluate_kinds_with_typedefs():
    nodes = [
        model.Struct("Empty", []),
        model.Struct("Dynamic", [
            model.StructMember("a_len", "u8"),
            model.StructMember("a", "u8", bound = "a_len")
        ]),
        model.Struct("Fixed", [
            model.StructMember("a", "u8", size = "10")
        ]),
        model.Struct("Limited", [
            model.StructMember("a_len", "u8"),
            model.StructMember("a", "u8", bound = "a_len", size = "10")
        ]),
        model.Struct("Greedy", [
            model.StructMember("a", "byte", unlimited = True)
        ]),
        model.Struct("DynamicWrapper", [
            model.StructMember("a", "Dynamic")
        ]),
        model.Struct("GreedyWrapper", [
            model.StructMember("a", "Greedy")
        ]),
        model.Struct("GreedyDynamic", [
            model.StructMember("a", "Dynamic", unlimited = True)
        ]),
        model.Typedef("TU8", "u8"),
        model.Typedef("TDynamic", "Dynamic"),
        model.Typedef("TGreedy", "Greedy"),
        model.Struct("TypedefedU8", [
            model.StructMember("a", "TU8")
        ]),
        model.Struct("TypedefedDynamic", [
            model.StructMember("a", "TDynamic")
        ]),
        model.Struct("TypedefedGreedy", [
            model.StructMember("a", "TGreedy")
        ]),
        model.Typedef("TTDynamic", "TDynamic"),
        model.Typedef("TTTDynamic", "TTDynamic"),
        model.Struct("DeeplyTypedefed", [
            model.StructMember("a", "TTTDynamic")
        ]),
    ]

    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)

    assert [x.kind for x in nodes if isinstance(x, model.Struct)] == [
        model.Kind.FIXED,
        model.Kind.DYNAMIC,
        model.Kind.FIXED,
        model.Kind.FIXED,
        model.Kind.UNLIMITED,
        model.Kind.DYNAMIC,
        model.Kind.UNLIMITED,
        model.Kind.UNLIMITED,
        model.Kind.FIXED,
        model.Kind.DYNAMIC,
        model.Kind.UNLIMITED,
        model.Kind.DYNAMIC,
    ]
Пример #29
0
def test_cross_reference_struct_warnings():
    nodes = [model.Struct('X', [model.StructMember('x', 'TypeUnknown', size = '12 + NumUnknown')])]
    warn = WarnFake()
    model.cross_reference(nodes, warn)
    assert warn.msgs == ["type 'TypeUnknown' not found", "numeric constant 'NumUnknown' not found"]
Пример #30
0
def test_evaluate_kinds_with_typedefs():
    nodes = [
        model.Struct("Empty", []),
        model.Struct("Dynamic", [
            model.StructMember("a_len", "u8"),
            model.StructMember("a", "u8", bound = "a_len")
        ]),
        model.Struct("Fixed", [
            model.StructMember("a", "u8", size = "10")
        ]),
        model.Struct("Limited", [
            model.StructMember("a_len", "u8"),
            model.StructMember("a", "u8", bound = "a_len", size = "10")
        ]),
        model.Struct("Greedy", [
            model.StructMember("a", "byte", unlimited = True)
        ]),
        model.Struct("DynamicWrapper", [
            model.StructMember("a", "Dynamic")
        ]),
        model.Struct("GreedyWrapper", [
            model.StructMember("a", "Greedy")
        ]),
        model.Struct("GreedyDynamic", [
            model.StructMember("a", "Dynamic", unlimited = True)
        ]),
        model.Typedef("TU8", "u8"),
        model.Typedef("TDynamic", "Dynamic"),
        model.Typedef("TGreedy", "Greedy"),
        model.Struct("TypedefedU8", [
            model.StructMember("a", "TU8")
        ]),
        model.Struct("TypedefedDynamic", [
            model.StructMember("a", "TDynamic")
        ]),
        model.Struct("TypedefedGreedy", [
            model.StructMember("a", "TGreedy")
        ]),
        model.Typedef("TTDynamic", "TDynamic"),
        model.Typedef("TTTDynamic", "TTDynamic"),
        model.Struct("DeeplyTypedefed", [
            model.StructMember("a", "TTTDynamic")
        ]),
    ]

    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)

    assert [x.kind for x in nodes if isinstance(x, model.Struct)] == [
        model.Kind.FIXED,
        model.Kind.DYNAMIC,
        model.Kind.FIXED,
        model.Kind.FIXED,
        model.Kind.UNLIMITED,
        model.Kind.DYNAMIC,
        model.Kind.UNLIMITED,
        model.Kind.UNLIMITED,
        model.Kind.FIXED,
        model.Kind.DYNAMIC,
        model.Kind.UNLIMITED,
        model.Kind.DYNAMIC,
    ]
Пример #31
0
def process_nodes(nodes):
    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)
Пример #32
0
def process(nodes):
    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)
    model.evaluate_sizes(nodes)
    return nodes
Пример #33
0
def test_cross_reference_no_warning_about_primitive_types():
    warn = WarnFake()
    model.cross_reference([model.Typedef('X', 'u8')], warn)
    model.cross_reference([model.Typedef('X', 'u16')], warn)
    model.cross_reference([model.Typedef('X', 'u32')], warn)
    model.cross_reference([model.Typedef('X', 'u64')], warn)
    model.cross_reference([model.Typedef('X', 'i8')], warn)
    model.cross_reference([model.Typedef('X', 'i16')], warn)
    model.cross_reference([model.Typedef('X', 'i32')], warn)
    model.cross_reference([model.Typedef('X', 'i64')], warn)
    model.cross_reference([model.Typedef('X', 'r32')], warn)
    model.cross_reference([model.Typedef('X', 'r64')], warn)
    model.cross_reference([model.Typedef('X', 'byte')], warn)
    assert warn.msgs == []
Пример #34
0
def process(nodes, warn=None):
    warnings = []
    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)
    model.evaluate_sizes(nodes, **(warn and {'warn': warn} or {}))
    return nodes
Пример #35
0
def process(nodes):
    model.cross_reference(nodes)
    model.evaluate_kinds(nodes)
    model.evaluate_sizes(nodes)
    _check_nodes(nodes)
    return nodes