Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Function for examining structure of calls in debug output

In case this is useful to anyone, the function below is a very simple
(and easy to confuse) way of examining the structure of shell debug
output such as what you get from ^X? in completion.  For example (except
I keep changing my mind on the format) from some _complete_debug output:

   _complete_debug:17 -> _main_complete
     _main_complete:25 -> (eval)
     _main_complete:82 -> _setup
     _main_complete:178 -> _oldlist
     _main_complete:178 -> _oldlist
     _main_complete:178 -> _expand
       _expand:81 -> (eval)
       _expand:89 -> (eval)
       _expand:106 -> (eval)
     _main_complete:178 -> _expand
     _main_complete:178 -> _user_expand
       _user_expand:39 -> (eval)
       _user_expand:48 -> _percent
     _main_complete:178 -> _user_expand
     _main_complete:178 -> _complete
       _complete:100 -> (eval)
       _complete:117 -> _normal
         _normal:38 -> _set_command
         _normal:40 -> _dispatch
           _dispatch:63 -> (eval)
             (eval):1 -> _mh
               _mh:44 -> _wanted
                 _wanted:7 -> _tags
                 _wanted:9 -> _tags
                 _wanted:10 -> _all_labels
                   _all_labels:37 -> _description
                     _description:18 -> _setup
                   _all_labels:39 -> _path_files
                     _path_files:17 -> _have_glob_qual
                     _path_files:201 -> _have_glob_qual
                     _path_files:202 -> _have_glob_qual
                     _path_files:725 -> _list_files
                 _wanted:10 -> _dispatch
                   _dispatch:64 -> _complete
                     _complete:144 -> _main_complete
                       _main_complete:380 -> _complete_debug

You'll notice it's already confused because the return from _dispatch
goes to _complete instead of _normal, since there are no further
non-trivial commands in _normal, and searching back up the stack for the
return function would mean there was no hope of it grokking recursive
structures.  I'm not sure how much effort I can be bothered to put into
this.  A better solution might be for a prompt escape that tracks the
nesting level (which is trivial apart from picking a new letter).

xtrace_trace() {
  # Trivial function to trace the strcture of zsh function calls
  # with xtrace output using a PS4 containing %N and %i (see prompt_match
  # below).
  # Input is stderr from a shell with xtrace active and a suitable PS4.
  # The completion system's ^X? binding can produce such output.
  # Because we can't be sure a change in execution is a new call
  # or a return to a previous function, we always assume the latter where
  # the names match.  This is the normal case but may be wrong for
  # certain recursive structures.

  emulate -L zsh
  setopt extendedglob

  # Match lines for PS4="+%N:%i> ".  Adapt as appropriate.
  local prompt_match="+(#b)([^>]##):([0-9]##)> *"
  # Function name in $match[1]
  integer func_match=1
  # Line number in $match[2]
  integer lineno_match=2
  # Padding to indent a line
  local pad="  "

  local line func indent last_line
  integer lineno
  local -a match mbegin mend funcs

  while read line; do
    [[ $line = ${~prompt_match} ]] || continue

    if (( ${#funcs} == 0 )); then
      print -r -- ${func}:${lineno}
    elif [[ $func != ${funcs[-1]} ]]; then
      if [[ $func = ${funcs[-2]} ]]; then
	print -r -- "$indent $last_line -> $func"

  done <${1:-/dev/stdin}

Peter Stephenson <p.stephenson@xxxxxxxxxxx>  Principal Software Engineer
Tel: +44 (0)1223 434724                Samsung Cambridge Solution Centre
St John's House, St John's Innovation Park, Cowley Road,
Cambridge, CB4 0DS, UK

Messages sorted by: Reverse Date, Date, Thread, Author