123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- typeset -grA __p9k_pb_cmd_skip=(
- '}' 'always' # handled specially
- '{' ''
- '{' ''
- '|' ''
- '||' ''
- '&' ''
- '&&' ''
- '|&' ''
- '&!' ''
- '&|' ''
- ')' ''
- '(' ''
- '()' ''
- '!' ''
- ';' ''
- 'if' ''
- 'fi' ''
- 'elif' ''
- 'else' ''
- 'then' ''
- 'while' ''
- 'until' ''
- 'do' ''
- 'done' ''
- 'esac' ''
- 'end' ''
- 'coproc' ''
- 'nocorrect' ''
- 'noglob' ''
- 'time' ''
- '[[' '\]\]'
- '((' '\)\)'
- 'case' '\)|esac'
- ';;' '\)|esac'
- ';&' '\)|esac'
- ';|' '\)|esac'
- 'foreach' '\(*\)'
- )
- typeset -grA __p9k_pb_precommand=(
- '-' ''
- 'builtin' ''
- 'command' ''
- 'exec' '-[^a]#[a]'
- 'nohup' ''
- 'setsid' ''
- 'eatmydata' ''
- 'catchsegv' ''
- 'pkexec' '--user'
- 'doas' '-[^aCu]#[acU]'
- 'nice' '-[^n]#[n]|--adjustment'
- 'stdbuf' '-[^ioe]#[ioe]|--(input|output|error)'
- 'sudo' '-[^aghpuUCcrtT]#[aghpuUCcrtT]|--(close-from|group|host|prompt|role|type|other-user|command-timeout|user)'
- 'ssh-agent' '-[^aEPt]#[aEPt]'
- 'tabbed' '-[^gnprtTuU]#[gnprtTuU]'
- 'chronic' ''
- 'ifne' ''
- )
- typeset -grA __p9k_pb_redirect=(
- '&>' ''
- '>' ''
- '>&' ''
- '<' ''
- '<&' ''
- '<>' ''
- '&>|' ''
- '>|' ''
- '&>>' ''
- '>>' ''
- '>>&' ''
- '&>>|' ''
- '>>|' ''
- '<<<' ''
- )
- typeset -grA __p9k_pb_term=(
- '|' ''
- '||' ''
- ';' ''
- '&' ''
- '&&' ''
- '|&' ''
- '&!' ''
- '&|' ''
- ';;' ''
- ';&' ''
- ';|' ''
- '(' ''
- ')' ''
- '()' '' # handled specially
- '}' '' # handled specially
- )
- typeset -grA __p9k_pb_term_skip=(
- '(' '\)'
- ';;' '\)|esac'
- ';&' '\)|esac'
- ';|' '\)|esac'
- )
- # Usage: _p9k_parse_buffer <buffer> [token-limit]
- #
- # Parses the specified command line buffer and pupulates array P9K_COMMANDS
- # with commands from it. Terminates early and returns 1 if there are more
- # tokens than the specified limit.
- #
- # Broken:
- #
- # ---------------
- # : $(x)
- # ---------------
- # : `x`
- # ---------------
- # ${x/}
- # ---------------
- # - -- x
- # ---------------
- # command -p -p x
- # ---------------
- # *
- # ---------------
- # x=$y; $x
- # ---------------
- # alias x=y; y
- # ---------------
- # x <<END
- # ; END
- # END
- # ---------------
- # Setup:
- # setopt interactive_comments
- # alias x='#'
- # Punchline:
- # x; y
- # ---------------
- #
- # More brokenness with non-standard options (ignore_braces, ignore_close_braces, etc.).
- function _p9k_parse_buffer() {
- [[ ${2:-0} == <-> ]] || return 2
- local rcquotes
- [[ -o rcquotes ]] && rcquotes=rcquotes
- eval "$__p9k_intro"
- setopt no_nomatch $rcquotes
- typeset -ga P9K_COMMANDS=()
- local -r id='(<->|[[:alpha:]_][[:IDENT:]]#)'
- local -r var="\$$id|\${$id}|\"\$$id\"|\"\${$id}\""
- local -i e ic c=${2:-'1 << 62'}
- local skip n s r state token cmd prev
- local -a aln alp alf v
- if [[ -o interactive_comments ]]; then
- ic=1
- local tokens=(${(Z+C+)1})
- else
- local tokens=(${(z)1})
- fi
- {
- while (( $#tokens )); do
- (( e = $#state ))
- while (( $#tokens == alp[-1] )); do
- aln[-1]=()
- alp[-1]=()
- if (( $#tokens == alf[-1] )); then
- alf[-1]=()
- (( e = 0 ))
- fi
- done
- while (( c-- > 0 )) || return; do
- token=$tokens[1]
- tokens[1]=()
- if (( $+galiases[$token] )); then
- (( $aln[(eI)p$token] )) && break
- s=$galiases[$token]
- n=p$token
- elif (( e )); then
- break
- elif (( $+aliases[$token] )); then
- (( $aln[(eI)p$token] )) && break
- s=$aliases[$token]
- n=p$token
- elif [[ $token == ?*.?* ]] && (( $+saliases[${token##*.}] )); then
- r=${token##*.}
- (( $aln[(eI)s$r] )) && break
- s=${saliases[$r]%% #}
- n=s$r
- else
- break
- fi
- aln+=$n
- alp+=$#tokens
- [[ $s == *' ' ]] && alf+=$#tokens
- (( ic )) && tokens[1,0]=(${(Z+C+)s}) || tokens[1,0]=(${(z)s})
- done
- case $token in
- '<<'(|-))
- state=h
- continue
- ;;
- *('`'|['<>=$']'(')*)
- if [[ $token == ('`'[^'`']##'`'|'"`'[^'`']##'`"'|'$('[^')']##')'|'"$('[^')']##')"'|['<>=']'('[^')']##')') ]]; then
- s=${${token##('"'|)(['$<>']|)?}%%?('"'|)}
- (( ic )) && tokens+=(';' ${(Z+C+)s}) || tokens+=(';' ${(z)s})
- fi
- ;;
- esac
- case $state in
- *r)
- state[-1]=
- continue
- ;;
- a)
- if [[ $token == $skip ]]; then
- if [[ $token == '{' ]]; then
- P9K_COMMANDS+=$cmd
- cmd=
- state=
- else
- skip='{'
- fi
- continue
- else
- state=t
- fi
- ;& # fall through
- t|p*)
- if (( $+__p9k_pb_term[$token] )); then
- if [[ $token == '()' ]]; then
- state=
- else
- P9K_COMMANDS+=$cmd
- if [[ $token == '}' ]]; then
- state=a
- skip=always
- else
- skip=$__p9k_pb_term_skip[$token]
- state=${skip:+s}
- fi
- fi
- cmd=
- continue
- elif [[ $state == t ]]; then
- continue
- elif [[ $state == *x ]]; then
- if (( $+__p9k_pb_redirect[$token] )); then
- prev=
- state[-1]=r
- continue
- else
- state[-1]=
- fi
- fi
- ;;
- s)
- if [[ $token == $~skip ]]; then
- state=
- fi
- continue
- ;;
- h)
- while (( $#tokens )); do
- (( e = ${tokens[(i)${(Q)token}]} ))
- if [[ $tokens[e-1] == ';' && $tokens[e+1] == ';' ]]; then
- tokens[1,e]=()
- break
- else
- tokens[1,e]=()
- fi
- done
- while (( $#alp && alp[-1] >= $#tokens )); do
- aln[-1]=()
- alp[-1]=()
- done
- state=t
- continue
- ;;
- esac
- if (( $+__p9k_pb_redirect[${token#<0-255>}] )); then
- state+=r
- continue
- fi
- if [[ $token == *'$'* ]]; then
- if [[ $token == $~var ]]; then
- n=${${token##[^[:IDENT:]]}%%[^[:IDENT:]]}
- [[ $token == *'"' ]] && v=("${(P)n}") || v=(${(P)n})
- tokens[1,0]=(${(@qq)v})
- continue
- fi
- fi
- case $state in
- '')
- if (( $+__p9k_pb_cmd_skip[$token] )); then
- skip=$__p9k_pb_cmd_skip[$token]
- [[ $token == '}' ]] && state=a || state=${skip:+s}
- continue
- fi
- if [[ $token == *=* ]]; then
- v=${(S)token/#(<->|([[:alpha:]_][[:IDENT:]]#(|'['*[^\\](\\\\)#']')))(|'+')=}
- if (( $#v < $#token )); then
- if [[ $v == '(' ]]; then
- state=s
- skip='\)'
- fi
- continue
- fi
- fi
- : ${token::=${(Q)${~token}}}
- ;;
- p2)
- if [[ -n $prev ]]; then
- prev=
- else
- : ${token::=${(Q)${~token}}}
- if [[ $token == '{'$~id'}' ]]; then
- state=p2x
- prev=$token
- else
- state=p
- fi
- continue
- fi
- ;& # fall through
- p)
- if [[ -n $prev ]]; then
- token=$prev
- prev=
- else
- : ${token::=${(Q)${~token}}}
- case $token in
- '{'$~id'}') prev=$token; state=px; continue;;
- [^-]*) ;;
- --) state=p1; continue;;
- $~skip) state=p2; continue;;
- *) continue;;
- esac
- fi
- ;;
- p1)
- if [[ -n $prev ]]; then
- token=$prev
- prev=
- else
- : ${token::=${(Q)${~token}}}
- if [[ $token == '{'$~id'}' ]]; then
- state=p1x
- prev=$token
- continue
- fi
- fi
- ;;
- esac
- if (( $+__p9k_pb_precommand[$token] )); then
- prev=
- state=p
- skip=$__p9k_pb_precommand[$token]
- cmd+=$token$'\0'
- else
- state=t
- [[ $token == ('(('*'))'|'`'*'`'|'$'*|['<>=']'('*')'|*$'\0'*) ]] || cmd+=$token$'\0'
- fi
- done
- } always {
- [[ $state == (px|p1x) ]] && cmd+=$prev
- P9K_COMMANDS+=$cmd
- P9K_COMMANDS=(${(u)P9K_COMMANDS%$'\0'})
- }
- }
|