7 from utils
import maybesorted
10 argp
= argparse
.ArgumentParser(description
="Render function database as various graphs")
11 argp
.add_argument("file", help="Input file (YAML)")
12 argp
.add_argument("-o", "--output", help="Output file (default stdout)")
13 argp
.add_argument("--func", help="Start from this function")
14 argp
.add_argument("--no-refs", action
="store_true", help="Show only direct calls, not refs to other functions "
15 "(otherwise refs shown as dashed lines)")
16 argp
.add_argument("--group", action
="append", default
=[], help="Group some functions together, GROUP is name=file.txt, "
17 "if name is '_ignore_', don't graph these functions")
18 argp
.add_argument("--each-call", action
="store_true", help="Show multiple edges for each call site")
19 args
= argp
.parse_args()
25 def read_func_list(fname
):
27 with
open(fname
) as f
:
30 if not l
or l
[0] == "#":
37 name
, fname
= g
.split("=", 1)
38 funcs
= read_func_list(fname
)
39 if name
== "_ignore_":
42 GROUPS
[name
] = set(funcs
)
45 FUNC_DB
= yaml
.load(open(args
.file))
48 out
= open(args
.output
, "w")
56 def index_by_name(db
):
57 for addr
, props
in list(db
.items()):
58 db
[props
["label"]] = props
61 def get_group(funcname
):
62 if funcname
in IGNORE
:
64 for name
, funcs
in GROUPS
.items():
69 def map_group(funcname
):
70 return get_group(funcname
) or funcname
73 def dump_level(func
, props
):
74 if get_group(props
["label"]):
76 for propname
in ("calls", "func_refs"):
77 if propname
== "func_refs" and args
.no_refs
:
79 for callee
in maybesorted(props
.get(propname
, [])):
82 callee
= map_group(callee
)
84 if not args
.each_call
:
85 if (props
["label"], callee
) in dup_set
:
87 dup_set
.add((props
["label"], callee
))
88 attrs
= {"func_refs": " [style=dashed]"}.get(propname
, "")
89 out
.write("%s -> %s%s\n" % (props
["label"], callee
, attrs
))
92 out
.write("digraph G {\n")
95 index_by_name(FUNC_DB
)
100 props
= FUNC_DB
.get(f
)
105 for callee
in props
["calls"]:
106 if callee
not in done
:
109 for func
, props
in maybesorted(FUNC_DB
.items()):
110 dump_level(func
, props
)