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>

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

Reply via email to