Skip to content

Instantly share code, notes, and snippets.

@lecram
Created November 7, 2011 18:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lecram/1345727 to your computer and use it in GitHub Desktop.
Save lecram/1345727 to your computer and use it in GitHub Desktop.
C Call Graph.
import subprocess
call = "ctags -no - *.c"
tags = subprocess.check_output(call, shell=True)
funcs = []
for entry in tags.split('\n'):
tokens = entry.split('\t')
if tokens[-1].strip() == "f":
func, source, line, symboltype = tokens
line = int(line.rstrip(";\""))
funcs.append((source, line, func))
funcs.sort(key=lambda f: f[1])
funcs.sort(key=lambda f: f[0])
arrows = []
for source, line, func in funcs:
regex = r'"\(^\|[^a-zA-Z]\)%s("' % func
call = "grep -nH %s *.c" % regex
matches = subprocess.check_output(call, shell=True)
callers = set()
for entry in matches.split('\n'):
tokens = entry.split(':')
if len(tokens) >= 3:
msource = tokens[0]
mline = int(tokens[1])
if msource == source and mline == line:
continue
defs = [f[2] for f in funcs
if f[0] == msource and f[1] < mline]
if defs:
callers.add(defs[-1])
callers = list(callers)
callers.sort()
for caller in callers:
arrows.append((caller, func))
arrows.sort(key=lambda a: a[0])
arrows.sort(key=lambda a: a[1])
dot = open("ccg.dot", "w")
dot.write("digraph G {\n")
dot.write(" ratio=1.0;\n")
for arrow in arrows:
dot.write(" %s -> %s;\n" % arrow)
dot.write("}\n")
dot.close()
call = "dot -Tpng ccg.dot -o ccg.png"
subprocess.check_call(call, shell=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment