-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathassignment_checker.py
executable file
·75 lines (60 loc) · 2.6 KB
/
assignment_checker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/usr/bin/env python3
"""
The goal of this file is to check all the assignments given. This module
relies on the scraping provided by other modules.
"""
import sys
from scrapers import AnnotationKind
from violation import AssignmentViolation
def split_type( usr, fun_types ):
"""
Split the type of a function into its direct and indirect constituents
"""
return (
set( [ name
for ( kind, name )
in fun_types.get( usr, set() )
if kind == AnnotationKind.DIRECT ] ),
set( [ name
for ( kind, name )
in fun_types.get( usr, set() )
if kind == AnnotationKind.INDIRECT ] ) )
def check_assignments( assignments, fun_types ):
"""
Check all the assignments in the given list of assignments. Takes in
a list of assignments, a mapping of function pointer usr's to their
qualified types, and a list of augmented function types (where indirect
calls have been added post-scrape). Reports an error for any
assignments that do not follow the conventions given.
"""
for lvalue, rvalue, cursor in assignments:
lvalue_direct_type, lvalue_indirect_type = split_type(
lvalue, fun_types )
rvalue_direct_type, rvalue_indirect_type = split_type(
rvalue, fun_types )
# direct types must match
# right indirect type must be subset of left indirect type
if ( lvalue_direct_type != rvalue_direct_type or
not rvalue_indirect_type.issubset( lvalue_indirect_type ) ):
yield AssignmentViolation( lvalue, rvalue, cursor )
if __name__ == '__main__':
import scrapers
import call_tree
from ast_helpers import get_translation_unit
from type_augmentor import augment_types
target = get_translation_unit( sys.argv[ 1 ] )
call_tree = call_tree.build_call_tree( target )
overrides = scrapers.Overrides.scrape( target )
func_cursors = scrapers.FunctionCursors.scrape( target )
func_types = scrapers.FunctionQualifiers.scrape( target )
funcptr_types = scrapers.FunctionPointers.scrape( target )
assignments = scrapers.FunPtrAssignments.scrape( target )
call_tree.augment_with_overrides( overrides )
func_types = augment_types( call_tree, funcptr_types, func_types )
assignment_violations = check_assignments(
assignments, funcptr_types, func_types )
for violation in assignment_violations:
print(
violation.render_string(
func_cursors, funcptr_types, func_types ) )
print()