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) > 0: while len(levels[-1]) > 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.
