summaryrefslogtreecommitdiff
path: root/FreeRTOS/Test/VeriFast/scripts/callgraph.py
blob: ca6fa4ee8bfab2d2221d742202ce649713e10886 (plain)
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
76
77
78
79
80
81
82
83
#!/usr/bin/env python3

from __future__ import print_function
from pycparser import c_parser, c_ast, parse_file
import sys

ignore_callee = set(['mutex_acquire', 'mutex_release'])
ignore_caller = set(['caller_reinstates_queue_predicate'])
proven = [
    'prvCopyDataFromQueue',
    'prvCopyDataToQueue',
    'prvInitialiseNewQueue',
    'prvIsQueueEmpty',
    'prvIsQueueFull',
    'prvLockQueue',
    'prvUnlockQueue',
    'uxQueueMessagesWaiting',
    'uxQueueSpacesAvailable',
    'vQueueDelete',
    'xQueueGenericCreate',
    'xQueueGenericReset',
    'xQueueGenericSend',
    'xQueueGenericSendFromISR',
    'xQueueIsQueueEmptyFromISR',
    'xQueueIsQueueFullFromISR',
    'xQueuePeek',
    'xQueuePeekFromISR',
    'xQueueReceive',
    'xQueueReceiveFromISR',
]

modeled = [
    'setInterruptMask',
    'clearInterruptMask',
    'setInterruptMaskFromISR',
    'clearInterruptMaskFromISR',
    'vTaskSuspendAll',
    'xTaskResumeAll',
]

CALLMAP = set()


class FuncCallVisitor(c_ast.NodeVisitor):
    def __init__(self, caller):
        self.caller = caller

    def visit_FuncCall(self, node):
        callee = node.name.name
        if callee not in ignore_callee:
            CALLMAP.add((node.name.name, self.caller))


class FuncDefVisitor(c_ast.NodeVisitor):
    def visit_FuncDef(self, node):
        caller = node.decl.name
        if caller in ignore_caller:
            return
        if caller.startswith('wrapper_'):
            caller = caller[8:]
        v = FuncCallVisitor(caller)
        v.visit(node)


def show_func_calls(filename):
    ast = parse_file(filename, use_cpp=False)
    v = FuncDefVisitor()
    v.visit(ast)


if __name__ == "__main__":
    filename = 'out.pp'
    show_func_calls(filename)
    print('digraph G {')
    print('  rankdir=LR;')
    print('  node [style = filled, colorscheme = set13;];')
    for f in proven:
        print('  %s [fillcolor = 3];' % f)
    for f in modeled:
        print('  %s [fillcolor = 2];' % f)
    for (callee, caller) in CALLMAP:
        print('  %s -> %s;' % (callee, caller))
    print('}')