Code for displaying a function call hierarchy in leo

16 views
Skip to first unread message

Brian Theado

unread,
Nov 16, 2011, 10:19:41 PM11/16/11
to leo-editor
The other day I stumbled across Ville's code in scripts.leo which
displays the output of python's trace module in a leo outline. The
output of the trace module is not very friendly and I didn't find the
result very usable. I was inspired to write some code to translate
the output so the tree of function calls is displayed via Leo
headlines. Thanks to Ville for sharing that code. I never would have
figure this out without that starting point.

Just Ctrl-Shift-V the below text into a leo outline (hopefully there
are no wrapping issues due to email) and hit ctrl-b on the "call tree"
node. The execution tree of the 'scroll-outline-up-line' minibuffer
command will be displayed to stdout and also as a tree of leo
headlines.


<?xml version="1.0" encoding="utf-8"?>
<!-- Created by Leo (http://webpages.charter.net/edreamleo/front.html) -->
<?xml-stylesheet ekr_test?>
<leo_file xmlns:leo="http://www.leo-editor.org/2011/leo" >
<leo_header file_format="2"/>
<vnodes>
<v t="btheado.20111114181136.9100" a="E"><vh>call tree</vh>
<v t="btheado.20111114181136.9101"><vh>displayCalltree</vh></v>
</v>
</vnodes>
<tnodes>
<t tx="btheado.20111114181136.9100">@others
import trace

# see http://docs.python.org/library/trace.html for documentation
# on the trace module
tracer = trace.Trace(countcallers=1)

# Trace a minibuffer command. Any function call will work, but leo
# minibuffer commands are easily discoverable via tab completion and
# the 'print-commands' command
#tracer.runfunc(c.executeMinibufferCommand, 'goto-prev-node')
tracer.runfunc(c.executeMinibufferCommand, 'scroll-outline-up-line')
top = p.insertAsLastChild().copy()
top.h = 'trace session'
displayCalltree(top, tracer.results().callers.keys())
c.redraw()</t>
<t tx="btheado.20111114181136.9101">def displayCalltree(p, callinfo):
'''
Converts the function call hierarchy in 'callinfo' into a tree of function
calls. The function call tree is displayed to stdout as indented text
and is inserted as a tree of leo nodes rooted at the given position 'p'
'''
callers = [k[0] for k in callinfo]
callees = [k[1] for k in callinfo]

# The first set of children will be those that don't have any callers
# listed in callinfo
toplevels = list(set(callers) - set(callees))
positions = {}
path = []

# Depth-first traversal of the call hierarchy represented by 'callinfo'
# 'levels' is a stack which grows during descend and shrinks
# during ascend. Each element of 'levels' is a list of unprocessed
# siblings of each other
levels = [toplevels]
while len(levels) &gt; 0:
while len(levels[-1]) &gt; 0:
# Process the first element in the 'deepest' (i.e. last)
list of siblings
cur = levels[-1][0]
levels[-1] = levels[-1][1:]
indent = " " * 4 * (len(levels)-1)
if cur not in path:
if cur in positions.keys():
# Function already seen, so make a clone
clone = positions[cur].clone()
clone.moveToLastChildOf(p)
print (indent + "%s %s ..." % cur[1:])
else:
# Haven't seen this function, so insert a new headline
p = p.insertAsLastChild().copy()
p.h = "%s %s" % cur[1:]
print (indent + p.h)

# Remember the position so it can be cloned if seen again
positions[cur] = p

# find all callees of this function and descend
levels.append([c[1] for c in callinfo if c[0] == cur])
path.append(cur)
else:
r = p.insertAsLastChild().copy()
r.h = "(recursive call) %s %s" % (cur[1], cur[2])
print(indent + r.h + "...")

# Ascend back up one level
path = path[0:-1]
p = p.parent()
levels = levels[0:-1]</t>
</tnodes>
</leo_file>

Kent Tenney

unread,
Nov 17, 2011, 10:02:07 AM11/17/11
to leo-e...@googlegroups.com
Very cool!

Makes me wish for a rclick on node option:
"Expand Subtree"

> --
> You received this message because you are subscribed to the Google Groups "leo-editor" group.
> To post to this group, send email to leo-e...@googlegroups.com.
> To unsubscribe from this group, send email to leo-editor+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/leo-editor?hl=en.
>
>

Reply all
Reply to author
Forward
0 new messages