mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-12-17 21:31:35 +01:00
zsh-3.1.5-pws-5
This commit is contained in:
parent
2a5a899a55
commit
20d67907c9
47 changed files with 2212 additions and 425 deletions
|
|
@ -27,5 +27,5 @@
|
||||||
# This must also serve as a shell script, so do not add spaces around the
|
# This must also serve as a shell script, so do not add spaces around the
|
||||||
# `=' signs.
|
# `=' signs.
|
||||||
|
|
||||||
VERSION=3.1.5-pws-4
|
VERSION=3.1.5-pws-5
|
||||||
VERSION_DATE='December 17, 1998'
|
VERSION_DATE='January 19, 1998'
|
||||||
|
|
|
||||||
|
|
@ -947,9 +947,10 @@ otherwise it is determined by the width of the value of the
|
||||||
first assignment.
|
first assignment.
|
||||||
)
|
)
|
||||||
item(tt(-a))(
|
item(tt(-a))(
|
||||||
The names refer to array parameters. For historical reasons, scalar
|
The names refer to array parameters. An array parameter may be
|
||||||
parameters are created even when this flag is specified, but the
|
created this way, but it may not be assigned to in the tt(typeset)
|
||||||
output is restricted to arrays (including associative arrays).
|
statement. When displaying, both normal and associative arrays are
|
||||||
|
shown.
|
||||||
)
|
)
|
||||||
item(tt(-f))(
|
item(tt(-f))(
|
||||||
The names refer to functions rather than parameters. No assignments
|
The names refer to functions rather than parameters. No assignments
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ the standard behavior for all commands. For example, if your access
|
||||||
to the user database is too slow and/or it contains too many users (so
|
to the user database is too slow and/or it contains too many users (so
|
||||||
that completion after `tt(~)' is too slow to be usable), you can use
|
that completion after `tt(~)' is too slow to be usable), you can use
|
||||||
|
|
||||||
nofill(tt(compctl -Tx 'C[0,*/*]' -f - 's[~]' -k friends -S/))
|
nofill(tt(compctl -Tx 'C[0,*/*]' -f - 's[~]' -k friends -S/ -tn))
|
||||||
|
|
||||||
to complete the strings in the array tt(friends) after a `tt(~)'.
|
to complete the strings in the array tt(friends) after a `tt(~)'.
|
||||||
The first argument is necessary so that this form of ~-completion is
|
The first argument is necessary so that this form of ~-completion is
|
||||||
|
|
@ -432,16 +432,18 @@ the sorted ones. I.e. it is possible to have a sorted and a unsorted group
|
||||||
with the same name and the matches in those groups will not be mixed.
|
with the same name and the matches in those groups will not be mixed.
|
||||||
)
|
)
|
||||||
item(tt(-t) var(continue))(
|
item(tt(-t) var(continue))(
|
||||||
The var(continue)-string contains a set of characters that specify if
|
The var(continue)-string contains a character that specifies which set
|
||||||
and when completion should continue to produce matches where it normally
|
of completion flags should be used next. Normally those of the next
|
||||||
would not do that. The character tt(c) means that completion continues
|
matching compctl are used, i.e. pattern compctls and normal compctls
|
||||||
with the next suitable compctl (i.e. if you don't specify this in a
|
after tt(-T) and after a pattern compctl. If var(continue) is the
|
||||||
tt(compctl -T), compctls for commands are never used). The character
|
character tt(PLUS()) the flags for the next alternative completion
|
||||||
tt(PLUS()) is used to continue with the matches for the next alternative
|
(see below) are used. The characters tt(-) and tt(x) can be used in
|
||||||
completion (see below). The characters tt(-) and tt(x) may be used in
|
sub-lists for extended completion (see below). They will make the
|
||||||
sub-lists for extended completion (see below). They will make the completion
|
completion code use the flag list after the next tt(-) (if the
|
||||||
code use the flag list after the next tt(-) (if the corresponding pattern
|
corresponding pattern matches) and the default flag list (those before
|
||||||
matches) and the default flag list (those before the tt(-x)), respectively.
|
the tt(-x)), respectively. if var(continue) is the character tt(n) no
|
||||||
|
other flag lists are used, i.e. the generation of matches stops
|
||||||
|
immediately.
|
||||||
)
|
)
|
||||||
item(tt(-M) var(match-spec))(
|
item(tt(-M) var(match-spec))(
|
||||||
This defines additional matching control specifications that should be used
|
This defines additional matching control specifications that should be used
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,27 @@ nofill(tt(LPAR()zftp open; zftp get foo >bar; zftp close)tt(RPAR() &))
|
||||||
--- here, the connection is restricted to a background subshell and
|
--- here, the connection is restricted to a background subshell and
|
||||||
you are free to open a simultaneous connection in the foreground.
|
you are free to open a simultaneous connection in the foreground.
|
||||||
)
|
)
|
||||||
|
item(tt(test))(
|
||||||
|
Test the connection; if the server has reported
|
||||||
|
that it has closed the connection (maybe due to a timeout), return
|
||||||
|
status 2; if no connection was open anyway, return status 1; else
|
||||||
|
return status 0. The tt(test) subcommand is
|
||||||
|
silent, apart from messages printed by the tt($ZFTP_VERBOSE)
|
||||||
|
mechanism, or error messages if the connection closes. There is no
|
||||||
|
network overhead for this test.
|
||||||
|
|
||||||
|
The test is only supported on systems with either the tt(select(2)) or
|
||||||
|
tt(poll(2)) system calls; otherwise the message tt(not
|
||||||
|
supported on this system) is printed instead.
|
||||||
|
|
||||||
|
It is useful to put the code
|
||||||
|
|
||||||
|
nofill(tt([[ -n $ZFTP_HOST ]] && zftp test))
|
||||||
|
|
||||||
|
into the shell function tt(precmd) for testing the connection before
|
||||||
|
every prompt. However, tt(zftp) will call tt(test) at the start of any
|
||||||
|
other subcommand when a connection is open.
|
||||||
|
)
|
||||||
item(tt(cd) var(directory))(
|
item(tt(cd) var(directory))(
|
||||||
Change the remote directory to var(directory). Also alters the shell
|
Change the remote directory to var(directory). Also alters the shell
|
||||||
variable tt(ZFTP_PWD).
|
variable tt(ZFTP_PWD).
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,8 @@ HP: HP-UX 9, 10.20
|
||||||
Should build `out-of-the-box'.
|
Should build `out-of-the-box'.
|
||||||
|
|
||||||
IBM: AIX
|
IBM: AIX
|
||||||
Should build `out-of-the-box'.
|
Should build `out-of-the-box'. On AIX 3.x (at least),
|
||||||
|
--enable-zsh-mem will not work.
|
||||||
|
|
||||||
Linux: Linux (i386) [3.1.4]
|
Linux: Linux (i386) [3.1.4]
|
||||||
If you are using an early minor version of libc 5, then a bug
|
If you are using an early minor version of libc 5, then a bug
|
||||||
|
|
@ -92,3 +93,6 @@ Sun: Solaris 2.*
|
||||||
To avoid this, make sure you compile zsh without any reference
|
To avoid this, make sure you compile zsh without any reference
|
||||||
to /usr/ucblib in your LD_LIBRARY_PATH. You can easily do this
|
to /usr/ucblib in your LD_LIBRARY_PATH. You can easily do this
|
||||||
by just unsetting LD_LIBRARY_PATH before building zsh.
|
by just unsetting LD_LIBRARY_PATH before building zsh.
|
||||||
|
|
||||||
|
Under Solaris 2.7, dynamically loaded library support with
|
||||||
|
--enable-dynamic currently does not work.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
DISTFILES_SRC='
|
DISTFILES_SRC='
|
||||||
.distfiles
|
.distfiles
|
||||||
c2z compctl-examples globtests globtests.ksh lete2ctl
|
c2z compctl-examples globtests globtests.ksh lete2ctl
|
||||||
|
new-completion-examples zftp-functions
|
||||||
'
|
'
|
||||||
|
|
|
||||||
453
Misc/new-completion-examples
Normal file
453
Misc/new-completion-examples
Normal file
|
|
@ -0,0 +1,453 @@
|
||||||
|
# Define a new widget behaving like `expand-or-complete' but calling the
|
||||||
|
# function `main-complete' to generate matches.
|
||||||
|
|
||||||
|
zle -c my-comp expand-or-complete main-complete
|
||||||
|
|
||||||
|
bindkey '\C-i' my-comp
|
||||||
|
|
||||||
|
|
||||||
|
# Below is a proposed main loop and the things it needs.
|
||||||
|
|
||||||
|
# One associative array for normal completions and one for patterns.
|
||||||
|
|
||||||
|
typeset -A comps
|
||||||
|
|
||||||
|
|
||||||
|
# These may be used to define completion handlers. First argument is the
|
||||||
|
# name of the function/variable containing the definition, the other
|
||||||
|
# arguments are the command names for which this definition should be used.
|
||||||
|
# With only one argument the function/variable-name __$1 is used.
|
||||||
|
|
||||||
|
defcomp() {
|
||||||
|
local v
|
||||||
|
|
||||||
|
if [[ $# -eq 1 ]] then
|
||||||
|
comps[$1]="__$1"
|
||||||
|
else
|
||||||
|
v="$1"
|
||||||
|
shift
|
||||||
|
for i; do
|
||||||
|
comps[$i]="$v"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
defpatcomp() {
|
||||||
|
if [[ ${+patcomps} == 1 ]] then
|
||||||
|
patcomps=("$patcomps[@]" "$2 $1" )
|
||||||
|
else
|
||||||
|
patcomps=( "$2 $1" )
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# These can be used to easily save and restore the state of the special
|
||||||
|
# variables used by the completion code.
|
||||||
|
|
||||||
|
alias compsave='local _opre _oipre _oargs _ocur;_opre="$PREFIX";_oipre="$IPREFIX";_oargs=( "$@" );_ocur="$CURRENT"'
|
||||||
|
alias compreset='PREFIX="$_opre";IPREFIX="$_oipre";argv=( "$_oargs[@]" );CURRENT="$_ocur"'
|
||||||
|
|
||||||
|
# This is an easy way to get completion for sub-commands.
|
||||||
|
|
||||||
|
alias compsub='do-complete "$@" || return 1'
|
||||||
|
|
||||||
|
# This searches $1 in the array for normal completions and calls the result.
|
||||||
|
|
||||||
|
compalso() {
|
||||||
|
1="$comps[$1]"
|
||||||
|
[[ -z "$1" ]] || call-complete "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# This generates matches. The first argument is something we got from one
|
||||||
|
# of the associative arrays above. This is expected to be either the name
|
||||||
|
# of a variable in which case we use its value as arguments to complist,
|
||||||
|
# or it is the name of a function in which case we call this function with
|
||||||
|
# the arguments from the command line as its arguments.
|
||||||
|
|
||||||
|
call-complete() {
|
||||||
|
local var
|
||||||
|
|
||||||
|
eval var\=\$\{\+$1\}
|
||||||
|
if [[ "$var" == 0 ]] then
|
||||||
|
"$@"
|
||||||
|
else
|
||||||
|
eval complist \$\{${1}\[\@\]\}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# The main loop of the competion code. This is what is called when TAB is
|
||||||
|
# pressed. The completion code gives us the special variables and the
|
||||||
|
# arguments from the command line are gives as positional parameters.
|
||||||
|
|
||||||
|
main-complete() {
|
||||||
|
emulate -R zsh
|
||||||
|
local comp
|
||||||
|
setopt localoptions nullglob rcexpandparam globdots
|
||||||
|
unsetopt markdirs globsubst shwordsplit nounset
|
||||||
|
|
||||||
|
# An entry for `--first--' is the replacement for `compctl -T'
|
||||||
|
# The `|| return 1' is used throughout: if a function producing matches
|
||||||
|
# returns non-zero this is interpreted as `do not try to produce more matches'
|
||||||
|
# (this is the replacement for `compctl -t').
|
||||||
|
|
||||||
|
comp="$comps[--first--]"
|
||||||
|
[[ -z "$comp" ]] || call-complete "$comp" "$@" || return 1
|
||||||
|
|
||||||
|
# For arguments we use the `do-complete' function below called via the
|
||||||
|
# convenience alias `compsub'.
|
||||||
|
|
||||||
|
if [[ $CONTEXT == argument || $CONTEXT == command ]] then
|
||||||
|
compsub
|
||||||
|
else
|
||||||
|
# Let's see if we have a special completion definition for the other
|
||||||
|
# possible contexts.
|
||||||
|
|
||||||
|
comp=''
|
||||||
|
|
||||||
|
case $CONTEXT in
|
||||||
|
redirect) comp="$comps[--redir--]";;
|
||||||
|
math) comp="$comps[--math--]";;
|
||||||
|
subscript) comp="$comps[--subscr--]";;
|
||||||
|
value) comp="$comps[--value--]";;
|
||||||
|
condition) comp="$comps[--cond--]";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# If not, we use default completion, if any.
|
||||||
|
|
||||||
|
[[ -z "$comp" ]] && comp="$comps[--default--]"
|
||||||
|
[[ -z "$comp" ]] || call-complete "$comp" "$@" || return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This does completion for a command (in command position and for the
|
||||||
|
# arguments).
|
||||||
|
|
||||||
|
do-complete() {
|
||||||
|
local comp cmd1 cmd2 pat val
|
||||||
|
|
||||||
|
# Completing in command position? If not we set up `cmd1' and `cmd2' as
|
||||||
|
# two strings we have search in the completion definition arrays (e.g.
|
||||||
|
# a path and the last path name component).
|
||||||
|
|
||||||
|
if [[ $CONTEXT == command ]] then
|
||||||
|
comp="$comps[--command--]"
|
||||||
|
[[ -z "$comp" ]] || call-complete "$comp" "$@" || return 1
|
||||||
|
return 0
|
||||||
|
elif [[ "$COMMAND[1]" == '=' ]] then
|
||||||
|
eval cmd1\=$COMMAND
|
||||||
|
cmd2="$COMMAND[2,-1]"
|
||||||
|
elif [[ "$COMMAND" == */* ]] then
|
||||||
|
cmd1="$COMMAND"
|
||||||
|
cmd2="${COMMAND:t}"
|
||||||
|
else
|
||||||
|
cmd1="$COMMAND"
|
||||||
|
eval cmd2=$(whence -p $COMMAND)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# See if there are any matching pattern completions.
|
||||||
|
|
||||||
|
for i in "$patcomps[@]"; do
|
||||||
|
pat="${i% *}"
|
||||||
|
val="${i#* }"
|
||||||
|
if [[ "$cmd1" == $~pat || "$cmd2" == $~pat ]] then
|
||||||
|
call-complete "$val" "$@" || return 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Now look up the two names in the normal completion array.
|
||||||
|
|
||||||
|
comp="${comps[$cmd1]:-$comps[$cmd2]}"
|
||||||
|
|
||||||
|
# And generate the matches, probably using default completion.
|
||||||
|
|
||||||
|
[[ -z "$comp" ]] && comp="$comps[--default--]"
|
||||||
|
[[ -z "$comp" ]] || call-complete "$comp" "$@" || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Do sub-completion for pre-command modifiers.
|
||||||
|
|
||||||
|
defcomp __precmd - noglob nocorrect exec command builtin
|
||||||
|
__precmd() {
|
||||||
|
COMMAND="$1"
|
||||||
|
shift
|
||||||
|
(( CURRENT-- ))
|
||||||
|
if [[ CURRENT -eq 0 ]] then
|
||||||
|
CONTEXT=command
|
||||||
|
else
|
||||||
|
CONTEXT=argument
|
||||||
|
fi
|
||||||
|
compsub
|
||||||
|
}
|
||||||
|
|
||||||
|
# Utility function for in-path completion.
|
||||||
|
# First argument should be an complist-option (e.g. -f, -/, -g). The other
|
||||||
|
# arguments should be glob patterns, one per argument.
|
||||||
|
# E.g.: files -g '*.tex' '*.texi'
|
||||||
|
# This is intended as a replacement for `complist -f', `complist -/', and
|
||||||
|
# `complist -g ...' (but don't use it with other options).
|
||||||
|
# This function behaves as if you have a matcher definition like:
|
||||||
|
# compctl -M 'r:|[-.,_/]=* r:|=* m:{a-z}={A-Z} m:-=_ m:.=,'
|
||||||
|
# so you may want to modify this.
|
||||||
|
|
||||||
|
pfiles() {
|
||||||
|
local nm str pa pre epre a b c s rest
|
||||||
|
|
||||||
|
setopt localoptions nullglob rcexpandparam globdots extendedglob
|
||||||
|
unsetopt markdirs globsubst shwordsplit nounset
|
||||||
|
|
||||||
|
nm=$NMATCHES
|
||||||
|
if [[ $# -eq 0 ]] then
|
||||||
|
complist -f
|
||||||
|
elif [[ "$1" = -g ]] then
|
||||||
|
complist -g "$argv[2,-1]"
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
complist $1
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
[[ -nmatches nm ]] || return
|
||||||
|
|
||||||
|
str="$PREFIX*$SUFFIX"
|
||||||
|
|
||||||
|
[[ -z "$1" ]] && 1='*'
|
||||||
|
if [[ $str[1] = \~ ]] then
|
||||||
|
pre="${str%%/*}/"
|
||||||
|
eval epre\=$pre
|
||||||
|
str="${str#*/}"
|
||||||
|
pa=''
|
||||||
|
else
|
||||||
|
pre=''
|
||||||
|
epre=''
|
||||||
|
if [[ $str[1] = / ]] then
|
||||||
|
str="$str[2,-1]"
|
||||||
|
pa='/'
|
||||||
|
else
|
||||||
|
pa=''
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
str="$str:gs/,/*,/:gs/_/*_/:gs./.*/.:gs/-/*[-_]/:gs/./*[.,]/:gs-*[.,]*[.,]*/-../-:gs.**.*."
|
||||||
|
while [[ "$str" = */* ]] do
|
||||||
|
rest="${str#*/}"
|
||||||
|
a="${epre}${pa}(#l)${str%%/*}(-/)"
|
||||||
|
a=( $~a )
|
||||||
|
if [[ $#a -eq 0 ]] then
|
||||||
|
return
|
||||||
|
elif [[ $#a -gt 1 ]] then
|
||||||
|
c=()
|
||||||
|
s=( $rest$@ )
|
||||||
|
s=( "${(@)s:gs.**.*.}" )
|
||||||
|
for i in $a; do
|
||||||
|
b=( $~i/(#l)$~s )
|
||||||
|
eval b\=\( \$\{b:/\*\(${(j:|:)fignore}\)\} \)
|
||||||
|
[[ $#b -ne 0 ]] && c=( $c $i )
|
||||||
|
done
|
||||||
|
if [[ $#c -eq 0 ]] then
|
||||||
|
return
|
||||||
|
elif [[ $#c -ne 1 ]] then
|
||||||
|
a="$epre$pa"
|
||||||
|
c=( $~c/(#l)$~s )
|
||||||
|
eval c\=\( \$\{c:/\*\(${(j:|:)fignore}\)\} \)
|
||||||
|
c=( ${c#$a} )
|
||||||
|
for i in $c; do
|
||||||
|
compadd -p "$pre$pa" -W "$a" -s "/${i#*/}" -f "${i%%/*}"
|
||||||
|
done
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
a=( "$c[1]" )
|
||||||
|
fi
|
||||||
|
a="$a[1]"
|
||||||
|
pa="$pa${a##*/}/"
|
||||||
|
str="$rest"
|
||||||
|
done
|
||||||
|
a="$epre$pa"
|
||||||
|
s=( $str$@ )
|
||||||
|
s=( "${(@)s:gs.**.*.}" )
|
||||||
|
b=( $~a(#l)$~s )
|
||||||
|
eval b\=\( \$\{b:/\*\(${(j:|:)fignore}\)\} \)
|
||||||
|
compadd -p "$pre$pa" -W "$epre$pa" -f ${b#$a}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Utility function for completing files of a given type or any file.
|
||||||
|
# In many cases you will want to call this one instead of pfiles().
|
||||||
|
|
||||||
|
files() {
|
||||||
|
local nm
|
||||||
|
|
||||||
|
nm=$NMATCHES
|
||||||
|
pfiles "$@"
|
||||||
|
|
||||||
|
[[ $# -ne 0 && -nmatches nm ]] && pfiles
|
||||||
|
}
|
||||||
|
|
||||||
|
# Simple default, command, and math completion defined with variables.
|
||||||
|
|
||||||
|
defcomp __default --default--
|
||||||
|
__default() {
|
||||||
|
files
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp __command --command--
|
||||||
|
__command=( -c )
|
||||||
|
|
||||||
|
defcomp __math --math--
|
||||||
|
__math=( -v )
|
||||||
|
|
||||||
|
defcomp __subscr --subscr--
|
||||||
|
__subscr() {
|
||||||
|
compalso --math-- "$@"
|
||||||
|
# ...probably other stuff
|
||||||
|
}
|
||||||
|
|
||||||
|
# A simple pattern completion, just as an example.
|
||||||
|
|
||||||
|
defpatcomp __x_options '*/X11/*'
|
||||||
|
__x_options() {
|
||||||
|
complist -J options -k '(-display -name -xrm)'
|
||||||
|
}
|
||||||
|
|
||||||
|
# A better example: completion for `find'.
|
||||||
|
|
||||||
|
defcomp find
|
||||||
|
__find() {
|
||||||
|
compsave
|
||||||
|
|
||||||
|
if [[ -mbetween -(ok|exec) \\\; ]] then
|
||||||
|
compsub
|
||||||
|
elif [[ -iprefix - ]] then
|
||||||
|
complist -s 'daystart {max,min,}depth follow noleaf version xdev \
|
||||||
|
{a,c,}newer {a,c,m}{min,time} empty false {fs,x,}type gid inum links \
|
||||||
|
{i,}{l,}name {no,}{user,group} path perm regex size true uid used \
|
||||||
|
exec {f,}print{f,0,} ok prune ls'
|
||||||
|
compreset
|
||||||
|
elif [[ -position 1 ]] then
|
||||||
|
complist -g '. ..'
|
||||||
|
files -g '(-/)'
|
||||||
|
elif [[ -mcurrent -1 -((a|c|)newer|fprint(|0|f)) ]] then
|
||||||
|
files
|
||||||
|
elif [[ -current -1 -fstype ]] then
|
||||||
|
complist -k '(ufs 4.2 4.3 nfs tmp mfs S51K S52K)'
|
||||||
|
elif [[ -current -1 -group ]] then
|
||||||
|
complist -k groups
|
||||||
|
elif [[ -current -1 -user ]] then
|
||||||
|
complist -u
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Various completions...
|
||||||
|
|
||||||
|
defcomp __gunzip gunzip zcat
|
||||||
|
__gunzip() {
|
||||||
|
files -g '*.[gG][z]'
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp gzip
|
||||||
|
__gzip() {
|
||||||
|
files -g '*~*.[gG][zZ]'
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp xfig
|
||||||
|
__xfig() {
|
||||||
|
files -g '*.fig'
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp __make make gmake
|
||||||
|
__make() {
|
||||||
|
complist -s "\$(awk '/^[a-zA-Z0-9][^/ ]+:/ {print \$1}' FS=: [mM]akefile)"
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp __ps gs ghostview gview psnup psselect pswrap pstops pstruct lpr
|
||||||
|
__ps() {
|
||||||
|
files -g '*([pP][sS]|eps)'
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp __which which whence
|
||||||
|
__which=( -caF )
|
||||||
|
|
||||||
|
defcomp __rlogin rlogin rsh ssh
|
||||||
|
__rlogin() {
|
||||||
|
if [[ -position 1 ]] then
|
||||||
|
complist -k hosts
|
||||||
|
elif [[ -position 2 ]] then
|
||||||
|
complist -k '(-l)'
|
||||||
|
elif [[ -position 3 && -word 1 artus ]] then
|
||||||
|
complist -k '(puck root)'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp __dvi xdvi dvips dvibook dviconcat dvicopy dvidvi dviselect dvitodvi dvitype
|
||||||
|
__dvi() {
|
||||||
|
files -g '*.(dvi|DVI)'
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp __dirs rmdir df du dircmp cd
|
||||||
|
__dirs() {
|
||||||
|
files -/ '*(-/)'
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp __jobs fg bg jobs
|
||||||
|
__jobs=(-j -P '%?')
|
||||||
|
|
||||||
|
defcomp kill
|
||||||
|
__kill() {
|
||||||
|
if [[ -iprefix '-' ]] then
|
||||||
|
complist -k signals
|
||||||
|
else
|
||||||
|
complist -P '%?' -j
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp __uncompress uncompress zmore
|
||||||
|
__uncompress() {
|
||||||
|
files -g '*.Z'
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp compress
|
||||||
|
__compress() {
|
||||||
|
files -g '*~*.Z'
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp __tex tex latex glatex slitex gslitex
|
||||||
|
__tex() {
|
||||||
|
files -g '*.(tex|TEX|texinfo|texi)'
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp __options setopt unsetopt
|
||||||
|
__options=(-M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o)
|
||||||
|
|
||||||
|
defcomp __funcs unfunction
|
||||||
|
__funcs=(-F)
|
||||||
|
|
||||||
|
defcomp __aliases unalias
|
||||||
|
__aliases=(-a)
|
||||||
|
|
||||||
|
defcomp __vars unset
|
||||||
|
__vars=(-v)
|
||||||
|
|
||||||
|
defcomp __enabled disable
|
||||||
|
__enabled=(-FBwa)
|
||||||
|
|
||||||
|
defcomp __disabled enable
|
||||||
|
__disabled=(-dFBwa)
|
||||||
|
|
||||||
|
defcomp __pdf acroread
|
||||||
|
__pdf() {
|
||||||
|
files -g '*.(pdf|PDF)'
|
||||||
|
}
|
||||||
|
|
||||||
|
defcomp tar
|
||||||
|
__tar() {
|
||||||
|
local nm tf
|
||||||
|
compsave
|
||||||
|
|
||||||
|
tf="$2"
|
||||||
|
nm=$NMATCHES
|
||||||
|
if [[ ( -mword 1 *t*f* || -mword 1 *x*f* ) && -position 3 100000 ]] then
|
||||||
|
complist -k "( $(tar tf $tf) )"
|
||||||
|
compreset
|
||||||
|
elif [[ -mword 1 *c*f* && -position 3 100000 ]] then
|
||||||
|
files
|
||||||
|
compreset
|
||||||
|
elif [[ -mcurrent -1 *f* && -position 2 ]] then
|
||||||
|
files -g '*.(tar|TAR)'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
@ -264,7 +264,7 @@ bin_limit(char *nam, char **argv, char *ops, int func)
|
||||||
* together more than one of these. It's easier to understand from *
|
* together more than one of these. It's easier to understand from *
|
||||||
* the code: */
|
* the code: */
|
||||||
val = zstrtorlimt(s, &s, 10);
|
val = zstrtorlimt(s, &s, 10);
|
||||||
if (*s)
|
if (*s) {
|
||||||
if ((*s == 'h' || *s == 'H') && !s[1])
|
if ((*s == 'h' || *s == 'H') && !s[1])
|
||||||
val *= 3600L;
|
val *= 3600L;
|
||||||
else if ((*s == 'm' || *s == 'M') && !s[1])
|
else if ((*s == 'm' || *s == 'M') && !s[1])
|
||||||
|
|
@ -275,6 +275,7 @@ bin_limit(char *nam, char **argv, char *ops, int func)
|
||||||
zwarnnam("limit", "unknown scaling factor: %s", s, 0);
|
zwarnnam("limit", "unknown scaling factor: %s", s, 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
# ifdef RLIMIT_NPROC
|
# ifdef RLIMIT_NPROC
|
||||||
else if (lim == RLIMIT_NPROC)
|
else if (lim == RLIMIT_NPROC)
|
||||||
|
|
@ -339,12 +340,12 @@ bin_unlimit(char *nam, char **argv, char *ops, int func)
|
||||||
/* Without arguments, remove all limits. */
|
/* Without arguments, remove all limits. */
|
||||||
if (!*argv) {
|
if (!*argv) {
|
||||||
for (limnum = 0; limnum != RLIM_NLIMITS; limnum++) {
|
for (limnum = 0; limnum != RLIM_NLIMITS; limnum++) {
|
||||||
if (hard)
|
if (hard) {
|
||||||
if (euid && current_limits[limnum].rlim_max != RLIM_INFINITY)
|
if (euid && current_limits[limnum].rlim_max != RLIM_INFINITY)
|
||||||
ret++;
|
ret++;
|
||||||
else
|
else
|
||||||
limits[limnum].rlim_max = RLIM_INFINITY;
|
limits[limnum].rlim_max = RLIM_INFINITY;
|
||||||
else
|
} else
|
||||||
limits[limnum].rlim_cur = limits[limnum].rlim_max;
|
limits[limnum].rlim_cur = limits[limnum].rlim_max;
|
||||||
}
|
}
|
||||||
if (ops['s'])
|
if (ops['s'])
|
||||||
|
|
@ -373,13 +374,13 @@ bin_unlimit(char *nam, char **argv, char *ops, int func)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* remove specified limit */
|
/* remove specified limit */
|
||||||
if (hard)
|
if (hard) {
|
||||||
if (euid && current_limits[lim].rlim_max != RLIM_INFINITY) {
|
if (euid && current_limits[lim].rlim_max != RLIM_INFINITY) {
|
||||||
zwarnnam(nam, "can't remove hard limits", NULL, 0);
|
zwarnnam(nam, "can't remove hard limits", NULL, 0);
|
||||||
ret++;
|
ret++;
|
||||||
} else
|
} else
|
||||||
limits[lim].rlim_max = RLIM_INFINITY;
|
limits[lim].rlim_max = RLIM_INFINITY;
|
||||||
else
|
} else
|
||||||
limits[lim].rlim_cur = limits[lim].rlim_max;
|
limits[lim].rlim_cur = limits[lim].rlim_max;
|
||||||
if (ops['s'] && zsetlimit(lim, nam))
|
if (ops['s'] && zsetlimit(lim, nam))
|
||||||
ret++;
|
ret++;
|
||||||
|
|
@ -478,11 +479,12 @@ bin_ulimit(char *name, char **argv, char *ops, int func)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!*argv || **argv == '-') {
|
if (!*argv || **argv == '-') {
|
||||||
if (res < 0)
|
if (res < 0) {
|
||||||
if (*argv || nres)
|
if (*argv || nres)
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
res = RLIMIT_FSIZE;
|
res = RLIMIT_FSIZE;
|
||||||
|
}
|
||||||
resmask |= 1 << res;
|
resmask |= 1 << res;
|
||||||
nres++;
|
nres++;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,5 @@ DISTFILES_SRC='
|
||||||
example.mdd example.c
|
example.mdd example.c
|
||||||
files.mdd files.c
|
files.mdd files.c
|
||||||
stat.mdd stat.c
|
stat.mdd stat.c
|
||||||
|
zftp.mdd zftp.c
|
||||||
'
|
'
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
autobins="example"
|
autobins="example"
|
||||||
|
|
||||||
|
autoinfixconds="ex"
|
||||||
|
autoprefixconds="len"
|
||||||
|
|
||||||
objects="example.o"
|
objects="example.o"
|
||||||
|
|
|
||||||
|
|
@ -195,18 +195,18 @@ bin_ln(char *nam, char **args, char *ops, int func)
|
||||||
|
|
||||||
|
|
||||||
if(func == BIN_MV) {
|
if(func == BIN_MV) {
|
||||||
move = rename;
|
move = (MoveFunc) rename;
|
||||||
flags = ops['f'] ? 0 : MV_ASKNW;
|
flags = ops['f'] ? 0 : MV_ASKNW;
|
||||||
flags |= MV_ATOMIC;
|
flags |= MV_ATOMIC;
|
||||||
} else {
|
} else {
|
||||||
flags = ops['f'] ? MV_FORCE : 0;
|
flags = ops['f'] ? MV_FORCE : 0;
|
||||||
#ifdef HAVE_LSTAT
|
#ifdef HAVE_LSTAT
|
||||||
if(ops['s'])
|
if(ops['s'])
|
||||||
move = symlink;
|
move = (MoveFunc) symlink;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
move = link;
|
move = (MoveFunc) link;
|
||||||
if(!ops['d'])
|
if(!ops['d'])
|
||||||
flags |= MV_NODIRS;
|
flags |= MV_NODIRS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -346,7 +346,7 @@ bin_stat(char *name, char **args, char *ops, int func)
|
||||||
} else {
|
} else {
|
||||||
for (; *arg; arg++) {
|
for (; *arg; arg++) {
|
||||||
if (strchr("glLnNrstT", *arg))
|
if (strchr("glLnNrstT", *arg))
|
||||||
ops[*arg] = 1;
|
ops[STOUC(*arg)] = 1;
|
||||||
else if (*arg == 'A') {
|
else if (*arg == 'A') {
|
||||||
if (arg[1]) {
|
if (arg[1]) {
|
||||||
arrnam = arg+1;
|
arrnam = arg+1;
|
||||||
|
|
@ -505,7 +505,7 @@ bin_stat(char *name, char **args, char *ops, int func)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & STF_FILE)
|
if (flags & STF_FILE) {
|
||||||
if (arrnam)
|
if (arrnam)
|
||||||
*arrptr++ = ztrdup(*args);
|
*arrptr++ = ztrdup(*args);
|
||||||
else if (hashnam) {
|
else if (hashnam) {
|
||||||
|
|
@ -513,6 +513,7 @@ bin_stat(char *name, char **args, char *ops, int func)
|
||||||
*hashptr++ = ztrdup(*args);
|
*hashptr++ = ztrdup(*args);
|
||||||
} else
|
} else
|
||||||
printf("%s%s", *args, (flags & STF_PICK) ? " " : ":\n");
|
printf("%s%s", *args, (flags & STF_PICK) ? " " : ":\n");
|
||||||
|
}
|
||||||
if (iwhich > -1) {
|
if (iwhich > -1) {
|
||||||
statprint(&statbuf, outbuf, *args, iwhich, flags);
|
statprint(&statbuf, outbuf, *args, iwhich, flags);
|
||||||
if (arrnam)
|
if (arrnam)
|
||||||
|
|
@ -544,7 +545,7 @@ bin_stat(char *name, char **args, char *ops, int func)
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arrnam)
|
if (arrnam) {
|
||||||
if (ret)
|
if (ret)
|
||||||
freearray(array);
|
freearray(array);
|
||||||
else {
|
else {
|
||||||
|
|
@ -552,8 +553,9 @@ bin_stat(char *name, char **args, char *ops, int func)
|
||||||
if (errflag)
|
if (errflag)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (hashnam)
|
if (hashnam) {
|
||||||
if (ret)
|
if (ret)
|
||||||
freearray(hash);
|
freearray(hash);
|
||||||
else {
|
else {
|
||||||
|
|
@ -561,6 +563,7 @@ bin_stat(char *name, char **args, char *ops, int func)
|
||||||
if (errflag)
|
if (errflag)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,9 +62,19 @@
|
||||||
/* it's a TELNET based protocol, but don't think I like doing this */
|
/* it's a TELNET based protocol, but don't think I like doing this */
|
||||||
#include <arpa/telnet.h>
|
#include <arpa/telnet.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We use poll() in preference to select because some subset of manuals says
|
||||||
|
* that's the thing to do, plus it's a bit less fiddly. I don't actually
|
||||||
|
* have access to a system with poll but not select, however, though
|
||||||
|
* both bits of the code have been tested on a machine with both.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
# include <poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* pinch the definition from <netinet/in.h> for deficient headers */
|
/* pinch the definition from <netinet/in.h> for deficient headers */
|
||||||
#ifndef INADDR_NONE
|
#ifndef INADDR_NONE
|
||||||
#define INADDR_NONE 0xffffffff
|
# define INADDR_NONE 0xffffffff
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -124,7 +134,8 @@ enum {
|
||||||
ZFTP_HERE = 0x0100, /* here rather than over there */
|
ZFTP_HERE = 0x0100, /* here rather than over there */
|
||||||
ZFTP_CDUP = 0x0200, /* CDUP rather than CWD */
|
ZFTP_CDUP = 0x0200, /* CDUP rather than CWD */
|
||||||
ZFTP_REST = 0x0400, /* restart: set point in remote file */
|
ZFTP_REST = 0x0400, /* restart: set point in remote file */
|
||||||
ZFTP_RECV = 0x0800 /* receive rather than send */
|
ZFTP_RECV = 0x0800, /* receive rather than send */
|
||||||
|
ZFTP_TEST = 0x1000 /* test command, don't test */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct zftpcmd *Zftpcmd;
|
typedef struct zftpcmd *Zftpcmd;
|
||||||
|
|
@ -134,6 +145,7 @@ static struct zftpcmd zftpcmdtab[] = {
|
||||||
{ "params", zftp_params, 0, 4, 0 },
|
{ "params", zftp_params, 0, 4, 0 },
|
||||||
{ "login", zftp_login, 0, 3, ZFTP_CONN },
|
{ "login", zftp_login, 0, 3, ZFTP_CONN },
|
||||||
{ "user", zftp_login, 0, 3, ZFTP_CONN },
|
{ "user", zftp_login, 0, 3, ZFTP_CONN },
|
||||||
|
{ "test", zftp_test, 0, 0, ZFTP_TEST },
|
||||||
{ "cd", zftp_cd, 1, 1, ZFTP_CONN|ZFTP_LOGI },
|
{ "cd", zftp_cd, 1, 1, ZFTP_CONN|ZFTP_LOGI },
|
||||||
{ "cdup", zftp_cd, 0, 0, ZFTP_CONN|ZFTP_LOGI|ZFTP_CDUP },
|
{ "cdup", zftp_cd, 0, 0, ZFTP_CONN|ZFTP_LOGI|ZFTP_CDUP },
|
||||||
{ "dir", zftp_dir, 0, -1, ZFTP_CONN|ZFTP_LOGI },
|
{ "dir", zftp_dir, 0, -1, ZFTP_CONN|ZFTP_LOGI },
|
||||||
|
|
@ -674,8 +686,8 @@ zfgetmsg()
|
||||||
|
|
||||||
zfgetline(line, 256, tmout);
|
zfgetline(line, 256, tmout);
|
||||||
ptr = line;
|
ptr = line;
|
||||||
if (zfdrrrring || !isdigit((int)*ptr) || !isdigit((int)ptr[1]) ||
|
if (zfdrrrring || !isdigit(STOUC(*ptr)) || !isdigit(STOUC(ptr[1])) ||
|
||||||
!isdigit((int)ptr[2])) {
|
!isdigit(STOUC(ptr[2]))) {
|
||||||
/* timeout, or not talking FTP. not really interested. */
|
/* timeout, or not talking FTP. not really interested. */
|
||||||
zcfinish = 2;
|
zcfinish = 2;
|
||||||
if (!zfclosing)
|
if (!zfclosing)
|
||||||
|
|
@ -820,7 +832,7 @@ zfopendata(char *name)
|
||||||
zwarnnam(name, "Must set preference S or P to transfer data", NULL, 0);
|
zwarnnam(name, "Must set preference S or P to transfer data", NULL, 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
zdfd = zfmovefd(socket(AF_INET, SOCK_STREAM, 0));
|
zdfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (zdfd < 0) {
|
if (zdfd < 0) {
|
||||||
zwarnnam(name, "can't get data socket: %e", NULL, errno);
|
zwarnnam(name, "can't get data socket: %e", NULL, errno);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -851,7 +863,7 @@ zfopendata(char *name)
|
||||||
* lastmsg already has the reply code expunged.
|
* lastmsg already has the reply code expunged.
|
||||||
*/
|
*/
|
||||||
for (ptr = lastmsg; *ptr; ptr++)
|
for (ptr = lastmsg; *ptr; ptr++)
|
||||||
if (isdigit(*ptr))
|
if (isdigit(STOUC(*ptr)))
|
||||||
break;
|
break;
|
||||||
if (sscanf(ptr, "%d,%d,%d,%d,%d,%d",
|
if (sscanf(ptr, "%d,%d,%d,%d,%d,%d",
|
||||||
nums, nums+1, nums+2, nums+3, nums+4, nums+5) != 6) {
|
nums, nums+1, nums+2, nums+3, nums+4, nums+5) != 6) {
|
||||||
|
|
@ -986,11 +998,11 @@ zfgetdata(char *name, char *rest, char *cmd, int getsize)
|
||||||
char *ptr = strstr(lastmsg, "bytes");
|
char *ptr = strstr(lastmsg, "bytes");
|
||||||
zfstatus |= ZFST_NOSZ|ZFST_TRSZ;
|
zfstatus |= ZFST_NOSZ|ZFST_TRSZ;
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
while (ptr > lastmsg && !isdigit(*ptr))
|
while (ptr > lastmsg && !isdigit(STOUC(*ptr)))
|
||||||
ptr--;
|
ptr--;
|
||||||
while (ptr > lastmsg && isdigit(ptr[-1]))
|
while (ptr > lastmsg && isdigit(STOUC(ptr[-1])))
|
||||||
ptr--;
|
ptr--;
|
||||||
if (isdigit(*ptr)) {
|
if (isdigit(STOUC(*ptr))) {
|
||||||
zfstatus &= ~ZFST_NOSZ;
|
zfstatus &= ~ZFST_NOSZ;
|
||||||
if (getsize) {
|
if (getsize) {
|
||||||
long sz = zstrtol(ptr, NULL, 10);
|
long sz = zstrtol(ptr, NULL, 10);
|
||||||
|
|
@ -1017,6 +1029,13 @@ zfgetdata(char *name, char *rest, char *cmd, int getsize)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
zdfd = newfd; /* this is now the actual data fd */
|
zdfd = newfd; /* this is now the actual data fd */
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* We avoided dup'ing zdfd up to this point, to try to keep
|
||||||
|
* things simple, so we now need to move it out of the way
|
||||||
|
* of the user-visible fd's.
|
||||||
|
*/
|
||||||
|
zdfd = zfmovefd(zdfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1659,7 +1678,7 @@ zftp_open(char *name, char **args, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
zsock.sin_port = zservp->s_port;
|
zsock.sin_port = zservp->s_port;
|
||||||
zcfd = zfmovefd(socket(zsock.sin_family, SOCK_STREAM, 0));
|
zcfd = socket(zsock.sin_family, SOCK_STREAM, 0);
|
||||||
if (zcfd < 0) {
|
if (zcfd < 0) {
|
||||||
zwarnnam(name, "socket failed: %e", NULL, errno);
|
zwarnnam(name, "socket failed: %e", NULL, errno);
|
||||||
zfunsetparam("ZFTP_HOST");
|
zfunsetparam("ZFTP_HOST");
|
||||||
|
|
@ -1667,12 +1686,6 @@ zftp_open(char *name, char **args, int flags)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(F_SETFD) && defined(FD_CLOEXEC)
|
|
||||||
/* If the shell execs a program, we don't want this fd left open. */
|
|
||||||
len = FD_CLOEXEC;
|
|
||||||
fcntl(zcfd, F_SETFD, &len);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* now connect the socket. manual pages all say things like `this is all
|
* now connect the socket. manual pages all say things like `this is all
|
||||||
* explained oh-so-wonderfully in some other manual page'. not.
|
* explained oh-so-wonderfully in some other manual page'. not.
|
||||||
|
|
@ -1708,6 +1721,19 @@ zftp_open(char *name, char **args, int flags)
|
||||||
/* now we can talk to the control connection */
|
/* now we can talk to the control connection */
|
||||||
zcfinish = 0;
|
zcfinish = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move the fd out of the user-visible range. We need to do
|
||||||
|
* this after the connect() on some systems.
|
||||||
|
*/
|
||||||
|
zcfd = zfmovefd(zcfd);
|
||||||
|
|
||||||
|
#if defined(F_SETFD) && defined(FD_CLOEXEC)
|
||||||
|
/* If the shell execs a program, we don't want this fd left open. */
|
||||||
|
len = FD_CLOEXEC;
|
||||||
|
fcntl(zcfd, F_SETFD, &len);
|
||||||
|
#endif
|
||||||
|
|
||||||
len = sizeof(zsock);
|
len = sizeof(zsock);
|
||||||
if (getsockname(zcfd, (struct sockaddr *)&zsock, &len) < 0) {
|
if (getsockname(zcfd, (struct sockaddr *)&zsock, &len) < 0) {
|
||||||
zwarnnam(name, "getsockname failed: %e", NULL, errno);
|
zwarnnam(name, "getsockname failed: %e", NULL, errno);
|
||||||
|
|
@ -2022,6 +2048,69 @@ zftp_login(char *name, char **args, int flags)
|
||||||
return zfgetcwd();
|
return zfgetcwd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See if the server wants to tell us something. On a timeout, we usually
|
||||||
|
* have a `421 Timeout' or something such waiting for us, so we read
|
||||||
|
* it here. As well as being called explicitly by the user
|
||||||
|
* (precmd is a very good place for this, it's cheap since it has
|
||||||
|
* no network overhead), we call it in the bin_zftp front end if we
|
||||||
|
* have a connection and weren't going to call it anyway.
|
||||||
|
*
|
||||||
|
* Poll-free and select-free systems are few and far between these days,
|
||||||
|
* but I'm willing to consider suggestions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
zftp_test(char *name, char **args, int flags)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_POLL) || defined(HAVE_SELECT)
|
||||||
|
int ret;
|
||||||
|
# ifdef HAVE_POLL
|
||||||
|
struct pollfd pfd;
|
||||||
|
# else
|
||||||
|
fd_set f;
|
||||||
|
struct timeval tv;
|
||||||
|
# endif /* HAVE_POLL */
|
||||||
|
|
||||||
|
if (zcfd == -1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
# ifdef HAVE_POLL
|
||||||
|
# ifndef POLLIN
|
||||||
|
/* safety first, though I think POLLIN is more common */
|
||||||
|
# define POLLIN POLLNORM
|
||||||
|
# endif /* HAVE_POLL */
|
||||||
|
pfd.fd = zcfd;
|
||||||
|
pfd.events = POLLIN;
|
||||||
|
if ((ret = poll(&pfd, 1, 0)) < 0 && errno != EINTR && errno != EAGAIN)
|
||||||
|
zfclose();
|
||||||
|
else if (ret > 0 && pfd.revents) {
|
||||||
|
/* handles 421 (maybe a bit noisily?) */
|
||||||
|
zfgetmsg();
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
FD_ZERO(&f);
|
||||||
|
FD_SET(zcfd, &f);
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
if ((ret = select(zcfd +1, (SELECT_ARG_2_T) &f, NULL, NULL, &tv)) < 0
|
||||||
|
&& errno != EINTR)
|
||||||
|
zfclose();
|
||||||
|
else if (ret > 0) {
|
||||||
|
/* handles 421 */
|
||||||
|
zfgetmsg();
|
||||||
|
}
|
||||||
|
# endif /* HAVE_POLL */
|
||||||
|
/* if we now have zcfd == -1, then we've just been dumped out. */
|
||||||
|
return (zcfd == -1) ? 2 : 0;
|
||||||
|
#else
|
||||||
|
zfwarnnam(name, "not supported on this system.", NULL, 0);
|
||||||
|
return 3;
|
||||||
|
#endif /* defined(HAVE_POLL) || defined(HAVE_SELECT) */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* do ls or dir on the remote directory */
|
/* do ls or dir on the remote directory */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
@ -2476,7 +2565,7 @@ bin_zftp(char *name, char **args, char *ops, int func)
|
||||||
char fullname[11] = "zftp ";
|
char fullname[11] = "zftp ";
|
||||||
char *cnam = *args++, *prefs, *ptr;
|
char *cnam = *args++, *prefs, *ptr;
|
||||||
Zftpcmd zptr;
|
Zftpcmd zptr;
|
||||||
int n, ret;
|
int n, ret = 0;
|
||||||
|
|
||||||
for (zptr = zftpcmdtab; zptr->nam; zptr++)
|
for (zptr = zftpcmdtab; zptr->nam; zptr++)
|
||||||
if (!strcmp(zptr->nam, cnam))
|
if (!strcmp(zptr->nam, cnam))
|
||||||
|
|
@ -2521,8 +2610,25 @@ bin_zftp(char *name, char **args, char *ops, int func)
|
||||||
"B" : "S"), ZFPM_READONLY);
|
"B" : "S"), ZFPM_READONLY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if defined(HAVE_SELECT) || defined (HAVE_POLL)
|
||||||
|
if (zcfd != -1 && !(zptr->flags & ZFTP_TEST)) {
|
||||||
|
/*
|
||||||
|
* Test the connection for a bad fd or incoming message, but
|
||||||
|
* only if the connection was last heard of open, and
|
||||||
|
* if we are not about to call the test command anyway.
|
||||||
|
* Not worth it unless we have select() or poll().
|
||||||
|
*/
|
||||||
|
ret = zftp_test("zftp test", NULL, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if ((zptr->flags & ZFTP_CONN) && zcfd == -1) {
|
if ((zptr->flags & ZFTP_CONN) && zcfd == -1) {
|
||||||
zwarnnam(fullname, "not connected.", NULL, 0);
|
if (ret != 2) {
|
||||||
|
/*
|
||||||
|
* with ret == 2, we just got dumped out in the test,
|
||||||
|
* so enough messages already.
|
||||||
|
*/
|
||||||
|
zwarnnam(fullname, "not connected.", NULL, 0);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ struct compctl cc_compos, cc_default, cc_first, cc_dummy;
|
||||||
/**/
|
/**/
|
||||||
Cmlist cmatcher;
|
Cmlist cmatcher;
|
||||||
|
|
||||||
/* pointers to functions required by zle */
|
/* pointers to functions required by zle and defined by compctl */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void (*printcompctlptr) _((char *, Compctl, int, int));
|
void (*printcompctlptr) _((char *, Compctl, int, int));
|
||||||
|
|
@ -49,6 +49,24 @@ void (*printcompctlptr) _((char *, Compctl, int, int));
|
||||||
/**/
|
/**/
|
||||||
Compctl (*compctl_widgetptr) _((char *, char **));
|
Compctl (*compctl_widgetptr) _((char *, char **));
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void (*makecompparamsptr) _((void));
|
||||||
|
|
||||||
|
/* pointers to functions required by compctl and defined by zle */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void (*addmatchesptr) _((char *, char *, char *, char *, char *, char *, char *, int, int, int, int, int, char **));
|
||||||
|
|
||||||
|
/**/
|
||||||
|
char *(*comp_strptr) _((int*,int*));
|
||||||
|
|
||||||
|
/**/
|
||||||
|
int (*getcpatptr) _((char *, int, char *, int));
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void (*makecomplistcallptr) _((Compctl));
|
||||||
|
|
||||||
|
|
||||||
/* Hash table for completion info for commands */
|
/* Hash table for completion info for commands */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
@ -72,6 +90,23 @@ char **clwords;
|
||||||
/**/
|
/**/
|
||||||
int incompctlfunc;
|
int incompctlfunc;
|
||||||
|
|
||||||
|
/* != 0 if we are in a new style completion function */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
int incompfunc;
|
||||||
|
|
||||||
|
/* global variables for shell parameters in new style completion */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
long compcurrent,
|
||||||
|
compnmatches;
|
||||||
|
|
||||||
|
/**/
|
||||||
|
char *compcontext,
|
||||||
|
*compcommand,
|
||||||
|
*compprefix,
|
||||||
|
*compsuffix,
|
||||||
|
*compiprefix;
|
||||||
|
|
||||||
/* This variable and the functions rembslash() and quotename() came from *
|
/* This variable and the functions rembslash() and quotename() came from *
|
||||||
* zle_tricky.c, but are now used in compctl.c, too. */
|
* zle_tricky.c, but are now used in compctl.c, too. */
|
||||||
|
|
@ -443,6 +478,8 @@ setup_comp1(Module m)
|
||||||
cc_first.refc = 10000;
|
cc_first.refc = 10000;
|
||||||
cc_first.mask = 0;
|
cc_first.mask = 0;
|
||||||
cc_first.mask2 = CC_CCCONT;
|
cc_first.mask2 = CC_CCCONT;
|
||||||
|
compcontext = compcommand = compprefix = compsuffix =
|
||||||
|
compiprefix = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -469,6 +506,11 @@ finish_comp1(Module m)
|
||||||
deletehashtable(compctltab);
|
deletehashtable(compctltab);
|
||||||
zfree(clwords, clwsize * sizeof(char *));
|
zfree(clwords, clwsize * sizeof(char *));
|
||||||
compctlreadptr = fallback_compctlread;
|
compctlreadptr = fallback_compctlread;
|
||||||
|
zsfree(compcontext);
|
||||||
|
zsfree(compcommand);
|
||||||
|
zsfree(compprefix);
|
||||||
|
zsfree(compiprefix);
|
||||||
|
zsfree(compsuffix);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#!
|
#!
|
||||||
|
addmatchesptr
|
||||||
cc_compos
|
cc_compos
|
||||||
cc_default
|
cc_default
|
||||||
cc_dummy
|
cc_dummy
|
||||||
|
|
@ -8,14 +9,26 @@ clwords
|
||||||
clwpos
|
clwpos
|
||||||
clwsize
|
clwsize
|
||||||
cmatcher
|
cmatcher
|
||||||
|
compcommand
|
||||||
|
compcontext
|
||||||
compctl_widgetptr
|
compctl_widgetptr
|
||||||
compctltab
|
compctltab
|
||||||
|
compcurrent
|
||||||
|
compiprefix
|
||||||
|
compnmatches
|
||||||
|
compprefix
|
||||||
|
comp_strptr
|
||||||
|
compsuffix
|
||||||
freecmatcher
|
freecmatcher
|
||||||
freecmlist
|
freecmlist
|
||||||
freecompcond
|
freecompcond
|
||||||
freecompctl
|
freecompctl
|
||||||
|
getcpatptr
|
||||||
incompctlfunc
|
incompctlfunc
|
||||||
|
incompfunc
|
||||||
instring
|
instring
|
||||||
|
makecomplistcallptr
|
||||||
|
makecompparamsptr
|
||||||
patcomps
|
patcomps
|
||||||
printcompctlptr
|
printcompctlptr
|
||||||
quotename
|
quotename
|
||||||
|
|
|
||||||
|
|
@ -373,7 +373,7 @@ parse_class(Cpattern p, unsigned char *s, unsigned char e)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
|
||||||
{
|
{
|
||||||
/* Parse the basic flags for completion:
|
/* Parse the basic flags for completion:
|
||||||
* first is a flag that we are not in extended completion,
|
* first is a flag that we are not in extended completion,
|
||||||
|
|
@ -394,12 +394,17 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
||||||
if(argv[0] && argv[0][0] == '-')
|
if(argv[0] && argv[0][0] == '-')
|
||||||
argv++;
|
argv++;
|
||||||
*av = argv;
|
*av = argv;
|
||||||
freecompctl(cc);
|
if (cl)
|
||||||
cclist = COMP_REMOVE;
|
return 1;
|
||||||
return 0;
|
else {
|
||||||
|
freecompctl(cc);
|
||||||
|
cclist = COMP_REMOVE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memset((void *)&cct, 0, sizeof(cct));
|
memset((void *)&cct, 0, sizeof(cct));
|
||||||
|
cct.mask2 = CC_CCCONT;
|
||||||
|
|
||||||
/* Loop through the flags until we have no more: *
|
/* Loop through the flags until we have no more: *
|
||||||
* those with arguments are not properly allocated yet, *
|
* those with arguments are not properly allocated yet, *
|
||||||
|
|
@ -505,6 +510,10 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
|
if (cl) {
|
||||||
|
zerrnam(name, "illegal option -%c", NULL, **argv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if ((*argv)[1]) {
|
if ((*argv)[1]) {
|
||||||
p = (*argv) + 1;
|
p = (*argv) + 1;
|
||||||
*argv = "" - 1;
|
*argv = "" - 1;
|
||||||
|
|
@ -516,26 +525,28 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
||||||
p = *++argv;
|
p = *++argv;
|
||||||
*argv = "" - 1;
|
*argv = "" - 1;
|
||||||
}
|
}
|
||||||
while (*p) {
|
switch (*p) {
|
||||||
switch (*p) {
|
case '+':
|
||||||
case '+':
|
cct.mask2 = CC_XORCONT;
|
||||||
cct.mask2 |= CC_XORCONT;
|
break;
|
||||||
break;
|
case 'n':
|
||||||
case 'c':
|
cct.mask2 = 0;
|
||||||
cct.mask2 |= CC_CCCONT;
|
break;
|
||||||
break;
|
case '-':
|
||||||
case '-':
|
cct.mask2 = CC_PATCONT;
|
||||||
cct.mask2 |= CC_PATCONT;
|
break;
|
||||||
break;
|
case 'x':
|
||||||
case 'x':
|
cct.mask2 = CC_DEFCONT;
|
||||||
cct.mask2 |= CC_DEFCONT;
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
zwarnnam(name, "invalid retry specification character `%c'",
|
||||||
zwarnnam(name, "invalid retry specification character `%c'",
|
NULL, *p);
|
||||||
NULL, *p);
|
return 1;
|
||||||
return 1;
|
}
|
||||||
}
|
if (p[1]) {
|
||||||
p++;
|
zwarnnam(name, "too many retry specification characters: `%s'",
|
||||||
|
p + 1, 0);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -645,7 +656,10 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
if ((*argv)[1]) {
|
if (cl) {
|
||||||
|
zerrnam(name, "illegal option -%c", NULL, **argv);
|
||||||
|
return 1;
|
||||||
|
} else if ((*argv)[1]) {
|
||||||
cct.subcmd = (*argv) + 1;
|
cct.subcmd = (*argv) + 1;
|
||||||
*argv = "" - 1;
|
*argv = "" - 1;
|
||||||
} else if (!argv[1]) {
|
} else if (!argv[1]) {
|
||||||
|
|
@ -745,6 +759,10 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
||||||
*argv = "" - 1;
|
*argv = "" - 1;
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
|
if (cl) {
|
||||||
|
zerrnam(name, "illegal option -%c", NULL, **argv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (first && !hx) {
|
if (first && !hx) {
|
||||||
cclist |= COMP_COMMAND;
|
cclist |= COMP_COMMAND;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -754,6 +772,10 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
|
if (cl) {
|
||||||
|
zerrnam(name, "illegal option -%c", NULL, **argv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (first && !hx) {
|
if (first && !hx) {
|
||||||
isdef = 1;
|
isdef = 1;
|
||||||
cclist |= COMP_DEFAULT;
|
cclist |= COMP_DEFAULT;
|
||||||
|
|
@ -764,7 +786,11 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
if (first && !hx) {
|
if (cl) {
|
||||||
|
zerrnam(name, "illegal option -%c", NULL, **argv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (first && !hx) {
|
||||||
cclist |= COMP_FIRST;
|
cclist |= COMP_FIRST;
|
||||||
} else {
|
} else {
|
||||||
zwarnnam(name, "misplaced first completion (-T) flag",
|
zwarnnam(name, "misplaced first completion (-T) flag",
|
||||||
|
|
@ -773,6 +799,10 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
|
if (cl) {
|
||||||
|
zerrnam(name, "illegal option -%c", NULL, **argv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (!first || hx) {
|
if (!first || hx) {
|
||||||
zwarnnam(name, "illegal use of -L flag", NULL, 0);
|
zwarnnam(name, "illegal use of -L flag", NULL, 0);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -780,6 +810,10 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
||||||
cclist |= COMP_LIST;
|
cclist |= COMP_LIST;
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
|
if (cl) {
|
||||||
|
zerrnam(name, "extended completion not allowed", NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (!argv[1]) {
|
if (!argv[1]) {
|
||||||
zwarnnam(name, "condition expected after -%c", NULL,
|
zwarnnam(name, "condition expected after -%c", NULL,
|
||||||
**argv);
|
**argv);
|
||||||
|
|
@ -811,6 +845,10 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
||||||
|
|
||||||
if (*++argv && (!ready || ready == 2) &&
|
if (*++argv && (!ready || ready == 2) &&
|
||||||
**argv == '+' && !argv[0][1]) {
|
**argv == '+' && !argv[0][1]) {
|
||||||
|
if (cl) {
|
||||||
|
zerrnam(name, "xor'ed completion illegal", NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/* There's an alternative (+) completion: assign
|
/* There's an alternative (+) completion: assign
|
||||||
* what we have so far before moving on to that.
|
* what we have so far before moving on to that.
|
||||||
*/
|
*/
|
||||||
|
|
@ -835,6 +873,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
||||||
cc->xor = (Compctl) zcalloc(sizeof(*cc));
|
cc->xor = (Compctl) zcalloc(sizeof(*cc));
|
||||||
cc = cc->xor;
|
cc = cc->xor;
|
||||||
memset((void *)&cct, 0, sizeof(cct));
|
memset((void *)&cct, 0, sizeof(cct));
|
||||||
|
cct.mask2 = CC_CCCONT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1084,7 +1123,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
|
||||||
(*next)->cond = m;
|
(*next)->cond = m;
|
||||||
argv++;
|
argv++;
|
||||||
/* End of the condition; get the flags that go with it. */
|
/* End of the condition; get the flags that go with it. */
|
||||||
if (get_compctl(name, &argv, *next, 0, isdef))
|
if (get_compctl(name, &argv, *next, 0, isdef, 0))
|
||||||
return 1;
|
return 1;
|
||||||
if ((!argv || !*argv) && (cclist & COMP_SPECIAL))
|
if ((!argv || !*argv) && (cclist & COMP_SPECIAL))
|
||||||
/* default, first, or command completion finished */
|
/* default, first, or command completion finished */
|
||||||
|
|
@ -1362,17 +1401,16 @@ printcompctl(char *s, Compctl cc, int printflags, int ispat)
|
||||||
t >>= 1;
|
t >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flags2 & (CC_XORCONT | CC_CCCONT | CC_PATCONT | CC_DEFCONT)) {
|
if (flags2 & (CC_XORCONT | CC_PATCONT | CC_DEFCONT)) {
|
||||||
printf(" -t");
|
printf(" -t");
|
||||||
if (flags2 & CC_XORCONT)
|
if (flags2 & CC_XORCONT)
|
||||||
putchar('+');
|
putchar('+');
|
||||||
if (flags2 & CC_CCCONT)
|
|
||||||
putchar('c');
|
|
||||||
if (flags2 & CC_PATCONT)
|
if (flags2 & CC_PATCONT)
|
||||||
putchar('-');
|
putchar('-');
|
||||||
if (flags2 & CC_DEFCONT)
|
if (flags2 & CC_DEFCONT)
|
||||||
putchar('x');
|
putchar('x');
|
||||||
}
|
} else if (!(flags2 & CC_CCCONT))
|
||||||
|
printf(" -tn");
|
||||||
/* now flags with arguments */
|
/* now flags with arguments */
|
||||||
printif(cc->mstr, 'M');
|
printif(cc->mstr, 'M');
|
||||||
if (flags2 & CC_NOSORT)
|
if (flags2 & CC_NOSORT)
|
||||||
|
|
@ -1518,7 +1556,7 @@ bin_compctl(char *name, char **argv, char *ops, int func)
|
||||||
return ret - 1;
|
return ret - 1;
|
||||||
|
|
||||||
cc = (Compctl) zcalloc(sizeof(*cc));
|
cc = (Compctl) zcalloc(sizeof(*cc));
|
||||||
if (get_compctl(name, &argv, cc, 1, 0)) {
|
if (get_compctl(name, &argv, cc, 1, 0, 0)) {
|
||||||
freecompctl(cc);
|
freecompctl(cc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -1610,7 +1648,7 @@ compctl_widget(char *name, char **argv)
|
||||||
cclist = 0;
|
cclist = 0;
|
||||||
showmask = 0;
|
showmask = 0;
|
||||||
|
|
||||||
if (get_compctl(name, &argv, cc, 1, 0)) {
|
if (get_compctl(name, &argv, cc, 1, 0, 0)) {
|
||||||
freecompctl(cc);
|
freecompctl(cc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -1632,8 +1670,478 @@ compctl_widget(char *name, char **argv)
|
||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
bin_complist(char *name, char **argv, char *ops, int func)
|
||||||
|
{
|
||||||
|
Compctl cc;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!incompfunc) {
|
||||||
|
zerrnam(name, "can only be called from completion function", NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cc = (Compctl) zcalloc(sizeof(*cc));
|
||||||
|
cclist = 0;
|
||||||
|
showmask = 0;
|
||||||
|
|
||||||
|
if (get_compctl(name, &argv, cc, 1, 0, 1))
|
||||||
|
ret = 1;
|
||||||
|
else if (*argv) {
|
||||||
|
zerrnam(name, "command names illegal", NULL, 0);
|
||||||
|
ret = 1;
|
||||||
|
} else
|
||||||
|
makecomplistcallptr(cc);
|
||||||
|
|
||||||
|
freecompctl(cc);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
bin_compadd(char *name, char **argv, char *ops, int func)
|
||||||
|
{
|
||||||
|
char *p, **sp, *e;
|
||||||
|
char *ipre = NULL, *ppre = NULL, *psuf = NULL, *prpre = NULL;
|
||||||
|
char *pre = NULL, *suf = NULL, *group = NULL;
|
||||||
|
int f = 0, q = 0, m = 0, ns = 0, a = 0;
|
||||||
|
|
||||||
|
if (!incompfunc) {
|
||||||
|
zerrnam(name, "can only be called from completion function", NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
for (; *argv && **argv == '-'; argv++) {
|
||||||
|
for (p = *argv + 1; *p; p++) {
|
||||||
|
sp = NULL;
|
||||||
|
switch (*p) {
|
||||||
|
case 'q':
|
||||||
|
f |= CMF_REMOVE;
|
||||||
|
break;
|
||||||
|
case 'Q':
|
||||||
|
q = 1;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
f |= CMF_FILE;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
f |= CMF_NOLIST;
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
m = 1;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
sp = ⪯
|
||||||
|
e = "string expected after -%c";
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
sp = &suf;
|
||||||
|
e = "string expected after -%c";
|
||||||
|
break;
|
||||||
|
case 'J':
|
||||||
|
sp = &group;
|
||||||
|
e = "group name expected after -%c";
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
if (!group)
|
||||||
|
ns = 1;
|
||||||
|
sp = &group;
|
||||||
|
e = "group name expected after -%c";
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
sp = &ipre;
|
||||||
|
e = "string expected after -%c";
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
sp = &ppre;
|
||||||
|
e = "string expected after -%c";
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
sp = &psuf;
|
||||||
|
e = "string expected after -%c";
|
||||||
|
break;
|
||||||
|
case 'W':
|
||||||
|
sp = &prpre;
|
||||||
|
e = "string expected after -%c";
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
a = 1;
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
argv++;
|
||||||
|
goto ca_args;
|
||||||
|
default:
|
||||||
|
zerrnam(name, "bad option: -%c", NULL, *p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (sp) {
|
||||||
|
if (*sp) {
|
||||||
|
zerrnam(name, "doubled option: -%c", NULL, *p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (p[1]) {
|
||||||
|
*sp = p + 1;
|
||||||
|
p = "" - 1;
|
||||||
|
} else if (argv[1]) {
|
||||||
|
*sp = *++argv;
|
||||||
|
p = "" - 1;
|
||||||
|
} else {
|
||||||
|
zerrnam(name, e, NULL, *p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ca_args:
|
||||||
|
if (!*argv) {
|
||||||
|
zerrnam(name, "missing completions", NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
addmatchesptr(ipre, ppre, psuf, prpre, pre, suf, group,
|
||||||
|
f, q, m, ns, a, argv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define VAR(X) ((void *) (&(X)))
|
||||||
|
static struct compparam {
|
||||||
|
char *name;
|
||||||
|
int type;
|
||||||
|
void *var;
|
||||||
|
} compparams[] = {
|
||||||
|
{ "CURRENT", PM_INTEGER, VAR(compcurrent) },
|
||||||
|
{ "CONTEXT", PM_SCALAR, VAR(compcontext) },
|
||||||
|
{ "COMMAND", PM_SCALAR, VAR(compcommand) },
|
||||||
|
{ "PREFIX", PM_SCALAR, VAR(compprefix) },
|
||||||
|
{ "SUFFIX", PM_SCALAR, VAR(compsuffix) },
|
||||||
|
{ "IPREFIX", PM_SCALAR, VAR(compiprefix) },
|
||||||
|
{ "NMATCHES", PM_INTEGER, VAR(compnmatches) },
|
||||||
|
{ NULL, 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void makecompparams(void)
|
||||||
|
{
|
||||||
|
struct compparam *cp;
|
||||||
|
|
||||||
|
for (cp = compparams; cp->name; cp++) {
|
||||||
|
Param pm = createparam(cp->name, cp->type | PM_SPECIAL);
|
||||||
|
if (!pm)
|
||||||
|
pm = (Param) paramtab->getnode(paramtab, cp->name);
|
||||||
|
DPUTS(!pm, "param not set in makecompparams");
|
||||||
|
|
||||||
|
pm->level = locallevel;
|
||||||
|
pm->u.data = cp->var;
|
||||||
|
switch(PM_TYPE(cp->type)) {
|
||||||
|
case PM_SCALAR:
|
||||||
|
pm->sets.cfn = strvarsetfn;
|
||||||
|
pm->gets.cfn = strvargetfn;
|
||||||
|
break;
|
||||||
|
case PM_INTEGER:
|
||||||
|
pm->sets.ifn = intvarsetfn;
|
||||||
|
pm->gets.ifn = intvargetfn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pm->unsetfn = compunsetfn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static void
|
||||||
|
compunsetfn(Param pm, int exp)
|
||||||
|
{
|
||||||
|
if (exp)
|
||||||
|
stdunsetfn(pm, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
comp_wrapper(List list, FuncWrap w, char *name)
|
||||||
|
{
|
||||||
|
if (!incompfunc)
|
||||||
|
return 1;
|
||||||
|
else {
|
||||||
|
char *octxt, *ocmd, *opre, *osuf, *oipre;
|
||||||
|
long ocur;
|
||||||
|
|
||||||
|
ocur = compcurrent;
|
||||||
|
octxt = dupstring(compcontext);
|
||||||
|
ocmd = dupstring(compcommand);
|
||||||
|
opre = dupstring(compprefix);
|
||||||
|
osuf = dupstring(compsuffix);
|
||||||
|
oipre = dupstring(compiprefix);
|
||||||
|
|
||||||
|
runshfunc(list, w, name);
|
||||||
|
|
||||||
|
compcurrent = ocur;
|
||||||
|
zsfree(compcontext);
|
||||||
|
compcontext = ztrdup(octxt);
|
||||||
|
zsfree(compcommand);
|
||||||
|
compcommand = ztrdup(ocmd);
|
||||||
|
zsfree(compprefix);
|
||||||
|
compprefix = ztrdup(opre);
|
||||||
|
zsfree(compsuffix);
|
||||||
|
compsuffix = ztrdup(osuf);
|
||||||
|
zsfree(compiprefix);
|
||||||
|
compiprefix = ztrdup(oipre);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static void
|
||||||
|
ignore_prefix(int l)
|
||||||
|
{
|
||||||
|
char *o, sav = compprefix[l];
|
||||||
|
|
||||||
|
compprefix[l] = '\0';
|
||||||
|
o = compiprefix;
|
||||||
|
compiprefix = tricat(o, compprefix, "");
|
||||||
|
zsfree(o);
|
||||||
|
compprefix[l] = sav;
|
||||||
|
o = compprefix;
|
||||||
|
compprefix = ztrdup(o + l);
|
||||||
|
zsfree(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
comp_check(void)
|
||||||
|
{
|
||||||
|
if (!incompfunc) {
|
||||||
|
zerr("condition can only be used in completion function", NULL, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static void
|
||||||
|
restrict_range(int b, int e)
|
||||||
|
{
|
||||||
|
int i = e - b;
|
||||||
|
char **p = (char **) zcalloc((i + 1) * sizeof(char *)), **q, **pp;
|
||||||
|
|
||||||
|
for (q = p, pp = pparams + b + 1; i; i--, q++, pp++)
|
||||||
|
*q = ztrdup(*pp);
|
||||||
|
zsfree(compcommand);
|
||||||
|
compcommand = ztrdup(pparams[b]);
|
||||||
|
freearray(pparams);
|
||||||
|
pparams = p;
|
||||||
|
zsfree(compcontext);
|
||||||
|
if ((compcurrent -= b + 1))
|
||||||
|
compcontext = ztrdup("arg");
|
||||||
|
else
|
||||||
|
compcontext = ztrdup("cmd");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
cond_prefix(char **a, int id)
|
||||||
|
{
|
||||||
|
if (comp_check())
|
||||||
|
return strpfx(cond_str(a, 0), compprefix);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
cond_iprefix(char **a, int id)
|
||||||
|
{
|
||||||
|
if (comp_check()) {
|
||||||
|
char *s = cond_str(a, 0);
|
||||||
|
|
||||||
|
if (strpfx(s, compprefix)) {
|
||||||
|
ignore_prefix(strlen(s));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
cond_position(char **a, int id)
|
||||||
|
{
|
||||||
|
if (comp_check()) {
|
||||||
|
int b = cond_val(a, 0), e = (a[1] ? cond_val(a, 1) : b);
|
||||||
|
int l = arrlen(pparams), t, i = compcurrent - 1;
|
||||||
|
|
||||||
|
if (b > 0)
|
||||||
|
b--;
|
||||||
|
if (e > 0)
|
||||||
|
e--;
|
||||||
|
if (b < 0)
|
||||||
|
b += l;
|
||||||
|
if (e < 0)
|
||||||
|
e += l;
|
||||||
|
t = (b >= 0 && e >= 0 && i >= b && i <= e && b <= e);
|
||||||
|
|
||||||
|
if (t && a[1]) {
|
||||||
|
if (b > l)
|
||||||
|
b = l;
|
||||||
|
if (e > l)
|
||||||
|
e = l;
|
||||||
|
restrict_range(b, e);
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
cond_word(char **a, int id)
|
||||||
|
{
|
||||||
|
if (comp_check()) {
|
||||||
|
int o = ((id & 2) ? compcurrent : 0) + cond_val(a, 0);
|
||||||
|
int l = arrlen(pparams);
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
if (o < 0)
|
||||||
|
o += l;
|
||||||
|
|
||||||
|
o--;
|
||||||
|
if (o < 0 || o >= l)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
s = pparams[o];
|
||||||
|
return ((id & 1) ? cond_match(a, 1, s) : !strcmp(s, cond_str(a, 1)));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
cond_strcl(char **a, int id)
|
||||||
|
{
|
||||||
|
if (comp_check()) {
|
||||||
|
char *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (a[1]) {
|
||||||
|
s = cond_str(a, 1);
|
||||||
|
i = cond_val(a, 0);
|
||||||
|
} else {
|
||||||
|
s = cond_str(a, 0);
|
||||||
|
i = -1;
|
||||||
|
}
|
||||||
|
if (!getcpatptr) {
|
||||||
|
zerr("zle not loaded, zle condition not available", NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
i = getcpatptr(comp_strptr(NULL, NULL), i, s, id);
|
||||||
|
if (i != -1) {
|
||||||
|
ignore_prefix(i);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
cond_words(char **a, int id)
|
||||||
|
{
|
||||||
|
if (comp_check()) {
|
||||||
|
int b = cond_val(a, 0), e = (a[1] ? cond_val(a, 1) : -1);
|
||||||
|
int l = arrlen(pparams);
|
||||||
|
|
||||||
|
return (l >= b && l <= e);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
cond_range(char **a, int id)
|
||||||
|
{
|
||||||
|
if (comp_check()) {
|
||||||
|
char *s, **p;
|
||||||
|
int i, l = arrlen(pparams), t = 0, b = 0, e = l - 1;
|
||||||
|
Comp c;
|
||||||
|
|
||||||
|
i = compcurrent - 1;
|
||||||
|
if (i < 0 || i >= l)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (id & 1) {
|
||||||
|
s = a[0];
|
||||||
|
singsub(&s);
|
||||||
|
c = parsereg(s);
|
||||||
|
} else
|
||||||
|
s = cond_str(a, 0);
|
||||||
|
|
||||||
|
for (i--, p = pparams + i; i >= 0; p--, i--) {
|
||||||
|
if (((id & 1) ? domatch(*p, c, 0) : !strcmp(*p, s))) {
|
||||||
|
b = i + 1;
|
||||||
|
t = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (t && (id & 2)) {
|
||||||
|
int tt = 0;
|
||||||
|
|
||||||
|
if (id & 1) {
|
||||||
|
s = a[1];
|
||||||
|
singsub(&s);
|
||||||
|
c = parsereg(s);
|
||||||
|
} else
|
||||||
|
s = cond_str(a, 1);
|
||||||
|
|
||||||
|
for (i++, p = pparams + i; i < l; p++, i++) {
|
||||||
|
if (((id & 1) ? domatch(*p, c, 0) : !strcmp(*p, s))) {
|
||||||
|
e = i - 1;
|
||||||
|
tt = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tt && i < compcurrent)
|
||||||
|
t = 0;
|
||||||
|
}
|
||||||
|
if (e < b)
|
||||||
|
t = 0;
|
||||||
|
if (t)
|
||||||
|
restrict_range(b, e);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
cond_nmatches(char **a, int id)
|
||||||
|
{
|
||||||
|
if (comp_check())
|
||||||
|
return compnmatches == cond_val(a, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct builtin bintab[] = {
|
static struct builtin bintab[] = {
|
||||||
BUILTIN("compctl", 0, bin_compctl, 0, -1, 0, NULL, NULL),
|
BUILTIN("compctl", 0, bin_compctl, 0, -1, 0, NULL, NULL),
|
||||||
|
BUILTIN("complist", 0, bin_complist, 1, -1, 0, NULL, NULL),
|
||||||
|
BUILTIN("compadd", 0, bin_compadd, 1, -1, 0, NULL, NULL),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct conddef cotab[] = {
|
||||||
|
CONDDEF("prefix", 0, cond_prefix, 1, 1, 0),
|
||||||
|
CONDDEF("iprefix", 0, cond_iprefix, 1, 1, 0),
|
||||||
|
CONDDEF("position", 0, cond_position, 1, 2, 0),
|
||||||
|
CONDDEF("word", 0, cond_word, 2, 2, 0),
|
||||||
|
CONDDEF("mword", 0, cond_word, 2, 2, 1),
|
||||||
|
CONDDEF("current", 0, cond_word, 2, 2, 2),
|
||||||
|
CONDDEF("mcurrent", 0, cond_word, 2, 2, 3),
|
||||||
|
CONDDEF("string", 0, cond_strcl, 1, 2, 0),
|
||||||
|
CONDDEF("class", 0, cond_strcl, 1, 2, 1),
|
||||||
|
CONDDEF("words", 0, cond_words, 1, 2, 0),
|
||||||
|
CONDDEF("between", 0, cond_range, 2, 2, 2),
|
||||||
|
CONDDEF("mbetween", 0, cond_range, 2, 2, 3),
|
||||||
|
CONDDEF("after", 0, cond_range, 1, 1, 0),
|
||||||
|
CONDDEF("mafter", 0, cond_range, 1, 1, 1),
|
||||||
|
CONDDEF("nmatches", 0, cond_nmatches, 1, 1, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct funcwrap wrapper[] = {
|
||||||
|
WRAPDEF(comp_wrapper),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
@ -1643,6 +2151,7 @@ setup_compctl(Module m)
|
||||||
compctltab->printnode = printcompctlp;
|
compctltab->printnode = printcompctlp;
|
||||||
printcompctlptr = printcompctl;
|
printcompctlptr = printcompctl;
|
||||||
compctl_widgetptr = compctl_widget;
|
compctl_widgetptr = compctl_widget;
|
||||||
|
makecompparamsptr = makecompparams;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1650,7 +2159,9 @@ setup_compctl(Module m)
|
||||||
int
|
int
|
||||||
boot_compctl(Module m)
|
boot_compctl(Module m)
|
||||||
{
|
{
|
||||||
if(!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)))
|
if(!(addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)) |
|
||||||
|
addconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab)) |
|
||||||
|
!addwrapper(m, wrapper)))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1662,6 +2173,8 @@ int
|
||||||
cleanup_compctl(Module m)
|
cleanup_compctl(Module m)
|
||||||
{
|
{
|
||||||
deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
|
deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
|
||||||
|
deleteconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab));
|
||||||
|
deletewrapper(m, wrapper);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1672,6 +2185,7 @@ finish_compctl(Module m)
|
||||||
compctltab->printnode = NULL;
|
compctltab->printnode = NULL;
|
||||||
printcompctlptr = NULL;
|
printcompctlptr = NULL;
|
||||||
compctl_widgetptr = NULL;
|
compctl_widgetptr = NULL;
|
||||||
|
makecompparamsptr = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
moddeps="comp1"
|
moddeps="comp1"
|
||||||
|
|
||||||
autobins="compctl"
|
autobins="compctl complist compadd"
|
||||||
|
|
||||||
|
autoprefixconds="prefix iprefix position word mword current mcurrent string class words between mbetween after mafter nmatches"
|
||||||
|
|
||||||
objects="compctl.o"
|
objects="compctl.o"
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
"beginning-of-line-hist", beginningoflinehist, 0
|
"beginning-of-line-hist", beginningoflinehist, 0
|
||||||
"capitalize-word", capitalizeword, 0
|
"capitalize-word", capitalizeword, 0
|
||||||
"clear-screen", clearscreen, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
|
"clear-screen", clearscreen, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
|
||||||
"complete-word", completeword, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
"complete-word", completeword, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP
|
||||||
"copy-prev-word", copyprevword, 0
|
"copy-prev-word", copyprevword, 0
|
||||||
"copy-region-as-kill", copyregionaskill, ZLE_KEEPSUFFIX
|
"copy-region-as-kill", copyregionaskill, ZLE_KEEPSUFFIX
|
||||||
"delete-char", deletechar, ZLE_KEEPSUFFIX
|
"delete-char", deletechar, ZLE_KEEPSUFFIX
|
||||||
"delete-char-or-list", deletecharorlist, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
"delete-char-or-list", deletecharorlist, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP
|
||||||
"delete-word", deleteword, ZLE_KEEPSUFFIX
|
"delete-word", deleteword, ZLE_KEEPSUFFIX
|
||||||
"describe-key-briefly", describekeybriefly, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
"describe-key-briefly", describekeybriefly, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
||||||
"digit-argument", digitargument, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
|
"digit-argument", digitargument, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
|
||||||
|
|
@ -48,8 +48,8 @@
|
||||||
"execute-named-cmd", NULL, 0
|
"execute-named-cmd", NULL, 0
|
||||||
"expand-cmd-path", expandcmdpath, 0
|
"expand-cmd-path", expandcmdpath, 0
|
||||||
"expand-history", expandhistory, 0
|
"expand-history", expandhistory, 0
|
||||||
"expand-or-complete", expandorcomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
"expand-or-complete", expandorcomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP
|
||||||
"expand-or-complete-prefix", expandorcompleteprefix, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
"expand-or-complete-prefix", expandorcompleteprefix, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP
|
||||||
"expand-word", expandword, 0
|
"expand-word", expandword, 0
|
||||||
"forward-char", forwardchar, 0
|
"forward-char", forwardchar, 0
|
||||||
"forward-word", forwardword, 0
|
"forward-word", forwardword, 0
|
||||||
|
|
@ -68,11 +68,11 @@
|
||||||
"kill-region", killregion, ZLE_KILL | ZLE_KEEPSUFFIX
|
"kill-region", killregion, ZLE_KILL | ZLE_KEEPSUFFIX
|
||||||
"kill-whole-line", killwholeline, ZLE_KILL | ZLE_KEEPSUFFIX
|
"kill-whole-line", killwholeline, ZLE_KILL | ZLE_KEEPSUFFIX
|
||||||
"kill-word", killword, ZLE_KILL | ZLE_KEEPSUFFIX
|
"kill-word", killword, ZLE_KILL | ZLE_KEEPSUFFIX
|
||||||
"list-choices", listchoices, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
"list-choices", listchoices, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_ISCOMP
|
||||||
"list-expand", listexpand, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
"list-expand", listexpand, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
||||||
"magic-space", magicspace, 0
|
"magic-space", magicspace, 0
|
||||||
"menu-complete", menucomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
"menu-complete", menucomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP
|
||||||
"menu-expand-or-complete", menuexpandorcomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
"menu-expand-or-complete", menuexpandorcomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP
|
||||||
"neg-argument", negargument, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
|
"neg-argument", negargument, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
|
||||||
"overwrite-mode", overwritemode, 0
|
"overwrite-mode", overwritemode, 0
|
||||||
"pound-insert", poundinsert, 0
|
"pound-insert", poundinsert, 0
|
||||||
|
|
@ -84,7 +84,7 @@
|
||||||
"quote-region", quoteregion, 0
|
"quote-region", quoteregion, 0
|
||||||
"redisplay", redisplay, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
"redisplay", redisplay, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
||||||
"redo", redo, 0
|
"redo", redo, 0
|
||||||
"reverse-menu-complete", reversemenucomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
"reverse-menu-complete", reversemenucomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP
|
||||||
"run-help", processcmd, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
"run-help", processcmd, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
||||||
"self-insert", selfinsert, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
"self-insert", selfinsert, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
||||||
"self-insert-unmeta", selfinsertunmeta, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
"self-insert-unmeta", selfinsertunmeta, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
||||||
|
|
|
||||||
|
|
@ -47,23 +47,29 @@ struct widget {
|
||||||
ZleIntFunc fn; /* pointer to internally implemented widget */
|
ZleIntFunc fn; /* pointer to internally implemented widget */
|
||||||
char *fnnam; /* name of the shell function for user-defined widget */
|
char *fnnam; /* name of the shell function for user-defined widget */
|
||||||
Compctl cc; /* for use with a WIDGET_COMP widget */
|
Compctl cc; /* for use with a WIDGET_COMP widget */
|
||||||
|
struct {
|
||||||
|
ZleIntFunc fn; /* internal widget function to call */
|
||||||
|
char *wid; /* name of widget to call */
|
||||||
|
char *func; /* name of shell function to call */
|
||||||
|
} comp;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WIDGET_INT (1<<0) /* widget is internally implemented */
|
#define WIDGET_INT (1<<0) /* widget is internally implemented */
|
||||||
#define WIDGET_COMP (1<<1) /* Special completion widget */
|
#define WIDGET_COMP (1<<1) /* Special completion widget */
|
||||||
#define ZLE_MENUCMP (1<<2) /* DON'T invalidate completion list */
|
#define WIDGET_NCOMP (1<<2) /* new style completion widget */
|
||||||
#define ZLE_YANK (1<<3)
|
#define ZLE_MENUCMP (1<<3) /* DON'T invalidate completion list */
|
||||||
#define ZLE_LINEMOVE (1<<4) /* command is a line-oriented movement */
|
#define ZLE_YANK (1<<4)
|
||||||
#define ZLE_LASTCOL (1<<5) /* command maintains lastcol correctly */
|
#define ZLE_LINEMOVE (1<<5) /* command is a line-oriented movement */
|
||||||
#define ZLE_KILL (1<<6)
|
#define ZLE_LASTCOL (1<<6) /* command maintains lastcol correctly */
|
||||||
|
#define ZLE_KILL (1<<7)
|
||||||
#define ZLE_KEEPSUFFIX (1<<9) /* DON'T remove added suffix */
|
#define ZLE_KEEPSUFFIX (1<<9) /* DON'T remove added suffix */
|
||||||
#define ZLE_USEMENU (1<<10) /* Do ) use menu completion for */
|
#define ZLE_USEMENU (1<<10) /* Do ) use menu completion for */
|
||||||
#define ZLE_NOMENU (1<<11) /* Don't ) widget, else use default */
|
#define ZLE_NOMENU (1<<11) /* Don't ) widget, else use default */
|
||||||
#define ZLE_USEGLOB (1<<12) /* Do ) use glob completion for */
|
#define ZLE_USEGLOB (1<<12) /* Do ) use glob completion for */
|
||||||
#define ZLE_NOGLOB (1<<13) /* Don't ) widget, else use default */
|
#define ZLE_NOGLOB (1<<13) /* Don't ) widget, else use default */
|
||||||
#define ZLE_NOTCOMMAND (1<<14) /* widget should not alter lastcmd */
|
#define ZLE_NOTCOMMAND (1<<14) /* widget should not alter lastcmd */
|
||||||
|
#define ZLE_ISCOMP (1<<15) /* usable for new style completion */
|
||||||
/* thingies */
|
/* thingies */
|
||||||
|
|
||||||
struct thingy {
|
struct thingy {
|
||||||
|
|
|
||||||
|
|
@ -598,10 +598,10 @@ bin_bindkey(char *name, char **argv, char *ops, int func)
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
/* select operation and ensure no clashing arguments */
|
/* select operation and ensure no clashing arguments */
|
||||||
for(op = opns; op->o && !ops[op->o]; op++) ;
|
for(op = opns; op->o && !ops[STOUC(op->o)]; op++) ;
|
||||||
if(op->o)
|
if(op->o)
|
||||||
for(opp = op; (++opp)->o; )
|
for(opp = op; (++opp)->o; )
|
||||||
if(ops[opp->o]) {
|
if(ops[STOUC(opp->o)]) {
|
||||||
zwarnnam(name, "incompatible operation selection options",
|
zwarnnam(name, "incompatible operation selection options",
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
||||||
|
|
@ -443,9 +443,9 @@ zleread(char *lp, char *rp, int ha)
|
||||||
insmode = unset(OVERSTRIKE);
|
insmode = unset(OVERSTRIKE);
|
||||||
eofsent = 0;
|
eofsent = 0;
|
||||||
resetneeded = 0;
|
resetneeded = 0;
|
||||||
lpptbuf = promptexpand(lp, 1, NULL, NULL);
|
lpromptbuf = promptexpand(lp, 1, NULL, NULL);
|
||||||
pmpt_attr = txtchange;
|
pmpt_attr = txtchange;
|
||||||
rpptbuf = promptexpand(rp, 1, NULL, NULL);
|
rpromptbuf = promptexpand(rp, 1, NULL, NULL);
|
||||||
rpmpt_attr = txtchange;
|
rpmpt_attr = txtchange;
|
||||||
histallowed = ha;
|
histallowed = ha;
|
||||||
PERMALLOC {
|
PERMALLOC {
|
||||||
|
|
@ -529,8 +529,8 @@ zleread(char *lp, char *rp, int ha)
|
||||||
statusline = NULL;
|
statusline = NULL;
|
||||||
invalidatelist();
|
invalidatelist();
|
||||||
trashzle();
|
trashzle();
|
||||||
free(lpptbuf);
|
free(lpromptbuf);
|
||||||
free(rpptbuf);
|
free(rpromptbuf);
|
||||||
zleactive = 0;
|
zleactive = 0;
|
||||||
alarm(0);
|
alarm(0);
|
||||||
} LASTALLOC;
|
} LASTALLOC;
|
||||||
|
|
@ -565,13 +565,14 @@ execzlefunc(Thingy func)
|
||||||
showmsg(msg);
|
showmsg(msg);
|
||||||
zsfree(msg);
|
zsfree(msg);
|
||||||
feep();
|
feep();
|
||||||
} else if((w = func->widget)->flags & (WIDGET_INT|WIDGET_COMP)) {
|
} else if((w = func->widget)->flags &
|
||||||
|
(WIDGET_INT|WIDGET_COMP | WIDGET_NCOMP)) {
|
||||||
int wflags = w->flags;
|
int wflags = w->flags;
|
||||||
|
|
||||||
if(!(wflags & ZLE_KEEPSUFFIX))
|
if(!(wflags & ZLE_KEEPSUFFIX))
|
||||||
removesuffix();
|
removesuffix();
|
||||||
if(!(wflags & ZLE_MENUCMP) ||
|
if(!(wflags & ZLE_MENUCMP) ||
|
||||||
((wflags & WIDGET_COMP) && compwidget != w)) {
|
((wflags & (WIDGET_COMP|WIDGET_NCOMP)) && compwidget != w)) {
|
||||||
/* If we are doing a special completion, and the widget
|
/* If we are doing a special completion, and the widget
|
||||||
* is not the one currently in use for special completion,
|
* is not the one currently in use for special completion,
|
||||||
* we are starting a new completion.
|
* we are starting a new completion.
|
||||||
|
|
@ -586,6 +587,9 @@ execzlefunc(Thingy func)
|
||||||
if (wflags & WIDGET_COMP) {
|
if (wflags & WIDGET_COMP) {
|
||||||
compwidget = w;
|
compwidget = w;
|
||||||
completespecial();
|
completespecial();
|
||||||
|
} else if (wflags & WIDGET_NCOMP) {
|
||||||
|
compwidget = w;
|
||||||
|
completecall();
|
||||||
} else
|
} else
|
||||||
w->u.fn();
|
w->u.fn();
|
||||||
if (!(wflags & ZLE_NOTCOMMAND))
|
if (!(wflags & ZLE_NOTCOMMAND))
|
||||||
|
|
@ -855,7 +859,7 @@ trashzle(void)
|
||||||
static struct builtin bintab[] = {
|
static struct builtin bintab[] = {
|
||||||
BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaMldDANmrsLR", NULL),
|
BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaMldDANmrsLR", NULL),
|
||||||
BUILTIN("vared", 0, bin_vared, 1, 7, 0, NULL, NULL),
|
BUILTIN("vared", 0, bin_vared, 1, 7, 0, NULL, NULL),
|
||||||
BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgG", NULL),
|
BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgGc", NULL),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
@ -869,6 +873,11 @@ setup_zle(Module m)
|
||||||
spaceinlineptr = spaceinline;
|
spaceinlineptr = spaceinline;
|
||||||
zlereadptr = zleread;
|
zlereadptr = zleread;
|
||||||
|
|
||||||
|
addmatchesptr = addmatches;
|
||||||
|
comp_strptr = comp_str;
|
||||||
|
getcpatptr = getcpat;
|
||||||
|
makecomplistcallptr = makecomplistcall;
|
||||||
|
|
||||||
/* initialise the thingies */
|
/* initialise the thingies */
|
||||||
init_thingies();
|
init_thingies();
|
||||||
|
|
||||||
|
|
@ -931,6 +940,11 @@ finish_zle(Module m)
|
||||||
spaceinlineptr = noop_function_int;
|
spaceinlineptr = noop_function_int;
|
||||||
zlereadptr = fallback_zleread;
|
zlereadptr = fallback_zleread;
|
||||||
|
|
||||||
|
addmatchesptr = NULL;
|
||||||
|
comp_strptr = NULL;
|
||||||
|
getcpatptr = NULL;
|
||||||
|
makecomplistcallptr = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@
|
||||||
/* Expanded prompts */
|
/* Expanded prompts */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
char *lpptbuf, *rpptbuf;
|
char *lpromptbuf, *rpromptbuf;
|
||||||
|
|
||||||
/* Text attributes after displaying prompts */
|
/* Text attributes after displaying prompts */
|
||||||
|
|
||||||
|
|
@ -77,17 +77,17 @@ int cost;
|
||||||
/* Oct/Nov 94: <mason> some code savagely redesigned to fix several bugs -
|
/* Oct/Nov 94: <mason> some code savagely redesigned to fix several bugs -
|
||||||
refreshline() & tc_rightcurs() majorly rewritten; zrefresh() fixed -
|
refreshline() & tc_rightcurs() majorly rewritten; zrefresh() fixed -
|
||||||
I've put my fingers into just about every routine in here -
|
I've put my fingers into just about every routine in here -
|
||||||
any queries about updates to mason@werple.net.au */
|
any queries about updates to mason@primenet.com.au */
|
||||||
|
|
||||||
static char **nbuf = NULL, /* new video buffer line-by-line char array */
|
static char **nbuf = NULL, /* new video buffer line-by-line char array */
|
||||||
**obuf = NULL; /* old video buffer line-by-line char array */
|
**obuf = NULL; /* old video buffer line-by-line char array */
|
||||||
static int more_start, /* more text before start of screen? */
|
static int more_start, /* more text before start of screen? */
|
||||||
more_end, /* more stuff after end of screen? */
|
more_end, /* more stuff after end of screen? */
|
||||||
lppth, /* lines taken up by the prompt */
|
|
||||||
olnct, /* previous number of lines */
|
olnct, /* previous number of lines */
|
||||||
ovln, /* previous video cursor position line */
|
ovln, /* previous video cursor position line */
|
||||||
pptw, rpw, /* prompt widths on screen */
|
lpromptw, rpromptw, /* prompt widths on screen */
|
||||||
rppth, /* right prompt height */
|
lprompth, /* lines taken up by the prompt */
|
||||||
|
rprompth, /* right prompt height */
|
||||||
vcs, vln, /* video cursor position column & line */
|
vcs, vln, /* video cursor position column & line */
|
||||||
vmaxln, /* video maximum number of lines */
|
vmaxln, /* video maximum number of lines */
|
||||||
winw, winh, rwinh, /* window width & height */
|
winw, winh, rwinh, /* window width & height */
|
||||||
|
|
@ -100,7 +100,6 @@ resetvideo(void)
|
||||||
int ln;
|
int ln;
|
||||||
static int lwinw = -1, lwinh = -1; /* last window width & height */
|
static int lwinw = -1, lwinh = -1; /* last window width & height */
|
||||||
|
|
||||||
genprompts();
|
|
||||||
winw = columns; /* terminal width */
|
winw = columns; /* terminal width */
|
||||||
if (termflags & TERM_SHORT)
|
if (termflags & TERM_SHORT)
|
||||||
winh = 1;
|
winh = 1;
|
||||||
|
|
@ -132,13 +131,16 @@ resetvideo(void)
|
||||||
*obuf[ln] = '\0';
|
*obuf[ln] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pptw) {
|
countprompt(lpromptbuf, &lpromptw, &lprompth);
|
||||||
memset(nbuf[0], ' ', pptw);
|
countprompt(rpromptbuf, &rpromptw, &rprompth);
|
||||||
memset(obuf[0], ' ', pptw);
|
|
||||||
nbuf[0][pptw] = obuf[0][pptw] = '\0';
|
if (lpromptw) {
|
||||||
|
memset(nbuf[0], ' ', lpromptw);
|
||||||
|
memset(obuf[0], ' ', lpromptw);
|
||||||
|
nbuf[0][lpromptw] = obuf[0][lpromptw] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
vcs = pptw;
|
vcs = lpromptw;
|
||||||
olnct = nlnct = 0;
|
olnct = nlnct = 0;
|
||||||
if (showinglist > 0)
|
if (showinglist > 0)
|
||||||
showinglist = -2;
|
showinglist = -2;
|
||||||
|
|
@ -280,21 +282,25 @@ zrefresh(void)
|
||||||
tsetcap(TCSTANDOUTEND, 0);
|
tsetcap(TCSTANDOUTEND, 0);
|
||||||
tsetcap(TCUNDERLINEEND, 0);
|
tsetcap(TCUNDERLINEEND, 0);
|
||||||
|
|
||||||
if (!clearflag)
|
if (!clearflag) {
|
||||||
if (tccan(TCCLEAREOD))
|
if (tccan(TCCLEAREOD))
|
||||||
tcout(TCCLEAREOD);
|
tcout(TCCLEAREOD);
|
||||||
else
|
else
|
||||||
cleareol = 1; /* request: clear to end of line */
|
cleareol = 1; /* request: clear to end of line */
|
||||||
|
}
|
||||||
if (t0 > -1)
|
if (t0 > -1)
|
||||||
olnct = t0;
|
olnct = t0;
|
||||||
if (termflags & TERM_SHORT)
|
if (termflags & TERM_SHORT)
|
||||||
vcs = 0;
|
vcs = 0;
|
||||||
else if (!clearflag && lpptbuf[0])
|
else if (!clearflag && lpromptbuf[0]) {
|
||||||
zputs(lpptbuf, shout);
|
zputs(lpromptbuf, shout);
|
||||||
|
if (lpromptw == 0)
|
||||||
|
zputs("\n", shout); /* works with both hasam and !hasam */
|
||||||
|
}
|
||||||
if (clearflag) {
|
if (clearflag) {
|
||||||
zputc('\r', shout);
|
zputc('\r', shout);
|
||||||
vcs = 0;
|
vcs = 0;
|
||||||
moveto(0, pptw);
|
moveto(0, lpromptw);
|
||||||
}
|
}
|
||||||
fflush(shout);
|
fflush(shout);
|
||||||
clearf = clearflag;
|
clearf = clearflag;
|
||||||
|
|
@ -326,7 +332,7 @@ zrefresh(void)
|
||||||
if (!*nbuf)
|
if (!*nbuf)
|
||||||
*nbuf = (char *)zalloc(winw + 2);
|
*nbuf = (char *)zalloc(winw + 2);
|
||||||
|
|
||||||
s = (unsigned char *)(nbuf[ln = 0] + pptw);
|
s = (unsigned char *)(nbuf[ln = 0] + lpromptw);
|
||||||
t = line;
|
t = line;
|
||||||
sen = (unsigned char *)(*nbuf + winw);
|
sen = (unsigned char *)(*nbuf + winw);
|
||||||
for (; t < line+ll; t++) {
|
for (; t < line+ll; t++) {
|
||||||
|
|
@ -425,15 +431,16 @@ zrefresh(void)
|
||||||
|
|
||||||
/* determine whether the right-prompt exists and can fit on the screen */
|
/* determine whether the right-prompt exists and can fit on the screen */
|
||||||
if (!more_start)
|
if (!more_start)
|
||||||
put_rpmpt = rppth == 1 && rpptbuf[0] && !strchr(rpptbuf, '\t') &&
|
put_rpmpt = rprompth == 1 && rpromptbuf[0] &&
|
||||||
(int)strlen(nbuf[0]) + rpw < winw - 1;
|
!strchr(rpromptbuf, '\t') &&
|
||||||
|
(int)strlen(nbuf[0]) + rpromptw < winw - 1;
|
||||||
else {
|
else {
|
||||||
/* insert >.... on first line if there is more text before start of screen */
|
/* insert >.... on first line if there is more text before start of screen */
|
||||||
memset(nbuf[0], ' ', pptw);
|
memset(nbuf[0], ' ', lpromptw);
|
||||||
t0 = winw - pptw;
|
t0 = winw - lpromptw;
|
||||||
t0 = t0 > 5 ? 5 : t0;
|
t0 = t0 > 5 ? 5 : t0;
|
||||||
strncpy(nbuf[0] + pptw, ">....", t0);
|
strncpy(nbuf[0] + lpromptw, ">....", t0);
|
||||||
memset(nbuf[0] + pptw + t0, ' ', winw - t0 - pptw);
|
memset(nbuf[0] + lpromptw + t0, ' ', winw - t0 - lpromptw);
|
||||||
nbuf[0][winw] = nbuf[0][winw + 1] = '\0';
|
nbuf[0][winw] = nbuf[0][winw + 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -477,8 +484,8 @@ zrefresh(void)
|
||||||
|
|
||||||
/* output the right-prompt if appropriate */
|
/* output the right-prompt if appropriate */
|
||||||
if (put_rpmpt && !ln && !oput_rpmpt) {
|
if (put_rpmpt && !ln && !oput_rpmpt) {
|
||||||
moveto(0, winw - 1 - rpw);
|
moveto(0, winw - 1 - rpromptw);
|
||||||
zputs(rpptbuf, shout);
|
zputs(rpromptbuf, shout);
|
||||||
vcs = winw - 1;
|
vcs = winw - 1;
|
||||||
/* reset character attributes to that set by the main prompt */
|
/* reset character attributes to that set by the main prompt */
|
||||||
txtchange = pmpt_attr;
|
txtchange = pmpt_attr;
|
||||||
|
|
@ -659,12 +666,12 @@ refreshline(int ln)
|
||||||
/* 2c: if we're on the first line, start checking at the end of the prompt;
|
/* 2c: if we're on the first line, start checking at the end of the prompt;
|
||||||
we shouldn't be doing anything within the prompt */
|
we shouldn't be doing anything within the prompt */
|
||||||
|
|
||||||
if (ln == 0 && pptw) {
|
if (ln == 0 && lpromptw) {
|
||||||
i = pptw - ccs;
|
i = lpromptw - ccs;
|
||||||
j = strlen(ol);
|
j = strlen(ol);
|
||||||
nl += i;
|
nl += i;
|
||||||
ol += (i > j ? j : i); /* if ol is too short, point it to '\0' */
|
ol += (i > j ? j : i); /* if ol is too short, point it to '\0' */
|
||||||
ccs = pptw;
|
ccs = lpromptw;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 3: main display loop - write out the buffer using whatever tricks we can */
|
/* 3: main display loop - write out the buffer using whatever tricks we can */
|
||||||
|
|
@ -815,7 +822,7 @@ moveto(int ln, int cl)
|
||||||
instead of TCDOWN */
|
instead of TCDOWN */
|
||||||
|
|
||||||
while (ln > vln) {
|
while (ln > vln) {
|
||||||
if (vln < vmaxln - 1)
|
if (vln < vmaxln - 1) {
|
||||||
if (ln > vmaxln - 1) {
|
if (ln > vmaxln - 1) {
|
||||||
if (tc_downcurs(vmaxln - 1 - vln))
|
if (tc_downcurs(vmaxln - 1 - vln))
|
||||||
vcs = 0;
|
vcs = 0;
|
||||||
|
|
@ -826,6 +833,7 @@ moveto(int ln, int cl)
|
||||||
vln = ln;
|
vln = ln;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
zputc('\r', shout), vcs = 0; /* safety precaution */
|
zputc('\r', shout), vcs = 0; /* safety precaution */
|
||||||
while (ln > vln) {
|
while (ln > vln) {
|
||||||
zputc('\n', shout);
|
zputc('\n', shout);
|
||||||
|
|
@ -893,21 +901,23 @@ tc_rightcurs(int cl)
|
||||||
|
|
||||||
/* otherwise _carefully_ write the contents of the video buffer.
|
/* otherwise _carefully_ write the contents of the video buffer.
|
||||||
if we're anywhere in the prompt, goto the left column and write the whole
|
if we're anywhere in the prompt, goto the left column and write the whole
|
||||||
prompt out unless ztrlen(lpptbuf) == pptw : we can cheat then */
|
prompt out unless ztrlen(lpromptbuf) == lpromptw : we can cheat then */
|
||||||
if (vln == 0 && i < pptw) {
|
if (vln == 0 && i < lpromptw) {
|
||||||
if (strlen(lpptbuf) == pptw)
|
if (strlen(lpromptbuf) == lpromptw)
|
||||||
fputs(lpptbuf + i, shout);
|
fputs(lpromptbuf + i, shout);
|
||||||
else if (tccan(TCRIGHT) && (tclen[TCRIGHT] * ct <= ztrlen(lpptbuf)))
|
else if (tccan(TCRIGHT) && (tclen[TCRIGHT] * ct <= ztrlen(lpromptbuf)))
|
||||||
/* it is cheaper to send TCRIGHT than reprint the whole prompt */
|
/* it is cheaper to send TCRIGHT than reprint the whole prompt */
|
||||||
for (ct = pptw - i; ct--; )
|
for (ct = lpromptw - i; ct--; )
|
||||||
tcout(TCRIGHT);
|
tcout(TCRIGHT);
|
||||||
else {
|
else {
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
zputc('\r', shout);
|
zputc('\r', shout);
|
||||||
tc_upcurs(lppth - 1);
|
tc_upcurs(lprompth - 1);
|
||||||
zputs(lpptbuf, shout);
|
zputs(lpromptbuf, shout);
|
||||||
|
if (lpromptw == 0)
|
||||||
|
zputs("\n", shout); /* works with both hasam and !hasam */
|
||||||
}
|
}
|
||||||
i = pptw;
|
i = lpromptw;
|
||||||
ct = cl - i;
|
ct = cl - i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -969,7 +979,7 @@ redisplay(void)
|
||||||
{
|
{
|
||||||
moveto(0, 0);
|
moveto(0, 0);
|
||||||
zputc('\r', shout); /* extra care */
|
zputc('\r', shout); /* extra care */
|
||||||
tc_upcurs(lppth - 1);
|
tc_upcurs(lprompth - 1);
|
||||||
resetneeded = 1;
|
resetneeded = 1;
|
||||||
clearflag = 0;
|
clearflag = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -987,7 +997,7 @@ singlerefresh(void)
|
||||||
|
|
||||||
nlnct = 1;
|
nlnct = 1;
|
||||||
/* generate the new line buffer completely */
|
/* generate the new line buffer completely */
|
||||||
for (vsiz = 1 + pptw, t0 = 0; t0 != ll; t0++, vsiz++)
|
for (vsiz = 1 + lpromptw, t0 = 0; t0 != ll; t0++, vsiz++)
|
||||||
if (line[t0] == '\t')
|
if (line[t0] == '\t')
|
||||||
vsiz = (vsiz | 7) + 1;
|
vsiz = (vsiz | 7) + 1;
|
||||||
else if (icntrl(line[t0]))
|
else if (icntrl(line[t0]))
|
||||||
|
|
@ -1002,9 +1012,10 @@ singlerefresh(void)
|
||||||
cs = 0;
|
cs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(vbuf, strchr(lpptbuf, 0) - pptw, pptw); /* only use last part of prompt */
|
/* only use last part of prompt */
|
||||||
vbuf[pptw] = '\0';
|
memcpy(vbuf, strchr(lpromptbuf, 0) - lpromptw, lpromptw);
|
||||||
vp = vbuf + pptw;
|
vbuf[lpromptw] = '\0';
|
||||||
|
vp = vbuf + lpromptw;
|
||||||
|
|
||||||
for (t0 = 0; t0 != ll; t0++) {
|
for (t0 = 0; t0 != ll; t0++) {
|
||||||
if (line[t0] == '\t')
|
if (line[t0] == '\t')
|
||||||
|
|
@ -1104,13 +1115,3 @@ singmoveto(int pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* recheck size of prompts */
|
|
||||||
|
|
||||||
/**/
|
|
||||||
static void
|
|
||||||
genprompts(void)
|
|
||||||
{
|
|
||||||
countprompt(lpptbuf, &pptw, &lppth);
|
|
||||||
countprompt(rpptbuf, &rpw, &rppth);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -246,7 +246,10 @@ freewidget(Widget w)
|
||||||
{
|
{
|
||||||
if ((w->flags & WIDGET_COMP) && w->u.cc)
|
if ((w->flags & WIDGET_COMP) && w->u.cc)
|
||||||
freecompctl(w->u.cc);
|
freecompctl(w->u.cc);
|
||||||
else if(!(w->flags & WIDGET_INT))
|
else if (w->flags & WIDGET_NCOMP) {
|
||||||
|
zsfree(w->u.comp.wid);
|
||||||
|
zsfree(w->u.comp.func);
|
||||||
|
} else if(!(w->flags & WIDGET_INT))
|
||||||
zsfree(w->u.fnnam);
|
zsfree(w->u.fnnam);
|
||||||
zfree(w, sizeof(*w));
|
zfree(w, sizeof(*w));
|
||||||
}
|
}
|
||||||
|
|
@ -337,16 +340,17 @@ bin_zle(char *name, char **args, char *ops, int func)
|
||||||
{ 'A', bin_zle_link, 2, 2 },
|
{ 'A', bin_zle_link, 2, 2 },
|
||||||
{ 'N', bin_zle_new, 1, 2 },
|
{ 'N', bin_zle_new, 1, 2 },
|
||||||
{ 'C', bin_zle_compctl, 1, -1},
|
{ 'C', bin_zle_compctl, 1, -1},
|
||||||
|
{ 'c', bin_zle_complete, 3, 3 },
|
||||||
{ 0, bin_zle_call, 0, -1 },
|
{ 0, bin_zle_call, 0, -1 },
|
||||||
};
|
};
|
||||||
struct opn const *op, *opp;
|
struct opn const *op, *opp;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
/* select operation and ensure no clashing arguments */
|
/* select operation and ensure no clashing arguments */
|
||||||
for(op = opns; op->o && !ops[op->o]; op++) ;
|
for(op = opns; op->o && !ops[STOUC(op->o)]; op++) ;
|
||||||
if(op->o)
|
if(op->o)
|
||||||
for(opp = op; (++opp)->o; )
|
for(opp = op; (++opp)->o; )
|
||||||
if(ops[opp->o]) {
|
if(ops[STOUC(opp->o)]) {
|
||||||
zerrnam(name, "incompatible operation selection options",
|
zerrnam(name, "incompatible operation selection options",
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -395,6 +399,11 @@ scanlistwidgets(HashNode hn, int list)
|
||||||
if (w->flags & WIDGET_COMP) {
|
if (w->flags & WIDGET_COMP) {
|
||||||
if (printcompctlptr && w->u.cc)
|
if (printcompctlptr && w->u.cc)
|
||||||
printcompctlptr(NULL, w->u.cc, PRINT_LIST, 0);
|
printcompctlptr(NULL, w->u.cc, PRINT_LIST, 0);
|
||||||
|
} else if (w->flags & WIDGET_NCOMP) {
|
||||||
|
fputc(' ', stdout);
|
||||||
|
quotedzputs(w->u.comp.wid, stdout);
|
||||||
|
fputc(' ', stdout);
|
||||||
|
quotedzputs(w->u.comp.func, stdout);
|
||||||
} else if(strcmp(t->nam, w->u.fnnam)) {
|
} else if(strcmp(t->nam, w->u.fnnam)) {
|
||||||
fputc(' ', stdout);
|
fputc(' ', stdout);
|
||||||
quotedzputs(w->u.fnnam, stdout);
|
quotedzputs(w->u.fnnam, stdout);
|
||||||
|
|
@ -405,6 +414,11 @@ scanlistwidgets(HashNode hn, int list)
|
||||||
fputs(" -C", stdout);
|
fputs(" -C", stdout);
|
||||||
if (printcompctlptr && w->u.cc)
|
if (printcompctlptr && w->u.cc)
|
||||||
printcompctlptr(NULL, w->u.cc, PRINT_TYPE, 0);
|
printcompctlptr(NULL, w->u.cc, PRINT_TYPE, 0);
|
||||||
|
} else if (w->flags & WIDGET_NCOMP) {
|
||||||
|
fputs(" -c ", stdout);
|
||||||
|
nicezputs(w->u.comp.wid, stdout);
|
||||||
|
fputc(' ', stdout);
|
||||||
|
nicezputs(w->u.comp.func, stdout);
|
||||||
} else if(strcmp(t->nam, w->u.fnnam)) {
|
} else if(strcmp(t->nam, w->u.fnnam)) {
|
||||||
fputs(" (", stdout);
|
fputs(" (", stdout);
|
||||||
nicezputs(w->u.fnnam, stdout);
|
nicezputs(w->u.fnnam, stdout);
|
||||||
|
|
@ -504,13 +518,41 @@ bin_zle_compctl(char *name, char **args, char *ops, char func)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
bin_zle_complete(char *name, char **args, char *ops, char func)
|
||||||
|
{
|
||||||
|
Thingy t;
|
||||||
|
Widget w, cw;
|
||||||
|
|
||||||
|
t = rthingy(args[1]);
|
||||||
|
cw = t->widget;
|
||||||
|
unrefthingy(t);
|
||||||
|
if (!(cw->flags & ZLE_ISCOMP)) {
|
||||||
|
zerrnam(name, "invalid widget `%s'", args[1], 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
w = zalloc(sizeof(*w));
|
||||||
|
w->flags = WIDGET_NCOMP|ZLE_MENUCMP|ZLE_KEEPSUFFIX;
|
||||||
|
w->first = NULL;
|
||||||
|
w->u.comp.fn = cw->u.fn;
|
||||||
|
w->u.comp.wid = ztrdup(args[1]);
|
||||||
|
w->u.comp.func = ztrdup(args[2]);
|
||||||
|
if (bindwidget(w, rthingy(args[0]))) {
|
||||||
|
freewidget(w);
|
||||||
|
zerrnam(name, "widget name `%s' is protected", args[0], 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
bin_zle_call(char *name, char **args, char *ops, char func)
|
bin_zle_call(char *name, char **args, char *ops, char func)
|
||||||
{
|
{
|
||||||
Thingy t;
|
Thingy t;
|
||||||
|
|
||||||
if(!zleactive || incompctlfunc) {
|
if(!zleactive || incompctlfunc || incompfunc) {
|
||||||
zerrnam(name, "widgets can only be called when ZLE is active",
|
zerrnam(name, "widgets can only be called when ZLE is active",
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,15 @@ struct aminfo {
|
||||||
|
|
||||||
static Aminfo ainfo, fainfo;
|
static Aminfo ainfo, fainfo;
|
||||||
|
|
||||||
|
/* This contains the name of the function to call if this is for a new *
|
||||||
|
* style completion. */
|
||||||
|
|
||||||
|
static char *compfunc = NULL;
|
||||||
|
|
||||||
|
/* The memory heap to use for new style completion generation. */
|
||||||
|
|
||||||
|
static Heap compheap;
|
||||||
|
|
||||||
/* Find out if we have to insert a tab (instead of trying to complete). */
|
/* Find out if we have to insert a tab (instead of trying to complete). */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
@ -272,6 +281,15 @@ completespecial(void)
|
||||||
docomplete(compwidget->u.cc ? COMP_WIDGET : COMP_COMPLETE);
|
docomplete(compwidget->u.cc ? COMP_WIDGET : COMP_COMPLETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void
|
||||||
|
completecall(void)
|
||||||
|
{
|
||||||
|
compfunc = compwidget->u.comp.func;
|
||||||
|
compwidget->u.comp.fn();
|
||||||
|
compfunc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
completeword(void)
|
completeword(void)
|
||||||
|
|
@ -408,11 +426,15 @@ reversemenucomplete(void)
|
||||||
void
|
void
|
||||||
acceptandmenucomplete(void)
|
acceptandmenucomplete(void)
|
||||||
{
|
{
|
||||||
|
int sl = suffixlen[' '];
|
||||||
|
|
||||||
if (!menucmp) {
|
if (!menucmp) {
|
||||||
feep();
|
feep();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cs = menuend + menuinsc;
|
cs = menupos + menulen + menuinsc;
|
||||||
|
if (sl)
|
||||||
|
backdel(sl);
|
||||||
inststrlen(" ", 1, 1);
|
inststrlen(" ", 1, 1);
|
||||||
menuinsc = menulen = 0;
|
menuinsc = menulen = 0;
|
||||||
menupos = cs;
|
menupos = cs;
|
||||||
|
|
@ -439,6 +461,13 @@ static int lastambig;
|
||||||
|
|
||||||
static char *cmdstr;
|
static char *cmdstr;
|
||||||
|
|
||||||
|
/* This hold the name of the variable we are working on. */
|
||||||
|
|
||||||
|
static char *varname;
|
||||||
|
|
||||||
|
/* != 0 if we are in a subscript */
|
||||||
|
|
||||||
|
static int insubscr;
|
||||||
|
|
||||||
/* Check if the given string is the name of a parameter and if this *
|
/* Check if the given string is the name of a parameter and if this *
|
||||||
* parameter is one worth expanding. */
|
* parameter is one worth expanding. */
|
||||||
|
|
@ -614,16 +643,13 @@ docomplete(int lst)
|
||||||
lst = COMP_EXPAND;
|
lst = COMP_EXPAND;
|
||||||
else {
|
else {
|
||||||
int t0, n = 0;
|
int t0, n = 0;
|
||||||
char *fc;
|
|
||||||
struct hashnode *hn;
|
struct hashnode *hn;
|
||||||
|
|
||||||
for (t0 = cmdnamtab->hsize - 1; t0 >= 0; t0--)
|
for (t0 = cmdnamtab->hsize - 1; t0 >= 0; t0--)
|
||||||
for (hn = cmdnamtab->nodes[t0]; hn;
|
for (hn = cmdnamtab->nodes[t0]; hn;
|
||||||
hn = hn->next) {
|
hn = hn->next) {
|
||||||
if (strpfx(q, hn->nam) && (fc = findcmd(hn->nam))) {
|
if (strpfx(q, hn->nam) && findcmd(hn->nam, 0))
|
||||||
zsfree(fc);
|
|
||||||
n++;
|
n++;
|
||||||
}
|
|
||||||
if (n == 2)
|
if (n == 2)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -889,7 +915,7 @@ unmetafy_line(void)
|
||||||
static char *
|
static char *
|
||||||
get_comp_string(void)
|
get_comp_string(void)
|
||||||
{
|
{
|
||||||
int t0, tt0, i, j, k, cp, rd, sl, ocs;
|
int t0, tt0, i, j, k, cp, rd, sl, ocs, ins, oins;
|
||||||
char *s = NULL, *linptr, *tmp, *p, *tt = NULL;
|
char *s = NULL, *linptr, *tmp, *p, *tt = NULL;
|
||||||
|
|
||||||
zsfree(brbeg);
|
zsfree(brbeg);
|
||||||
|
|
@ -943,13 +969,16 @@ get_comp_string(void)
|
||||||
linredir = inredir;
|
linredir = inredir;
|
||||||
zsfree(cmdstr);
|
zsfree(cmdstr);
|
||||||
cmdstr = NULL;
|
cmdstr = NULL;
|
||||||
|
zsfree(varname);
|
||||||
|
varname = NULL;
|
||||||
|
insubscr = 0;
|
||||||
zleparse = 1;
|
zleparse = 1;
|
||||||
clwpos = -1;
|
clwpos = -1;
|
||||||
lexsave();
|
lexsave();
|
||||||
inpush(dupstrspace((char *) linptr), 0, NULL);
|
inpush(dupstrspace((char *) linptr), 0, NULL);
|
||||||
strinbeg();
|
strinbeg();
|
||||||
stophist = 2;
|
stophist = 2;
|
||||||
i = tt0 = cp = rd = 0;
|
i = tt0 = cp = rd = ins = oins = 0;
|
||||||
|
|
||||||
/* This loop is possibly the wrong way to do this. It goes through *
|
/* This loop is possibly the wrong way to do this. It goes through *
|
||||||
* the previously massaged command line using the lexer. It stores *
|
* the previously massaged command line using the lexer. It stores *
|
||||||
|
|
@ -963,8 +992,10 @@ get_comp_string(void)
|
||||||
* this would be to pass the command line through the parser too, *
|
* this would be to pass the command line through the parser too, *
|
||||||
* and get the arguments that way. Maybe in 3.1... */
|
* and get the arguments that way. Maybe in 3.1... */
|
||||||
do {
|
do {
|
||||||
lincmd = incmdpos;
|
lincmd = ((incmdpos && !ins) || (oins == 2 && i == 2) ||
|
||||||
linredir = inredir;
|
(ins == 3 && i == 1));
|
||||||
|
linredir = (inredir && !ins);
|
||||||
|
oins = ins;
|
||||||
/* Get the next token. */
|
/* Get the next token. */
|
||||||
ctxtlex();
|
ctxtlex();
|
||||||
if (tok == DINPAR)
|
if (tok == DINPAR)
|
||||||
|
|
@ -973,7 +1004,9 @@ get_comp_string(void)
|
||||||
/* We reached the end. */
|
/* We reached the end. */
|
||||||
if (tok == ENDINPUT)
|
if (tok == ENDINPUT)
|
||||||
break;
|
break;
|
||||||
if (tok == BAR || tok == AMPER ||
|
if ((ins && (tok == DO || tok == SEPER)) ||
|
||||||
|
(ins == 2 && i == 2) || (ins == 3 && i == 3) ||
|
||||||
|
tok == BAR || tok == AMPER ||
|
||||||
tok == BARAMP || tok == AMPERBANG ||
|
tok == BARAMP || tok == AMPERBANG ||
|
||||||
((tok == DBAR || tok == DAMPER) && !incond)) {
|
((tok == DBAR || tok == DAMPER) && !incond)) {
|
||||||
/* This is one of the things that separate commands. If we *
|
/* This is one of the things that separate commands. If we *
|
||||||
|
|
@ -982,11 +1015,13 @@ get_comp_string(void)
|
||||||
if (tt)
|
if (tt)
|
||||||
break;
|
break;
|
||||||
/* Otherwise reset the variables we are collecting data in. */
|
/* Otherwise reset the variables we are collecting data in. */
|
||||||
i = tt0 = cp = rd = 0;
|
i = tt0 = cp = rd = ins = 0;
|
||||||
}
|
}
|
||||||
if (lincmd && tok == STRING) {
|
if (lincmd && (tok == STRING || tok == FOR || tok == FOREACH ||
|
||||||
|
tok == SELECT || tok == REPEAT || tok == CASE)) {
|
||||||
/* The lexer says, this token is in command position, so *
|
/* The lexer says, this token is in command position, so *
|
||||||
* store the token string (to find the right compctl). */
|
* store the token string (to find the right compctl). */
|
||||||
|
ins = (tok == REPEAT ? 2 : (tok != STRING));
|
||||||
zsfree(cmdstr);
|
zsfree(cmdstr);
|
||||||
cmdstr = ztrdup(tokstr);
|
cmdstr = ztrdup(tokstr);
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
@ -1004,9 +1039,13 @@ get_comp_string(void)
|
||||||
rd = linredir;
|
rd = linredir;
|
||||||
if (inwhat == IN_NOTHING && incond)
|
if (inwhat == IN_NOTHING && incond)
|
||||||
inwhat = IN_COND;
|
inwhat = IN_COND;
|
||||||
}
|
} else if (linredir)
|
||||||
|
continue;
|
||||||
if (!tokstr)
|
if (!tokstr)
|
||||||
continue;
|
continue;
|
||||||
|
/* Hack to allow completion after `repeat n do'. */
|
||||||
|
if (oins == 2 && !i && !strcmp(tokstr, "do"))
|
||||||
|
ins = 3;
|
||||||
/* We need to store the token strings of all words (for some of *
|
/* We need to store the token strings of all words (for some of *
|
||||||
* the more complicated compctl -x things). They are stored in *
|
* the more complicated compctl -x things). They are stored in *
|
||||||
* the clwords array. Make this array big enough. */
|
* the clwords array. Make this array big enough. */
|
||||||
|
|
@ -1069,10 +1108,16 @@ get_comp_string(void)
|
||||||
/* We found a simple string. */
|
/* We found a simple string. */
|
||||||
s = ztrdup(clwords[clwpos]);
|
s = ztrdup(clwords[clwpos]);
|
||||||
} else if (t0 == ENVSTRING) {
|
} else if (t0 == ENVSTRING) {
|
||||||
|
char sav;
|
||||||
/* The cursor was inside a parameter assignment. */
|
/* The cursor was inside a parameter assignment. */
|
||||||
for (s = tt; iident(*s); s++);
|
for (s = tt; iident(*s); s++);
|
||||||
|
sav = *s;
|
||||||
|
*s = '\0';
|
||||||
|
zsfree(varname);
|
||||||
|
varname = ztrdup(tt);
|
||||||
|
*s = sav;
|
||||||
if (skipparens(Inbrack, Outbrack, &s) > 0 || s > tt + cs - wb)
|
if (skipparens(Inbrack, Outbrack, &s) > 0 || s > tt + cs - wb)
|
||||||
s = NULL, inwhat = IN_MATH;
|
s = NULL, inwhat = IN_MATH, insubscr = 1;
|
||||||
else if (*s == '=') {
|
else if (*s == '=') {
|
||||||
s++;
|
s++;
|
||||||
wb += s - tt;
|
wb += s - tt;
|
||||||
|
|
@ -1110,14 +1155,32 @@ get_comp_string(void)
|
||||||
* foo[_ wrong (note no $). If we are in a subscript, treat it *
|
* foo[_ wrong (note no $). If we are in a subscript, treat it *
|
||||||
* as being in math. */
|
* as being in math. */
|
||||||
if (inwhat != IN_MATH) {
|
if (inwhat != IN_MATH) {
|
||||||
int i = 0;
|
int i = 0, hn = 0;
|
||||||
|
char *nb = (*s == String ? s + 1 : NULL), *ne = NULL;
|
||||||
|
|
||||||
for (tt = s; ++tt < s + cs - wb;)
|
for (tt = s; ++tt < s + cs - wb;)
|
||||||
if (*tt == Inbrack)
|
if (*tt == String) {
|
||||||
|
hn = 0;
|
||||||
|
nb = tt + 1;
|
||||||
|
} else if (*tt == Inbrack) {
|
||||||
i++;
|
i++;
|
||||||
else if (i && *tt == Outbrack)
|
if (nb && !hn) {
|
||||||
|
hn = 1;
|
||||||
|
ne = tt;
|
||||||
|
}
|
||||||
|
} else if (i && *tt == Outbrack)
|
||||||
i--;
|
i--;
|
||||||
if (i)
|
if (i) {
|
||||||
inwhat = IN_MATH;
|
inwhat = IN_MATH;
|
||||||
|
insubscr = 1;
|
||||||
|
if (hn && nb && ne) {
|
||||||
|
char sav = *ne;
|
||||||
|
*ne = '\0';
|
||||||
|
zsfree(varname);
|
||||||
|
varname = ztrdup(nb);
|
||||||
|
*ne = sav;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (inwhat == IN_MATH) {
|
if (inwhat == IN_MATH) {
|
||||||
/* In mathematical expression, we complete parameter names (even *
|
/* In mathematical expression, we complete parameter names (even *
|
||||||
|
|
@ -2336,6 +2399,119 @@ instmatch(Cmatch m)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void
|
||||||
|
addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre,
|
||||||
|
char *suf, char *group,
|
||||||
|
int flags, int quote, int menu, int nosort, int alt, char **argv)
|
||||||
|
{
|
||||||
|
char *s, *t;
|
||||||
|
int lpl, lsl, i;
|
||||||
|
Aminfo ai = (alt ? fainfo : ainfo);
|
||||||
|
Cmatch cm;
|
||||||
|
|
||||||
|
if (menu && isset(AUTOMENU))
|
||||||
|
usemenu = 1;
|
||||||
|
SWITCHHEAPS(compheap) {
|
||||||
|
HEAPALLOC {
|
||||||
|
if (ipre)
|
||||||
|
ipre = dupstring(ipre);
|
||||||
|
if (ppre) {
|
||||||
|
ppre = dupstring(ppre);
|
||||||
|
lpl = strlen(ppre);
|
||||||
|
} else
|
||||||
|
lpl = 0;
|
||||||
|
if (psuf) {
|
||||||
|
psuf = dupstring(psuf);
|
||||||
|
lsl = strlen(psuf);
|
||||||
|
} else
|
||||||
|
lsl = 0;
|
||||||
|
if (pre)
|
||||||
|
pre = dupstring(pre);
|
||||||
|
if (suf)
|
||||||
|
suf = dupstring(suf);
|
||||||
|
if (!prpre && (prpre = ppre)) {
|
||||||
|
singsub(&prpre);
|
||||||
|
untokenize(prpre);
|
||||||
|
} else
|
||||||
|
prpre = dupstring(prpre);
|
||||||
|
if (group) {
|
||||||
|
endcmgroup(NULL);
|
||||||
|
begcmgroup(group, nosort);
|
||||||
|
if (nosort)
|
||||||
|
mgroup->flags |= CGF_NOSORT;
|
||||||
|
}
|
||||||
|
if (ai->pprefix) {
|
||||||
|
if (pre)
|
||||||
|
ai->pprefix[pfxlen(ai->pprefix, pre)] = '\0';
|
||||||
|
else
|
||||||
|
ai->pprefix[0] = '\0';
|
||||||
|
} else
|
||||||
|
ai->pprefix = dupstring(pre ? pre : "");
|
||||||
|
|
||||||
|
for (; (s = *argv); argv++) {
|
||||||
|
if (ai->firstm) {
|
||||||
|
if ((i = pfxlen(ai->firstm->str, s)) < ai->prerest)
|
||||||
|
ai->prerest = i;
|
||||||
|
if ((i = sfxlen(ai->firstm->str, s)) < ai->suflen)
|
||||||
|
ai->suflen = i;
|
||||||
|
}
|
||||||
|
t = s;
|
||||||
|
if (ppre)
|
||||||
|
t = dyncat(ppre, t);
|
||||||
|
if (ipre && *ipre) {
|
||||||
|
ai->noipre = 0;
|
||||||
|
if (ai->icpl > lpl)
|
||||||
|
ai->icpl = lpl;
|
||||||
|
if (ai->icsl > lsl)
|
||||||
|
ai->icsl = lsl;
|
||||||
|
if (ai->iaprefix)
|
||||||
|
ai->iaprefix[pfxlen(ai->iaprefix, t)] = '\0';
|
||||||
|
else
|
||||||
|
ai->iaprefix = dupstring(t);
|
||||||
|
if (ai->iprefix) {
|
||||||
|
if (strcmp(ipre, ai->iprefix))
|
||||||
|
ai->iprefix = "";
|
||||||
|
} else
|
||||||
|
ai->iprefix = dupstring(ipre);
|
||||||
|
|
||||||
|
t = dyncat(ipre, t);
|
||||||
|
} else
|
||||||
|
ai->iprefix = "";
|
||||||
|
if (ai->cpl > lpl)
|
||||||
|
ai->cpl = lpl;
|
||||||
|
if (ai->csl > lsl)
|
||||||
|
ai->csl = lsl;
|
||||||
|
if (ai->aprefix)
|
||||||
|
ai->aprefix[pfxlen(ai->aprefix, t)] = '\0';
|
||||||
|
else
|
||||||
|
ai->aprefix = dupstring(t);
|
||||||
|
mnum++;
|
||||||
|
ai->count++;
|
||||||
|
|
||||||
|
cm = (Cmatch) halloc(sizeof(struct cmatch));
|
||||||
|
cm->ppre = ppre;
|
||||||
|
cm->psuf = psuf;
|
||||||
|
cm->prpre = prpre;
|
||||||
|
if (!quote)
|
||||||
|
s = quotename(s, NULL, NULL, NULL);
|
||||||
|
cm->str = dupstring(s);
|
||||||
|
cm->ipre = cm->ripre = ipre;
|
||||||
|
cm->pre = pre;
|
||||||
|
cm->suf = suf;
|
||||||
|
cm->flags = flags;
|
||||||
|
cm->brpl = brpl;
|
||||||
|
cm->brsl = brsl;
|
||||||
|
addlinknode((alt ? fmatches : matches), cm);
|
||||||
|
|
||||||
|
if (expl)
|
||||||
|
expl->fcount++;
|
||||||
|
if (!ai->firstm)
|
||||||
|
ai->firstm = cm;
|
||||||
|
}
|
||||||
|
} LASTALLOC;
|
||||||
|
} SWITCHBACKHEAPS;
|
||||||
|
}
|
||||||
|
|
||||||
/* This adds a match to the list of matches. The string to add is given *
|
/* This adds a match to the list of matches. The string to add is given *
|
||||||
* in s, the type of match is given in the global variable addwhat and *
|
* in s, the type of match is given in the global variable addwhat and *
|
||||||
|
|
@ -2351,7 +2527,7 @@ addmatch(char *s, char *t)
|
||||||
{
|
{
|
||||||
int test = 0, sl = strlen(s), pl = rpl, cc = 0, isf = 0;
|
int test = 0, sl = strlen(s), pl = rpl, cc = 0, isf = 0;
|
||||||
int mpl = 0, msl = 0, bpl = brpl, bsl = brsl;
|
int mpl = 0, msl = 0, bpl = brpl, bsl = brsl;
|
||||||
char *e = NULL, *tt, *te, *fc, *ms = NULL;
|
char *e = NULL, *tt, *te, *ms = NULL;
|
||||||
Comp cp = patcomp;
|
Comp cp = patcomp;
|
||||||
HashNode hn;
|
HashNode hn;
|
||||||
Param pm;
|
Param pm;
|
||||||
|
|
@ -2377,6 +2553,8 @@ addmatch(char *s, char *t)
|
||||||
hn = (HashNode) t;
|
hn = (HashNode) t;
|
||||||
pm = (Param) t;
|
pm = (Param) t;
|
||||||
|
|
||||||
|
if (incompfunc)
|
||||||
|
s = dupstring(s);
|
||||||
if (!addwhat) {
|
if (!addwhat) {
|
||||||
test = 1;
|
test = 1;
|
||||||
} else if (addwhat == -1 || addwhat == -5 || addwhat == -6 ||
|
} else if (addwhat == -1 || addwhat == -5 || addwhat == -6 ||
|
||||||
|
|
@ -2427,11 +2605,8 @@ addmatch(char *s, char *t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (test) {
|
if (test) {
|
||||||
fc = NULL;
|
if (addwhat == -7 && !findcmd(s, 0))
|
||||||
if (addwhat == -7 && !(fc = findcmd(s)))
|
|
||||||
return;
|
return;
|
||||||
if (fc)
|
|
||||||
zsfree(fc);
|
|
||||||
isf = CMF_FILE;
|
isf = CMF_FILE;
|
||||||
|
|
||||||
if (addwhat == CC_FILES || addwhat == -6 ||
|
if (addwhat == CC_FILES || addwhat == -6 ||
|
||||||
|
|
@ -2515,7 +2690,6 @@ addmatch(char *s, char *t)
|
||||||
}
|
}
|
||||||
if (!test)
|
if (!test)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!ms && !ispattern && ai->firstm) {
|
if (!ms && !ispattern && ai->firstm) {
|
||||||
if ((test = sl - pfxlen(ai->firstm->str, s)) < ai->prerest)
|
if ((test = sl - pfxlen(ai->firstm->str, s)) < ai->prerest)
|
||||||
ai->prerest = test;
|
ai->prerest = test;
|
||||||
|
|
@ -2602,8 +2776,13 @@ addmatch(char *s, char *t)
|
||||||
cm->str = (ms ? ms : s);
|
cm->str = (ms ? ms : s);
|
||||||
cm->ipre = (ipre && *ipre ? ipre : NULL);
|
cm->ipre = (ipre && *ipre ? ipre : NULL);
|
||||||
cm->ripre = (ripre && *ripre ? ripre : NULL);
|
cm->ripre = (ripre && *ripre ? ripre : NULL);
|
||||||
cm->pre = curcc->prefix;
|
if (incompfunc) {
|
||||||
cm->suf = curcc->suffix;
|
cm->pre = dupstring(curcc->prefix);
|
||||||
|
cm->suf = dupstring(curcc->suffix);
|
||||||
|
} else {
|
||||||
|
cm->pre = curcc->prefix;
|
||||||
|
cm->suf = curcc->suffix;
|
||||||
|
}
|
||||||
cm->flags = mflags | isf;
|
cm->flags = mflags | isf;
|
||||||
cm->brpl = bpl;
|
cm->brpl = bpl;
|
||||||
cm->brsl = bsl;
|
cm->brsl = bsl;
|
||||||
|
|
@ -2729,7 +2908,7 @@ maketildelist(void)
|
||||||
/* This does the check for compctl -x `n' and `N' patterns. */
|
/* This does the check for compctl -x `n' and `N' patterns. */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
int
|
||||||
getcpat(char *str, int cpatindex, char *cpat, int class)
|
getcpat(char *str, int cpatindex, char *cpat, int class)
|
||||||
{
|
{
|
||||||
char *s, *t, *p;
|
char *s, *t, *p;
|
||||||
|
|
@ -2951,6 +3130,8 @@ docompletion(char *s, int lst, int incmd)
|
||||||
|
|
||||||
else if (nmatches == 1) {
|
else if (nmatches == 1) {
|
||||||
/* Only one match. */
|
/* Only one match. */
|
||||||
|
while (!amatches->mcount)
|
||||||
|
amatches = amatches->next;
|
||||||
do_single(amatches->matches[0]);
|
do_single(amatches->matches[0]);
|
||||||
invalidatelist();
|
invalidatelist();
|
||||||
}
|
}
|
||||||
|
|
@ -3051,7 +3232,98 @@ makecomplist(char *s, int incmd, int lst)
|
||||||
ccused = newlinklist();
|
ccused = newlinklist();
|
||||||
ccstack = newlinklist();
|
ccstack = newlinklist();
|
||||||
|
|
||||||
makecomplistglobal(s, incmd, lst);
|
if (compfunc) {
|
||||||
|
List list;
|
||||||
|
int lv = lastval;
|
||||||
|
|
||||||
|
if ((list = getshfunc(compfunc)) != &dummy_list) {
|
||||||
|
LinkList args = newlinklist();
|
||||||
|
char **p, *tmp;
|
||||||
|
int aadd = 0, usea = 1;
|
||||||
|
|
||||||
|
addlinknode(args, compfunc);
|
||||||
|
|
||||||
|
zsfree(compcontext);
|
||||||
|
zsfree(compcommand);
|
||||||
|
compcommand = "";
|
||||||
|
if (inwhat == IN_MATH) {
|
||||||
|
if (insubscr) {
|
||||||
|
compcontext = "subscript";
|
||||||
|
compcommand = varname ? varname : "";
|
||||||
|
} else
|
||||||
|
compcontext = "math";
|
||||||
|
usea = 0;
|
||||||
|
} else if (lincmd)
|
||||||
|
compcontext = (insubscr ? "subscript" : "command");
|
||||||
|
else if (linredir)
|
||||||
|
compcontext = "redirect";
|
||||||
|
else
|
||||||
|
switch (inwhat) {
|
||||||
|
case IN_ENV:
|
||||||
|
compcontext = "value";
|
||||||
|
compcommand = varname;
|
||||||
|
usea = 0;
|
||||||
|
break;
|
||||||
|
case IN_COND:
|
||||||
|
compcontext = "condition";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (cmdstr) {
|
||||||
|
compcontext = "argument";
|
||||||
|
compcommand = cmdstr;
|
||||||
|
} else {
|
||||||
|
compcontext = "value";
|
||||||
|
if (clwords[0])
|
||||||
|
compcommand = clwords[0];
|
||||||
|
}
|
||||||
|
aadd = 1;
|
||||||
|
}
|
||||||
|
compcontext = ztrdup(compcontext);
|
||||||
|
tmp = quotename(compcommand, NULL, NULL, NULL);
|
||||||
|
untokenize(tmp);
|
||||||
|
compcommand = ztrdup(tmp);
|
||||||
|
if (usea && (!aadd || clwords[0]))
|
||||||
|
for (p = clwords + aadd; *p; p++) {
|
||||||
|
tmp = dupstring(*p);
|
||||||
|
untokenize(tmp);
|
||||||
|
addlinknode(args, tmp);
|
||||||
|
}
|
||||||
|
zsfree(compprefix);
|
||||||
|
zsfree(compsuffix);
|
||||||
|
if (unset(COMPLETEINWORD)) {
|
||||||
|
tmp = quotename(s, NULL, NULL, NULL);
|
||||||
|
untokenize(tmp);
|
||||||
|
compprefix = ztrdup(tmp);
|
||||||
|
compsuffix = ztrdup("");
|
||||||
|
} else {
|
||||||
|
char *ss = s + offs, sav;
|
||||||
|
|
||||||
|
tmp = quotename(s, &ss, NULL, NULL);
|
||||||
|
sav = *ss;
|
||||||
|
*ss = '\0';
|
||||||
|
untokenize(tmp);
|
||||||
|
compprefix = ztrdup(tmp);
|
||||||
|
*ss = sav;
|
||||||
|
untokenize(ss);
|
||||||
|
compsuffix = ztrdup(ss);
|
||||||
|
}
|
||||||
|
zsfree(compiprefix);
|
||||||
|
compiprefix = ztrdup("");
|
||||||
|
compcurrent = (usea ? (clwpos + 1 - aadd) : 1);
|
||||||
|
compnmatches = mnum;
|
||||||
|
incompfunc = 1;
|
||||||
|
startparamscope();
|
||||||
|
makecompparamsptr();
|
||||||
|
NEWHEAPS(compheap) {
|
||||||
|
doshfunc(compfunc, list, args, 0, 1);
|
||||||
|
} OLDHEAPS;
|
||||||
|
endparamscope();
|
||||||
|
lastcmd = 9;
|
||||||
|
incompfunc = 0;
|
||||||
|
}
|
||||||
|
lastval = lv;
|
||||||
|
} else
|
||||||
|
makecomplistglobal(s, incmd, lst);
|
||||||
|
|
||||||
endcmgroup(NULL);
|
endcmgroup(NULL);
|
||||||
|
|
||||||
|
|
@ -3082,6 +3354,83 @@ makecomplist(char *s, int incmd, int lst)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This should probably be moved into tokenize(). */
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ctokenize(char *p)
|
||||||
|
{
|
||||||
|
char *r = p;
|
||||||
|
int bslash = 0;
|
||||||
|
|
||||||
|
tokenize(p);
|
||||||
|
|
||||||
|
for (p = r; *p; p++) {
|
||||||
|
if (*p == '\\')
|
||||||
|
bslash = 1;
|
||||||
|
else {
|
||||||
|
if (*p == '$') {
|
||||||
|
if (bslash)
|
||||||
|
p[-1] = Bnull;
|
||||||
|
else
|
||||||
|
*p = String;
|
||||||
|
}
|
||||||
|
bslash = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
char *
|
||||||
|
comp_str(int *ipl, int *pl)
|
||||||
|
{
|
||||||
|
char *p = dupstring(compprefix);
|
||||||
|
char *s = dupstring(compsuffix);
|
||||||
|
char *ip = dupstring(compiprefix);
|
||||||
|
char *str;
|
||||||
|
int lp, ls, lip;
|
||||||
|
|
||||||
|
ctokenize(p);
|
||||||
|
remnulargs(p);
|
||||||
|
ctokenize(s);
|
||||||
|
remnulargs(s);
|
||||||
|
ctokenize(ip);
|
||||||
|
remnulargs(ip);
|
||||||
|
ls = strlen(s);
|
||||||
|
lip = strlen(ip);
|
||||||
|
lp = strlen(p);
|
||||||
|
str = halloc(lip + lp + ls + 1);
|
||||||
|
strcpy(str, ip);
|
||||||
|
strcat(str, p);
|
||||||
|
strcat(str, s);
|
||||||
|
|
||||||
|
if (ipl)
|
||||||
|
*ipl = lip;
|
||||||
|
if (pl)
|
||||||
|
*pl = lp;
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void
|
||||||
|
makecomplistcall(Compctl cc)
|
||||||
|
{
|
||||||
|
SWITCHHEAPS(compheap) {
|
||||||
|
HEAPALLOC {
|
||||||
|
int ooffs = offs, lip, lp;
|
||||||
|
char *str = comp_str(&lip, &lp);
|
||||||
|
|
||||||
|
offs = lip + lp;
|
||||||
|
cc->refc++;
|
||||||
|
ccont = 0;
|
||||||
|
makecomplistor(cc, str, lincmd, lip, 0);
|
||||||
|
offs = ooffs;
|
||||||
|
compnmatches = mnum;
|
||||||
|
} LASTALLOC;
|
||||||
|
} SWITCHBACKHEAPS;
|
||||||
|
}
|
||||||
|
|
||||||
/* This function gets the compctls for the given command line and *
|
/* This function gets the compctls for the given command line and *
|
||||||
* adds all completions for them. */
|
* adds all completions for them. */
|
||||||
|
|
||||||
|
|
@ -3159,7 +3508,7 @@ makecomplistcmd(char *os, int incmd)
|
||||||
/* If the command string starts with `=', try the path name of the *
|
/* If the command string starts with `=', try the path name of the *
|
||||||
* command. */
|
* command. */
|
||||||
if (cmdstr && cmdstr[0] == Equals) {
|
if (cmdstr && cmdstr[0] == Equals) {
|
||||||
char *c = findcmd(cmdstr + 1);
|
char *c = findcmd(cmdstr + 1, 1);
|
||||||
|
|
||||||
if (c) {
|
if (c) {
|
||||||
zsfree(cmdstr);
|
zsfree(cmdstr);
|
||||||
|
|
@ -3191,7 +3540,7 @@ makecomplistpc(char *os, int incmd)
|
||||||
{
|
{
|
||||||
Patcomp pc;
|
Patcomp pc;
|
||||||
Comp pat;
|
Comp pat;
|
||||||
char *s = findcmd(cmdstr);
|
char *s = findcmd(cmdstr, 1);
|
||||||
|
|
||||||
for (pc = patcomps; pc; pc = pc->next) {
|
for (pc = patcomps; pc; pc = pc->next) {
|
||||||
if ((pat = parsereg(pc->pat)) &&
|
if ((pat = parsereg(pc->pat)) &&
|
||||||
|
|
@ -3468,12 +3817,12 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
||||||
|
|
||||||
ccont |= (cc->mask2 & (CC_CCCONT | CC_DEFCONT | CC_PATCONT));
|
ccont |= (cc->mask2 & (CC_CCCONT | CC_DEFCONT | CC_PATCONT));
|
||||||
|
|
||||||
if (findnode(ccstack, cc))
|
if (!incompfunc && findnode(ccstack, cc))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
addlinknode(ccstack, cc);
|
addlinknode(ccstack, cc);
|
||||||
|
|
||||||
if (allccs) {
|
if (!incompfunc && allccs) {
|
||||||
if (findnode(allccs, cc)) {
|
if (findnode(allccs, cc)) {
|
||||||
uremnode(ccstack, firstnode(ccstack));
|
uremnode(ccstack, firstnode(ccstack));
|
||||||
return;
|
return;
|
||||||
|
|
@ -4107,7 +4456,8 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This flag allows us to use read -l and -c. */
|
/* This flag allows us to use read -l and -c. */
|
||||||
incompctlfunc = 1;
|
if (!incompfunc)
|
||||||
|
incompctlfunc = 1;
|
||||||
sfcontext = SFC_COMPLETE;
|
sfcontext = SFC_COMPLETE;
|
||||||
/* Call the function. */
|
/* Call the function. */
|
||||||
doshfunc(cc->func, list, args, 0, 1);
|
doshfunc(cc->func, list, args, 0, 1);
|
||||||
|
|
@ -4126,7 +4476,8 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
||||||
char *j, *jj;
|
char *j, *jj;
|
||||||
|
|
||||||
for (i = 0; i < MAXJOB; i++)
|
for (i = 0; i < MAXJOB; i++)
|
||||||
if (jobtab[i].stat & STAT_INUSE) {
|
if ((jobtab[i].stat & STAT_INUSE) &&
|
||||||
|
jobtab[i].procs && jobtab[i].procs->text) {
|
||||||
int stopped = jobtab[i].stat & STAT_STOPPED;
|
int stopped = jobtab[i].stat & STAT_STOPPED;
|
||||||
|
|
||||||
j = jj = dupstring(jobtab[i].procs->text);
|
j = jj = dupstring(jobtab[i].procs->text);
|
||||||
|
|
@ -4274,7 +4625,8 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No harm in allowing read -l and -c here, too */
|
/* No harm in allowing read -l and -c here, too */
|
||||||
incompctlfunc = 1;
|
if (!incompfunc)
|
||||||
|
incompctlfunc = 1;
|
||||||
sfcontext = SFC_COMPLETE;
|
sfcontext = SFC_COMPLETE;
|
||||||
doshfunc(cc->ylist, list, args, 0, 1);
|
doshfunc(cc->ylist, list, args, 0, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
|
|
@ -4528,10 +4880,12 @@ makearray(LinkList l, int s, int *np, int *nlp)
|
||||||
for (bp = ap; bp[1] && matcheq(*ap, bp[1]); bp++, n--);
|
for (bp = ap; bp[1] && matcheq(*ap, bp[1]); bp++, n--);
|
||||||
ap = bp;
|
ap = bp;
|
||||||
/* Mark those, that would show the same string in the list. */
|
/* Mark those, that would show the same string in the list. */
|
||||||
for (; bp[1] && !strcmp((*ap)->str, (bp[1])->str); bp++) {
|
for (; bp[1] && !strcmp((*ap)->str, (bp[1])->str); bp++)
|
||||||
(bp[1])->flags |= CMF_NOLIST; nl++;
|
(bp[1])->flags |= CMF_NOLIST;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
for (ap = rp; *ap; ap++)
|
||||||
|
if ((*ap)->flags & CMF_NOLIST)
|
||||||
|
nl++;
|
||||||
*cp = NULL;
|
*cp = NULL;
|
||||||
}
|
}
|
||||||
if (np)
|
if (np)
|
||||||
|
|
@ -4991,10 +5345,14 @@ do_single(Cmatch m)
|
||||||
if (m->suf) {
|
if (m->suf) {
|
||||||
havesuff = 1;
|
havesuff = 1;
|
||||||
menuinsc = ztrlen(m->suf);
|
menuinsc = ztrlen(m->suf);
|
||||||
if (menuwe && (m->flags & CMF_REMOVE)) {
|
menulen -= menuinsc;
|
||||||
makesuffix(menuinsc);
|
if (menuwe) {
|
||||||
if (menuinsc == 1)
|
menuend += menuinsc;
|
||||||
suffixlen[m->suf[0]] = 1;
|
if (m->flags & CMF_REMOVE) {
|
||||||
|
makesuffix(menuinsc);
|
||||||
|
if (menuinsc == 1)
|
||||||
|
suffixlen[STOUC(m->suf[0])] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* There is no user-specified suffix, *
|
/* There is no user-specified suffix, *
|
||||||
|
|
@ -5463,7 +5821,8 @@ listmatches(void)
|
||||||
}
|
}
|
||||||
if (n) {
|
if (n) {
|
||||||
putc('\n', shout);
|
putc('\n', shout);
|
||||||
p = skipnolist(p + 1);
|
if (n && nl)
|
||||||
|
p = skipnolist(p + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5671,7 +6030,7 @@ expandcmdpath(void)
|
||||||
feep();
|
feep();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
str = findcmd(s);
|
str = findcmd(s, 1);
|
||||||
zsfree(s);
|
zsfree(s);
|
||||||
if (!str) {
|
if (!str) {
|
||||||
feep();
|
feep();
|
||||||
|
|
@ -5686,7 +6045,6 @@ expandcmdpath(void)
|
||||||
cs += cmdwe - cmdwb + strlen(str);
|
cs += cmdwe - cmdwb + strlen(str);
|
||||||
if (cs > ll)
|
if (cs > ll)
|
||||||
cs = ll;
|
cs = ll;
|
||||||
zsfree(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extra function added by AR Iano-Fletcher. */
|
/* Extra function added by AR Iano-Fletcher. */
|
||||||
|
|
|
||||||
296
Src/builtin.c
296
Src/builtin.c
|
|
@ -680,7 +680,7 @@ bin_cd(char *nam, char **argv, char *ops, int func)
|
||||||
goto brk;
|
goto brk;
|
||||||
}
|
}
|
||||||
} while (*++s);
|
} while (*++s);
|
||||||
for (s = *argv; *++s; ops[*s] = 1);
|
for (s = *argv; *++s; ops[STOUC(*s)] = 1);
|
||||||
}
|
}
|
||||||
brk:
|
brk:
|
||||||
chaselinks = ops['P'] || (isset(CHASELINKS) && !ops['L']);
|
chaselinks = ops['P'] || (isset(CHASELINKS) && !ops['L']);
|
||||||
|
|
@ -790,7 +790,7 @@ cd_get_dest(char *nam, char **argv, char *ops, int func)
|
||||||
zsfree(remnode(dirstack, dir));
|
zsfree(remnode(dirstack, dir));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (dest != getdata(dir)) {
|
if (dest != (char *)getdata(dir)) {
|
||||||
zsfree(getdata(dir));
|
zsfree(getdata(dir));
|
||||||
setdata(dir, dest);
|
setdata(dir, dest);
|
||||||
}
|
}
|
||||||
|
|
@ -1224,13 +1224,14 @@ bin_fc(char *nam, char **argv, char *ops, int func)
|
||||||
if (!editor)
|
if (!editor)
|
||||||
editor = DEFAULT_FCEDIT;
|
editor = DEFAULT_FCEDIT;
|
||||||
|
|
||||||
if (fcedit(editor, fil))
|
if (fcedit(editor, fil)) {
|
||||||
if (stuff(fil))
|
if (stuff(fil))
|
||||||
zwarnnam("fc", "%e: %s", s, errno);
|
zwarnnam("fc", "%e: %s", s, errno);
|
||||||
else {
|
else {
|
||||||
loop(0,1);
|
loop(0,1);
|
||||||
retval = lastval;
|
retval = lastval;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unlink(fil);
|
unlink(fil);
|
||||||
|
|
@ -1464,6 +1465,117 @@ getasg(char *s)
|
||||||
return &asg;
|
return &asg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* function to set a single parameter */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
int
|
||||||
|
typeset_single(char *cname, char *pname, Param pm, int func,
|
||||||
|
int on, int off, int roff, char *value)
|
||||||
|
{
|
||||||
|
int usepm, tc;
|
||||||
|
|
||||||
|
/* use the existing pm? */
|
||||||
|
usepm = pm && !(pm->flags & PM_UNSET);
|
||||||
|
|
||||||
|
/* Always use an existing pm if special at current locallevel */
|
||||||
|
if (pm && (pm->flags & PM_SPECIAL) && pm->level == locallevel)
|
||||||
|
usepm = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't use a non-special existing param if
|
||||||
|
* - the local level has changed, and
|
||||||
|
* - the function is not `export'.
|
||||||
|
*/
|
||||||
|
if (usepm && !(pm->flags & PM_SPECIAL) &&
|
||||||
|
locallevel != pm->level && func != BIN_EXPORT)
|
||||||
|
usepm = 0;
|
||||||
|
|
||||||
|
/* attempting a type conversion? */
|
||||||
|
if ((tc = usepm && (((off & pm->flags) | (on & ~pm->flags)) &
|
||||||
|
(PM_INTEGER|PM_HASHED|PM_ARRAY))))
|
||||||
|
usepm = 0;
|
||||||
|
if (tc && (pm->flags & PM_SPECIAL)) {
|
||||||
|
zerrnam(cname, "%s: can't change type of a special parameter",
|
||||||
|
pname, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usepm) {
|
||||||
|
if (!on && !roff && !value) {
|
||||||
|
paramtab->printnode((HashNode)pm, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((pm->flags & PM_RESTRICTED && isset(RESTRICTED))) {
|
||||||
|
zerrnam(cname, "%s: restricted", pname, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) &&
|
||||||
|
!(pm->flags & PM_READONLY & ~off))
|
||||||
|
uniqarray((*pm->gets.afn) (pm));
|
||||||
|
pm->flags = (pm->flags | on) & ~off;
|
||||||
|
/* This auxlen/pm->ct stuff is a nasty hack. */
|
||||||
|
if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER)) &&
|
||||||
|
auxlen)
|
||||||
|
pm->ct = auxlen;
|
||||||
|
if (!(pm->flags & (PM_ARRAY|PM_HASHED))) {
|
||||||
|
if (pm->flags & PM_EXPORTED) {
|
||||||
|
if (!(pm->flags & PM_UNSET) && !pm->env && !value)
|
||||||
|
pm->env = addenv(pname, getsparam(pname));
|
||||||
|
} else if (pm->env) {
|
||||||
|
delenv(pm->env);
|
||||||
|
zsfree(pm->env);
|
||||||
|
pm->env = NULL;
|
||||||
|
}
|
||||||
|
if (value)
|
||||||
|
setsparam(pname, ztrdup(value));
|
||||||
|
} else if (value) {
|
||||||
|
zwarnnam(cname, "can't assign new value for array %s", pname, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We're here either because we're creating a new parameter,
|
||||||
|
* or we're adding a parameter at a different local level,
|
||||||
|
* or we're converting the type of a parameter. In the
|
||||||
|
* last case only, we need to delete the old parameter.
|
||||||
|
*/
|
||||||
|
if (tc) {
|
||||||
|
if (pm->flags & PM_READONLY) {
|
||||||
|
on |= ~off & PM_READONLY;
|
||||||
|
pm->flags &= ~PM_READONLY;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Try to carry over a value, but not when changing from,
|
||||||
|
* to, or between non-scalar types.
|
||||||
|
*/
|
||||||
|
if (!value && !((pm->flags|on) & (PM_ARRAY|PM_HASHED)))
|
||||||
|
value = dupstring(getsparam(pname));
|
||||||
|
/* pname may point to pm->nam which is about to disappear */
|
||||||
|
pname = dupstring(pname);
|
||||||
|
unsetparam_pm(pm, 0, 1);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Create a new node for a parameter with the flags in `on' minus the
|
||||||
|
* readonly flag
|
||||||
|
*/
|
||||||
|
pm = createparam(pname, on & ~PM_READONLY);
|
||||||
|
DPUTS(!pm, "BUG: parameter not created");
|
||||||
|
pm->ct = auxlen;
|
||||||
|
if (func != BIN_EXPORT)
|
||||||
|
pm->level = locallevel;
|
||||||
|
if (value && !(pm->flags & (PM_ARRAY|PM_HASHED)))
|
||||||
|
setsparam(pname, ztrdup(value));
|
||||||
|
pm->flags |= (on & PM_READONLY);
|
||||||
|
if (value && (pm->flags & (PM_ARRAY|PM_HASHED))) {
|
||||||
|
zerrnam(cname, "%s: can't assign initial value for array", pname, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* declare, export, integer, local, readonly, typeset */
|
/* declare, export, integer, local, readonly, typeset */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
@ -1475,7 +1587,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
|
||||||
Comp com;
|
Comp com;
|
||||||
char *optstr = "aiALRZlurtxU";
|
char *optstr = "aiALRZlurtxU";
|
||||||
int on = 0, off = 0, roff, bit = PM_ARRAY;
|
int on = 0, off = 0, roff, bit = PM_ARRAY;
|
||||||
int initon, initoff, of, i;
|
int i;
|
||||||
int returnval = 0, printflags = 0;
|
int returnval = 0, printflags = 0;
|
||||||
|
|
||||||
/* hash -f is really the builtin `functions' */
|
/* hash -f is really the builtin `functions' */
|
||||||
|
|
@ -1486,9 +1598,9 @@ bin_typeset(char *name, char **argv, char *ops, int func)
|
||||||
* Unfortunately, this depends on the order *
|
* Unfortunately, this depends on the order *
|
||||||
* these flags are defined in zsh.h */
|
* these flags are defined in zsh.h */
|
||||||
for (; *optstr; optstr++, bit <<= 1)
|
for (; *optstr; optstr++, bit <<= 1)
|
||||||
if (ops[*optstr] == 1)
|
if (ops[STOUC(*optstr)] == 1)
|
||||||
on |= bit;
|
on |= bit;
|
||||||
else if (ops[*optstr] == 2)
|
else if (ops[STOUC(*optstr)] == 2)
|
||||||
off |= bit;
|
off |= bit;
|
||||||
roff = off;
|
roff = off;
|
||||||
|
|
||||||
|
|
@ -1521,7 +1633,11 @@ bin_typeset(char *name, char **argv, char *ops, int func)
|
||||||
|
|
||||||
/* With the -m option, treat arguments as glob patterns */
|
/* With the -m option, treat arguments as glob patterns */
|
||||||
if (ops['m']) {
|
if (ops['m']) {
|
||||||
|
MUSTUSEHEAP("typeset -m");
|
||||||
while ((asg = getasg(*argv++))) {
|
while ((asg = getasg(*argv++))) {
|
||||||
|
LinkList pmlist = newlinklist();
|
||||||
|
LinkNode pmnode;
|
||||||
|
|
||||||
tokenize(asg->name); /* expand argument */
|
tokenize(asg->name); /* expand argument */
|
||||||
if (!(com = parsereg(asg->name))) {
|
if (!(com = parsereg(asg->name))) {
|
||||||
untokenize(asg->name);
|
untokenize(asg->name);
|
||||||
|
|
@ -1529,143 +1645,45 @@ bin_typeset(char *name, char **argv, char *ops, int func)
|
||||||
returnval = 1;
|
returnval = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* If no options or values are given, display all *
|
/*
|
||||||
* parameters matching the glob pattern. */
|
* Search through the parameter table and change all parameters
|
||||||
if (!(on || roff || asg->value)) {
|
* matching the glob pattern to have these flags and/or value.
|
||||||
scanmatchtable(paramtab, com, 0, 0, paramtab->printnode, 0);
|
* Bad news: if the parameter gets altered, e.g. by
|
||||||
continue;
|
* a type conversion, then paramtab can be shifted around,
|
||||||
}
|
* so we need to store the parameters to alter on a separate
|
||||||
/* Since either options or values are given, we search *
|
* list for later use.
|
||||||
* through the parameter table and change all parameters *
|
*/
|
||||||
* matching the glob pattern to have these flags and/or *
|
|
||||||
* value. */
|
|
||||||
for (i = 0; i < paramtab->hsize; i++) {
|
for (i = 0; i < paramtab->hsize; i++) {
|
||||||
for (pm = (Param) paramtab->nodes[i]; pm; pm = (Param) pm->next) {
|
for (pm = (Param) paramtab->nodes[i]; pm;
|
||||||
|
pm = (Param) pm->next) {
|
||||||
if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED))
|
if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED))
|
||||||
continue;
|
continue;
|
||||||
if (domatch(pm->nam, com, 0)) {
|
if (domatch(pm->nam, com, 0))
|
||||||
/* set up flags if we have any */
|
addlinknode(pmlist, pm);
|
||||||
if (on || roff) {
|
|
||||||
if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) &&
|
|
||||||
!(pm->flags & PM_READONLY & ~off))
|
|
||||||
uniqarray((*pm->gets.afn) (pm));
|
|
||||||
if ((on & ~pm->flags) & PM_HASHED) {
|
|
||||||
char *nam = ztrdup(pm->nam);
|
|
||||||
unsetparam(nam);
|
|
||||||
pm = createparam(nam, on & ~PM_READONLY);
|
|
||||||
DPUTS(!pm, "BUG: parameter not created");
|
|
||||||
}
|
|
||||||
pm->flags = (pm->flags | on) & ~off;
|
|
||||||
if (PM_TYPE(pm->flags) != PM_ARRAY &&
|
|
||||||
PM_TYPE(pm->flags) != PM_HASHED) {
|
|
||||||
if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER)) && auxlen)
|
|
||||||
pm->ct = auxlen;
|
|
||||||
/* did we just export this? */
|
|
||||||
if ((pm->flags & PM_EXPORTED) && !pm->env) {
|
|
||||||
pm->env = addenv(pm->nam, (asg->value) ? asg->value : getsparam(pm->nam));
|
|
||||||
} else if (!(pm->flags & PM_EXPORTED) && pm->env) {
|
|
||||||
/* did we just unexport this? */
|
|
||||||
delenv(pm->env);
|
|
||||||
zsfree(pm->env);
|
|
||||||
pm->env = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* set up a new value if given */
|
|
||||||
if (asg->value) {
|
|
||||||
setsparam(pm->nam, ztrdup(asg->value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (pmnode = firstnode(pmlist); pmnode; incnode(pmnode)) {
|
||||||
|
pm = (Param) getdata(pmnode);
|
||||||
|
if (typeset_single(name, pm->nam, pm, func, on, off, roff,
|
||||||
|
asg->value))
|
||||||
|
returnval = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return returnval;
|
return returnval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the values of on, off, and func */
|
|
||||||
initon = on;
|
|
||||||
initoff = off;
|
|
||||||
of = func;
|
|
||||||
|
|
||||||
/* Take arguments literally. Don't glob */
|
/* Take arguments literally. Don't glob */
|
||||||
while ((asg = getasg(*argv++))) {
|
while ((asg = getasg(*argv++))) {
|
||||||
/* restore the original values of on, off, and func */
|
|
||||||
on = initon;
|
|
||||||
off = initoff;
|
|
||||||
func = of;
|
|
||||||
on &= ~PM_ARRAY;
|
|
||||||
|
|
||||||
/* check if argument is a valid identifier */
|
/* check if argument is a valid identifier */
|
||||||
if (!isident(asg->name)) {
|
if (!isident(asg->name)) {
|
||||||
zerr("not an identifier: %s", asg->name, 0);
|
zerr("not an identifier: %s", asg->name, 0);
|
||||||
returnval = 1;
|
returnval = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bit = 0; /* flag for switching int<->not-int */
|
if (typeset_single(name, asg->name,
|
||||||
if ((pm = (Param)paramtab->getnode(paramtab, asg->name)) &&
|
(Param)paramtab->getnode(paramtab, asg->name),
|
||||||
(((pm->flags & PM_SPECIAL) && pm->level == locallevel) ||
|
func, on, off, roff, asg->value))
|
||||||
(!(pm->flags & PM_UNSET) &&
|
returnval = 1;
|
||||||
((locallevel == pm->level) || func == BIN_EXPORT) &&
|
|
||||||
!(bit = (((off & pm->flags) | (on & ~pm->flags)) &
|
|
||||||
(PM_INTEGER|PM_HASHED)))))) {
|
|
||||||
/* if no flags or values are given, just print this parameter */
|
|
||||||
if (!on && !roff && !asg->value) {
|
|
||||||
paramtab->printnode((HashNode) pm, 0);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED)) {
|
|
||||||
zerrnam(name, "%s: restricted", pm->nam, 0);
|
|
||||||
returnval = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if((pm->flags & PM_SPECIAL) &&
|
|
||||||
PM_TYPE((pm->flags | on) & ~off) != PM_TYPE(pm->flags)) {
|
|
||||||
zerrnam(name, "%s: cannot change type of a special parameter",
|
|
||||||
pm->nam, 0);
|
|
||||||
returnval = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) &&
|
|
||||||
!(pm->flags & PM_READONLY & ~off))
|
|
||||||
uniqarray((*pm->gets.afn) (pm));
|
|
||||||
pm->flags = (pm->flags | on) & ~off;
|
|
||||||
if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER)) &&
|
|
||||||
auxlen)
|
|
||||||
pm->ct = auxlen;
|
|
||||||
if (PM_TYPE(pm->flags) != PM_ARRAY &&
|
|
||||||
PM_TYPE(pm->flags) != PM_HASHED) {
|
|
||||||
if (pm->flags & PM_EXPORTED) {
|
|
||||||
if (!(pm->flags & PM_UNSET) && !pm->env && !asg->value)
|
|
||||||
pm->env = addenv(asg->name, getsparam(asg->name));
|
|
||||||
} else if (pm->env) {
|
|
||||||
delenv(pm->env);
|
|
||||||
zsfree(pm->env);
|
|
||||||
pm->env = NULL;
|
|
||||||
}
|
|
||||||
if (asg->value)
|
|
||||||
setsparam(asg->name, ztrdup(asg->value));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (bit) {
|
|
||||||
if (pm->flags & PM_READONLY) {
|
|
||||||
on |= ~off & PM_READONLY;
|
|
||||||
pm->flags &= ~PM_READONLY;
|
|
||||||
}
|
|
||||||
if (!asg->value)
|
|
||||||
asg->value = dupstring(getsparam(asg->name));
|
|
||||||
unsetparam(asg->name);
|
|
||||||
}
|
|
||||||
/* create a new node for a parameter with the *
|
|
||||||
* flags in `on' minus the readonly flag */
|
|
||||||
pm = createparam(ztrdup(asg->name), on & ~PM_READONLY);
|
|
||||||
DPUTS(!pm, "BUG: parameter not created");
|
|
||||||
pm->ct = auxlen;
|
|
||||||
if (func != BIN_EXPORT)
|
|
||||||
pm->level = locallevel;
|
|
||||||
if (asg->value)
|
|
||||||
setsparam(asg->name, ztrdup(asg->value));
|
|
||||||
pm->flags |= (on & PM_READONLY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return returnval;
|
return returnval;
|
||||||
}
|
}
|
||||||
|
|
@ -1989,7 +2007,7 @@ bin_whence(char *nam, char **argv, char *ops, int func)
|
||||||
puts(wd ? ": none" : " not found");
|
puts(wd ? ": none" : " not found");
|
||||||
returnval = 1;
|
returnval = 1;
|
||||||
}
|
}
|
||||||
} else if ((cnam = findcmd(*argv))) {
|
} else if ((cnam = findcmd(*argv, 1))) {
|
||||||
/* Found external command. */
|
/* Found external command. */
|
||||||
if (wd) {
|
if (wd) {
|
||||||
printf("%s: command\n", *argv);
|
printf("%s: command\n", *argv);
|
||||||
|
|
@ -2001,7 +2019,6 @@ bin_whence(char *nam, char **argv, char *ops, int func)
|
||||||
print_if_link(cnam);
|
print_if_link(cnam);
|
||||||
fputc('\n', stdout);
|
fputc('\n', stdout);
|
||||||
}
|
}
|
||||||
zsfree(cnam);
|
|
||||||
} else {
|
} else {
|
||||||
/* Not found at all. */
|
/* Not found at all. */
|
||||||
if (v || csh || wd)
|
if (v || csh || wd)
|
||||||
|
|
@ -2328,9 +2345,17 @@ bin_print(char *name, char **args, char *ops, int func)
|
||||||
args[n] = getkeystring(args[n], &len[n],
|
args[n] = getkeystring(args[n], &len[n],
|
||||||
func != BIN_ECHO && !ops['e'], &nnl);
|
func != BIN_ECHO && !ops['e'], &nnl);
|
||||||
/* -P option -- interpret as a prompt sequence */
|
/* -P option -- interpret as a prompt sequence */
|
||||||
if(ops['P'])
|
if(ops['P']) {
|
||||||
args[n] = unmetafy(promptexpand(metafy(args[n], len[n],
|
/*
|
||||||
META_NOALLOC), 0, NULL, NULL), &len[n]);
|
* promptexpand uses permanent storage: to avoid
|
||||||
|
* messy memory management, stick it on the heap
|
||||||
|
* instead.
|
||||||
|
*/
|
||||||
|
char *str = unmetafy(promptexpand(metafy(args[n], len[n],
|
||||||
|
META_NOALLOC), 0, NULL, NULL), &len[n]);
|
||||||
|
args[n] = dupstring(str);
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
/* -D option -- interpret as a directory, and use ~ */
|
/* -D option -- interpret as a directory, and use ~ */
|
||||||
if(ops['D']) {
|
if(ops['D']) {
|
||||||
Nameddir d = finddir(args[n]);
|
Nameddir d = finddir(args[n]);
|
||||||
|
|
@ -2778,8 +2803,9 @@ zexit(int val, int from_signal)
|
||||||
LASTALLOC_RETURN;
|
LASTALLOC_RETURN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (in_exit++ && from_signal)
|
if (in_exit++ && from_signal) {
|
||||||
LASTALLOC_RETURN;
|
LASTALLOC_RETURN;
|
||||||
|
}
|
||||||
if (isset(MONITOR))
|
if (isset(MONITOR))
|
||||||
/* send SIGHUP to any jobs left running */
|
/* send SIGHUP to any jobs left running */
|
||||||
killrunjobs(from_signal);
|
killrunjobs(from_signal);
|
||||||
|
|
@ -3181,13 +3207,14 @@ bin_read(char *name, char **args, char *ops, int func)
|
||||||
}
|
}
|
||||||
if (c == EOF || (c == '\n' && !zbuf))
|
if (c == EOF || (c == '\n' && !zbuf))
|
||||||
break;
|
break;
|
||||||
if (!bslash && isep(c) && bptr == buf)
|
if (!bslash && isep(c) && bptr == buf) {
|
||||||
if (iwsep(c))
|
if (iwsep(c))
|
||||||
continue;
|
continue;
|
||||||
else if (!first) {
|
else if (!first) {
|
||||||
first = 1;
|
first = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
bslash = c == '\\' && !bslash && !ops['r'];
|
bslash = c == '\\' && !bslash && !ops['r'];
|
||||||
if (bslash)
|
if (bslash)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -3240,7 +3267,7 @@ zread(void)
|
||||||
char cc, retry = 0;
|
char cc, retry = 0;
|
||||||
|
|
||||||
/* use zbuf if possible */
|
/* use zbuf if possible */
|
||||||
if (zbuf)
|
if (zbuf) {
|
||||||
/* If zbuf points to anything, it points to the next character in the
|
/* If zbuf points to anything, it points to the next character in the
|
||||||
buffer. This may be a null byte to indicate EOF. If reading from the
|
buffer. This may be a null byte to indicate EOF. If reading from the
|
||||||
buffer, move on the buffer pointer. */
|
buffer, move on the buffer pointer. */
|
||||||
|
|
@ -3248,6 +3275,7 @@ zread(void)
|
||||||
return zbuf++, STOUC(*zbuf++ ^ 32);
|
return zbuf++, STOUC(*zbuf++ ^ 32);
|
||||||
else
|
else
|
||||||
return (*zbuf) ? STOUC(*zbuf++) : EOF;
|
return (*zbuf) ? STOUC(*zbuf++) : EOF;
|
||||||
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* read a character from readfd */
|
/* read a character from readfd */
|
||||||
switch (read(readfd, &cc, 1)) {
|
switch (read(readfd, &cc, 1)) {
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ evalcond(Cond c)
|
||||||
int l = arrlen((char **) c->right);
|
int l = arrlen((char **) c->right);
|
||||||
|
|
||||||
if (l < cd->min || (cd->max >= 0 && l > cd->max)) {
|
if (l < cd->min || (cd->max >= 0 && l > cd->max)) {
|
||||||
zerr("unrecognized condition: `-%s'", (char *) c->left, 0);
|
zerr("unrecognized condition: `%s'", (char *) c->left, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -68,13 +68,13 @@ evalcond(Cond c)
|
||||||
int l = arrlen(a);
|
int l = arrlen(a);
|
||||||
|
|
||||||
if (l < cd->min || (cd->max >= 0 && l > cd->max)) {
|
if (l < cd->min || (cd->max >= 0 && l > cd->max)) {
|
||||||
zerr("unrecognized condition: `-%s'", (char *) c->left, 0);
|
zerr("unrecognized condition: `%s'", (char *) c->left, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
a[0] = (char *) c->left;
|
a[0] = (char *) c->left;
|
||||||
return cd->handler(a, cd->condid);
|
return cd->handler(a, cd->condid);
|
||||||
} else
|
} else
|
||||||
zerr("unrecognized condition: `-%s'", (char *) c->left, 0);
|
zerr("unrecognized condition: `%s'", (char *) c->left, 0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
Src/exec.c
18
Src/exec.c
|
|
@ -457,13 +457,17 @@ execute(Cmdnam not_used_yet, int dash)
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define try(X) { if (iscom(X)) return ztrdup(X); }
|
#define RET_IF_COM(X) { if (iscom(X)) return docopy ? dupstring(X) : arg0; }
|
||||||
|
|
||||||
/* get the full pathname of an external command */
|
/*
|
||||||
|
* Get the full pathname of an external command.
|
||||||
|
* If the second argument is zero, return the first argument if found;
|
||||||
|
* if non-zero, return the path using heap memory. (RET_IF_COM(X), above).
|
||||||
|
*/
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
char *
|
char *
|
||||||
findcmd(char *arg0)
|
findcmd(char *arg0, int docopy)
|
||||||
{
|
{
|
||||||
char **pp;
|
char **pp;
|
||||||
char *z, *s, buf[MAXCMDLEN];
|
char *z, *s, buf[MAXCMDLEN];
|
||||||
|
|
@ -476,7 +480,7 @@ findcmd(char *arg0)
|
||||||
return NULL;
|
return NULL;
|
||||||
for (s = arg0; *s; s++)
|
for (s = arg0; *s; s++)
|
||||||
if (*s == '/') {
|
if (*s == '/') {
|
||||||
try(arg0);
|
RET_IF_COM(arg0);
|
||||||
if (arg0 == s || unset(PATHDIRS)) {
|
if (arg0 == s || unset(PATHDIRS)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -496,13 +500,13 @@ findcmd(char *arg0)
|
||||||
*z++ = '/';
|
*z++ = '/';
|
||||||
}
|
}
|
||||||
strcpy(z, arg0);
|
strcpy(z, arg0);
|
||||||
try(buf);
|
RET_IF_COM(buf);
|
||||||
}
|
}
|
||||||
strcpy(nn, cn->u.name ? *(cn->u.name) : "");
|
strcpy(nn, cn->u.name ? *(cn->u.name) : "");
|
||||||
strcat(nn, "/");
|
strcat(nn, "/");
|
||||||
strcat(nn, cn->nam);
|
strcat(nn, cn->nam);
|
||||||
}
|
}
|
||||||
try(nn);
|
RET_IF_COM(nn);
|
||||||
}
|
}
|
||||||
for (pp = path; *pp; pp++) {
|
for (pp = path; *pp; pp++) {
|
||||||
z = buf;
|
z = buf;
|
||||||
|
|
@ -511,7 +515,7 @@ findcmd(char *arg0)
|
||||||
*z++ = '/';
|
*z++ = '/';
|
||||||
}
|
}
|
||||||
strcpy(z, arg0);
|
strcpy(z, arg0);
|
||||||
try(buf);
|
RET_IF_COM(buf);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2318,7 +2318,7 @@ doesmatch(Comp c)
|
||||||
for (; *pptr; pptr++) {
|
for (; *pptr; pptr++) {
|
||||||
if (*pptr == Meta)
|
if (*pptr == Meta)
|
||||||
pptr++;
|
pptr++;
|
||||||
else if (CHARMATCH(*pptr, looka))
|
else if (CHARMATCH(STOUC(*pptr), STOUC(looka)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!*(saves = pptr))
|
if (!*(saves = pptr))
|
||||||
|
|
@ -2688,7 +2688,7 @@ matchonce(Comp c)
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (CHARMATCH(*pptr, *pat)) {
|
if (CHARMATCH(STOUC(*pptr), STOUC(*pat))) {
|
||||||
/* just plain old characters */
|
/* just plain old characters */
|
||||||
pptr++;
|
pptr++;
|
||||||
pat++;
|
pat++;
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ addhashnode(HashTable ht, char *nam, void *nodeptr)
|
||||||
ht->nodes[hashval] = hn;
|
ht->nodes[hashval] = hn;
|
||||||
replacing:
|
replacing:
|
||||||
hn->next = hp->next;
|
hn->next = hp->next;
|
||||||
if(ht->scan)
|
if(ht->scan) {
|
||||||
if(ht->scan->sorted) {
|
if(ht->scan->sorted) {
|
||||||
HashNode *tab = ht->scan->u.s.tab;
|
HashNode *tab = ht->scan->u.s.tab;
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -181,6 +181,7 @@ addhashnode(HashTable ht, char *nam, void *nodeptr)
|
||||||
tab[i] = hn;
|
tab[i] = hn;
|
||||||
} else if(ht->scan->u.u == hp)
|
} else if(ht->scan->u.u == hp)
|
||||||
ht->scan->u.u = hn;
|
ht->scan->u.u = hn;
|
||||||
|
}
|
||||||
ht->freenode(hp);
|
ht->freenode(hp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -270,7 +271,7 @@ removehashnode(HashTable ht, char *nam)
|
||||||
ht->nodes[hashval] = hp->next;
|
ht->nodes[hashval] = hp->next;
|
||||||
gotit:
|
gotit:
|
||||||
ht->ct--;
|
ht->ct--;
|
||||||
if(ht->scan)
|
if(ht->scan) {
|
||||||
if(ht->scan->sorted) {
|
if(ht->scan->sorted) {
|
||||||
HashNode *tab = ht->scan->u.s.tab;
|
HashNode *tab = ht->scan->u.s.tab;
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -279,6 +280,7 @@ removehashnode(HashTable ht, char *nam)
|
||||||
tab[i] = NULL;
|
tab[i] = NULL;
|
||||||
} else if(ht->scan->u.u == hp)
|
} else if(ht->scan->u.u == hp)
|
||||||
ht->scan->u.u = hp->next;
|
ht->scan->u.u = hp->next;
|
||||||
|
}
|
||||||
return hp;
|
return hp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -392,7 +392,7 @@ histsubchar(int c)
|
||||||
c = ingetc();
|
c = ingetc();
|
||||||
}
|
}
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
if (!*buf)
|
if (!*buf) {
|
||||||
if (c != '%') {
|
if (c != '%') {
|
||||||
if (isset(CSHJUNKIEHISTORY))
|
if (isset(CSHJUNKIEHISTORY))
|
||||||
ev = curhist - 1;
|
ev = curhist - 1;
|
||||||
|
|
@ -408,6 +408,7 @@ histsubchar(int c)
|
||||||
else
|
else
|
||||||
ev = defev;
|
ev = defev;
|
||||||
evset = 0;
|
evset = 0;
|
||||||
|
}
|
||||||
} else if ((t0 = atoi(buf))) {
|
} else if ((t0 = atoi(buf))) {
|
||||||
ev = (t0 < 0) ? curhist + t0 : t0;
|
ev = (t0 < 0) ? curhist + t0 : t0;
|
||||||
evset = 1;
|
evset = 1;
|
||||||
|
|
@ -749,11 +750,12 @@ hend(void)
|
||||||
save = 0;
|
save = 0;
|
||||||
else {
|
else {
|
||||||
*hptr = '\0';
|
*hptr = '\0';
|
||||||
if (hptr[-1] == '\n')
|
if (hptr[-1] == '\n') {
|
||||||
if (chline[1]) {
|
if (chline[1]) {
|
||||||
*--hptr = '\0';
|
*--hptr = '\0';
|
||||||
} else
|
} else
|
||||||
save = 0;
|
save = 0;
|
||||||
|
}
|
||||||
if (!*chline || !strcmp(chline, "\n") ||
|
if (!*chline || !strcmp(chline, "\n") ||
|
||||||
(isset(HISTIGNORESPACE) && spaceflag))
|
(isset(HISTIGNORESPACE) && spaceflag))
|
||||||
save = 0;
|
save = 0;
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ inputline(void)
|
||||||
char *ingetcline, *ingetcpmptl = NULL, *ingetcpmptr = NULL;
|
char *ingetcline, *ingetcpmptl = NULL, *ingetcpmptr = NULL;
|
||||||
|
|
||||||
/* If reading code interactively, work out the prompts. */
|
/* If reading code interactively, work out the prompts. */
|
||||||
if (interact && isset(SHINSTDIN))
|
if (interact && isset(SHINSTDIN)) {
|
||||||
if (!isfirstln)
|
if (!isfirstln)
|
||||||
ingetcpmptl = prompt2;
|
ingetcpmptl = prompt2;
|
||||||
else {
|
else {
|
||||||
|
|
@ -227,6 +227,7 @@ inputline(void)
|
||||||
if (rprompt)
|
if (rprompt)
|
||||||
ingetcpmptr = rprompt;
|
ingetcpmptr = rprompt;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!(interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE))) {
|
if (!(interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE))) {
|
||||||
/*
|
/*
|
||||||
* If not using zle, read the line straight from the input file.
|
* If not using zle, read the line straight from the input file.
|
||||||
|
|
|
||||||
17
Src/jobs.c
17
Src/jobs.c
|
|
@ -462,7 +462,7 @@ printjob(Job jn, int lng, int synch)
|
||||||
if (jn->stat & STAT_SUPERJOB &&
|
if (jn->stat & STAT_SUPERJOB &&
|
||||||
jn->procs->status == SP_RUNNING && !pn->next)
|
jn->procs->status == SP_RUNNING && !pn->next)
|
||||||
pn->status = SP_RUNNING;
|
pn->status = SP_RUNNING;
|
||||||
if (pn->status != SP_RUNNING)
|
if (pn->status != SP_RUNNING) {
|
||||||
if (WIFSIGNALED(pn->status)) {
|
if (WIFSIGNALED(pn->status)) {
|
||||||
sig = WTERMSIG(pn->status);
|
sig = WTERMSIG(pn->status);
|
||||||
llen = strlen(sigmsg[sig]);
|
llen = strlen(sigmsg[sig]);
|
||||||
|
|
@ -483,6 +483,7 @@ printjob(Job jn, int lng, int synch)
|
||||||
} else if (isset(PRINTEXITVALUE) && isset(SHINSTDIN) &&
|
} else if (isset(PRINTEXITVALUE) && isset(SHINSTDIN) &&
|
||||||
WEXITSTATUS(pn->status))
|
WEXITSTATUS(pn->status))
|
||||||
sflag = 1;
|
sflag = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print if necessary */
|
/* print if necessary */
|
||||||
|
|
@ -508,7 +509,7 @@ printjob(Job jn, int lng, int synch)
|
||||||
break;
|
break;
|
||||||
len2 += strlen(qn->text) + 2;
|
len2 += strlen(qn->text) + 2;
|
||||||
}
|
}
|
||||||
if (job != thisjob)
|
if (job != thisjob) {
|
||||||
if (fline)
|
if (fline)
|
||||||
fprintf(fout, "[%ld] %c ",
|
fprintf(fout, "[%ld] %c ",
|
||||||
(long)(jn - jobtab),
|
(long)(jn - jobtab),
|
||||||
|
|
@ -516,7 +517,7 @@ printjob(Job jn, int lng, int synch)
|
||||||
: (job == prevjob) ? '-' : ' ');
|
: (job == prevjob) ? '-' : ' ');
|
||||||
else
|
else
|
||||||
fprintf(fout, (job > 9) ? " " : " ");
|
fprintf(fout, (job > 9) ? " " : " ");
|
||||||
else
|
} else
|
||||||
fprintf(fout, "zsh: ");
|
fprintf(fout, "zsh: ");
|
||||||
if (lng & 1)
|
if (lng & 1)
|
||||||
fprintf(fout, "%ld ", (long) pn->pid);
|
fprintf(fout, "%ld ", (long) pn->pid);
|
||||||
|
|
@ -531,18 +532,19 @@ printjob(Job jn, int lng, int synch)
|
||||||
lng &= ~3;
|
lng &= ~3;
|
||||||
} else
|
} else
|
||||||
fprintf(fout, "%*s", skip, "");
|
fprintf(fout, "%*s", skip, "");
|
||||||
if (pn->status == SP_RUNNING)
|
if (pn->status == SP_RUNNING) {
|
||||||
if (!conted)
|
if (!conted)
|
||||||
fprintf(fout, "running%*s", len - 7 + 2, "");
|
fprintf(fout, "running%*s", len - 7 + 2, "");
|
||||||
else
|
else
|
||||||
fprintf(fout, "continued%*s", len - 9 + 2, "");
|
fprintf(fout, "continued%*s", len - 9 + 2, "");
|
||||||
else if (WIFEXITED(pn->status))
|
}
|
||||||
|
else if (WIFEXITED(pn->status)) {
|
||||||
if (WEXITSTATUS(pn->status))
|
if (WEXITSTATUS(pn->status))
|
||||||
fprintf(fout, "exit %-4d%*s", WEXITSTATUS(pn->status),
|
fprintf(fout, "exit %-4d%*s", WEXITSTATUS(pn->status),
|
||||||
len - 9 + 2, "");
|
len - 9 + 2, "");
|
||||||
else
|
else
|
||||||
fprintf(fout, "done%*s", len - 4 + 2, "");
|
fprintf(fout, "done%*s", len - 4 + 2, "");
|
||||||
else if (WIFSTOPPED(pn->status))
|
} else if (WIFSTOPPED(pn->status))
|
||||||
fprintf(fout, "%-*s", len + 2, sigmsg[WSTOPSIG(pn->status)]);
|
fprintf(fout, "%-*s", len + 2, sigmsg[WSTOPSIG(pn->status)]);
|
||||||
else if (WCOREDUMP(pn->status))
|
else if (WCOREDUMP(pn->status))
|
||||||
fprintf(fout, "%s (core dumped)%*s",
|
fprintf(fout, "%s (core dumped)%*s",
|
||||||
|
|
@ -1071,7 +1073,7 @@ bin_fg(char *name, char **argv, char *ops, int func)
|
||||||
/* If you immediately type "exit" after "jobs", this *
|
/* If you immediately type "exit" after "jobs", this *
|
||||||
* will prevent zexit from complaining about stopped jobs */
|
* will prevent zexit from complaining about stopped jobs */
|
||||||
stopmsg = 2;
|
stopmsg = 2;
|
||||||
if (!*argv)
|
if (!*argv) {
|
||||||
/* This block handles all of the default cases (no arguments). bg,
|
/* This block handles all of the default cases (no arguments). bg,
|
||||||
fg and disown act on the current job, and jobs and wait act on all the
|
fg and disown act on the current job, and jobs and wait act on all the
|
||||||
jobs. */
|
jobs. */
|
||||||
|
|
@ -1100,6 +1102,7 @@ bin_fg(char *name, char **argv, char *ops, int func)
|
||||||
waitjob(job, SIGINT);
|
waitjob(job, SIGINT);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Defaults have been handled. We now have an argument or two, or three...
|
/* Defaults have been handled. We now have an argument or two, or three...
|
||||||
In the default case for bg, fg and disown, the argument will be provided by
|
In the default case for bg, fg and disown, the argument will be provided by
|
||||||
|
|
|
||||||
25
Src/lex.c
25
Src/lex.c
|
|
@ -457,11 +457,11 @@ add(int c)
|
||||||
|
|
||||||
#define SETPARBEGIN {if (zleparse && !(inbufflags & INP_ALIAS) && cs >= ll+1-inbufct) parbegin = inbufct;}
|
#define SETPARBEGIN {if (zleparse && !(inbufflags & INP_ALIAS) && cs >= ll+1-inbufct) parbegin = inbufct;}
|
||||||
#define SETPAREND {\
|
#define SETPAREND {\
|
||||||
if (zleparse && !(inbufflags & INP_ALIAS) && parbegin != -1 && parend == -1)\
|
if (zleparse && !(inbufflags & INP_ALIAS) && parbegin != -1 && parend == -1) {\
|
||||||
if (cs >= ll + 1 - inbufct)\
|
if (cs >= ll + 1 - inbufct)\
|
||||||
parbegin = -1;\
|
parbegin = -1;\
|
||||||
else\
|
else\
|
||||||
parend = inbufct;}
|
parend = inbufct;} }
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cmd_or_math(int cs_type)
|
cmd_or_math(int cs_type)
|
||||||
|
|
@ -823,20 +823,22 @@ gettokstr(int c, int sub)
|
||||||
case LX2_OUTPAR:
|
case LX2_OUTPAR:
|
||||||
if ((sub || in_brace_param) && isset(SHGLOB))
|
if ((sub || in_brace_param) && isset(SHGLOB))
|
||||||
break;
|
break;
|
||||||
if (!in_brace_param && !pct--)
|
if (!in_brace_param && !pct--) {
|
||||||
if (sub) {
|
if (sub) {
|
||||||
pct = 0;
|
pct = 0;
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
goto brk;
|
goto brk;
|
||||||
|
}
|
||||||
c = Outpar;
|
c = Outpar;
|
||||||
break;
|
break;
|
||||||
case LX2_BAR:
|
case LX2_BAR:
|
||||||
if (!pct && !in_brace_param)
|
if (!pct && !in_brace_param) {
|
||||||
if (sub)
|
if (sub)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
goto brk;
|
goto brk;
|
||||||
|
}
|
||||||
if (unset(SHGLOB) || (!sub && !in_brace_param))
|
if (unset(SHGLOB) || (!sub && !in_brace_param))
|
||||||
c = Bar;
|
c = Bar;
|
||||||
break;
|
break;
|
||||||
|
|
@ -912,8 +914,9 @@ gettokstr(int c, int sub)
|
||||||
*bptr = '\0';
|
*bptr = '\0';
|
||||||
return STRING;
|
return STRING;
|
||||||
}
|
}
|
||||||
if (in_brace_param)
|
if (in_brace_param) {
|
||||||
cmdpush(CS_BRACE);
|
cmdpush(CS_BRACE);
|
||||||
|
}
|
||||||
bct++;
|
bct++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -922,8 +925,9 @@ gettokstr(int c, int sub)
|
||||||
break;
|
break;
|
||||||
if (!bct)
|
if (!bct)
|
||||||
break;
|
break;
|
||||||
if (in_brace_param)
|
if (in_brace_param) {
|
||||||
cmdpop();
|
cmdpop();
|
||||||
|
}
|
||||||
if (bct-- == in_brace_param)
|
if (bct-- == in_brace_param)
|
||||||
in_brace_param = 0;
|
in_brace_param = 0;
|
||||||
c = Outbrace;
|
c = Outbrace;
|
||||||
|
|
@ -933,11 +937,12 @@ gettokstr(int c, int sub)
|
||||||
c = Comma;
|
c = Comma;
|
||||||
break;
|
break;
|
||||||
case LX2_OUTANG:
|
case LX2_OUTANG:
|
||||||
if (!intpos)
|
if (!intpos) {
|
||||||
if (in_brace_param || sub)
|
if (in_brace_param || sub)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
goto brk;
|
goto brk;
|
||||||
|
}
|
||||||
e = hgetc();
|
e = hgetc();
|
||||||
if (e != '(') {
|
if (e != '(') {
|
||||||
hungetc(e);
|
hungetc(e);
|
||||||
|
|
@ -1101,11 +1106,12 @@ gettokstr(int c, int sub)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
add(c);
|
add(c);
|
||||||
if (c == '\'')
|
if (c == '\'') {
|
||||||
if ((inquote = !inquote))
|
if ((inquote = !inquote))
|
||||||
STOPHIST
|
STOPHIST
|
||||||
else
|
else
|
||||||
ALLOWHIST
|
ALLOWHIST
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (inquote)
|
if (inquote)
|
||||||
ALLOWHIST
|
ALLOWHIST
|
||||||
|
|
@ -1260,8 +1266,9 @@ dquote_parse(char endchar, int sub)
|
||||||
}
|
}
|
||||||
if (intick == 2)
|
if (intick == 2)
|
||||||
ALLOWHIST
|
ALLOWHIST
|
||||||
if (intick)
|
if (intick) {
|
||||||
cmdpop();
|
cmdpop();
|
||||||
|
}
|
||||||
while (bct--)
|
while (bct--)
|
||||||
cmdpop();
|
cmdpop();
|
||||||
if (lexstop)
|
if (lexstop)
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ execfor(Cmd cmd)
|
||||||
List list;
|
List list;
|
||||||
Forcmd node;
|
Forcmd node;
|
||||||
char *str;
|
char *str;
|
||||||
int val;
|
int val = 0;
|
||||||
LinkList args;
|
LinkList args;
|
||||||
|
|
||||||
node = cmd->u.forcmd;
|
node = cmd->u.forcmd;
|
||||||
|
|
|
||||||
58
Src/mem.c
58
Src/mem.c
|
|
@ -129,26 +129,52 @@ global_permalloc(void)
|
||||||
return luh;
|
return luh;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* heappush saves the current heap state using this structure */
|
|
||||||
|
|
||||||
struct heapstack {
|
|
||||||
struct heapstack *next; /* next one in list for this heap */
|
|
||||||
size_t used;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A zsh heap. */
|
|
||||||
|
|
||||||
struct heap {
|
|
||||||
struct heap *next; /* next one */
|
|
||||||
size_t used; /* bytes used from the heap */
|
|
||||||
struct heapstack *sp; /* used by pushheap() to save the value used */
|
|
||||||
#define arena(X) ((char *) (X) + sizeof(struct heap))
|
|
||||||
};
|
|
||||||
|
|
||||||
/* list of zsh heap */
|
/* list of zsh heap */
|
||||||
|
|
||||||
static Heap heaps;
|
static Heap heaps;
|
||||||
|
|
||||||
|
/* Use new heaps from now on. This returns the old heap-list. */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
Heap
|
||||||
|
new_heaps(void)
|
||||||
|
{
|
||||||
|
Heap h = heaps;
|
||||||
|
|
||||||
|
heaps = NULL;
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Re-install the old heaps again, freeing the new ones. */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void
|
||||||
|
old_heaps(Heap old)
|
||||||
|
{
|
||||||
|
Heap h, n;
|
||||||
|
|
||||||
|
for (h = heaps; h; h = n) {
|
||||||
|
n = h->next;
|
||||||
|
DPUTS(h->sp, "BUG: old_heaps() with pushed heaps");
|
||||||
|
zfree(h, sizeof(*h));
|
||||||
|
}
|
||||||
|
heaps = old;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Temporarily switch to other heaps (or back again). */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
Heap
|
||||||
|
switch_heaps(Heap new)
|
||||||
|
{
|
||||||
|
Heap h = heaps;
|
||||||
|
|
||||||
|
heaps = new;
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
/* save states of zsh heaps */
|
/* save states of zsh heaps */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,17 @@ for x_mod in $x_mods; do
|
||||||
*" $x_mod "*) ;;
|
*" $x_mod "*) ;;
|
||||||
*) echo "/* non-linked-in known module \`$x_mod' */"
|
*) echo "/* non-linked-in known module \`$x_mod' */"
|
||||||
eval "loc=\$loc_$x_mod"
|
eval "loc=\$loc_$x_mod"
|
||||||
unset moddeps autobins
|
unset moddeps autobins autoinfixconds autoprefixconds
|
||||||
. $srcdir/../$loc/${x_mod}.mdd
|
. $srcdir/../$loc/${x_mod}.mdd
|
||||||
for bin in $autobins; do
|
for bin in $autobins; do
|
||||||
echo " add_autobin(\"$bin\", \"$x_mod\");"
|
echo " add_autobin(\"$bin\", \"$x_mod\");"
|
||||||
done
|
done
|
||||||
|
for cond in $autoinfixconds; do
|
||||||
|
echo " add_autocond(\"$cond\", 1, \"$x_mod\");"
|
||||||
|
done
|
||||||
|
for cond in $autoprefixconds; do
|
||||||
|
echo " add_autocond(\"$cond\", 0, \"$x_mod\");"
|
||||||
|
done
|
||||||
for dep in $moddeps; do
|
for dep in $moddeps; do
|
||||||
case $bin_mods in
|
case $bin_mods in
|
||||||
*" $dep "*)
|
*" $dep "*)
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,18 @@
|
||||||
# defines one module. The .mdd file is actually a shell script, which will
|
# defines one module. The .mdd file is actually a shell script, which will
|
||||||
# be sourced. It may define the following shell variables:
|
# be sourced. It may define the following shell variables:
|
||||||
#
|
#
|
||||||
# moddeps modules on which this module depends (default none)
|
# moddeps modules on which this module depends (default none)
|
||||||
# nozshdep non-empty indicates no dependence on the `zsh' pseudo-module
|
# nozshdep non-empty indicates no dependence on the `zsh' pseudo-module
|
||||||
# alwayslink if non-empty, always link the module into the executable
|
# alwayslink if non-empty, always link the module into the executable
|
||||||
# autobins builtins defined by the module, for autoloading
|
# autobins builtins defined by the module, for autoloading
|
||||||
# objects .o files making up this module (*must* be defined)
|
# autoinfixconds infix condition codes defined by the module, for
|
||||||
# proto .pro files for this module (default generated from $objects)
|
# autoloading (without the leading `-')
|
||||||
# headers extra headers for this module (default none)
|
# autoprefixconds like autoinfixconds, but for prefix condition codes
|
||||||
# hdrdeps extra headers on which the .mdh depends (default none)
|
# objects .o files making up this module (*must* be defined)
|
||||||
# otherincs extra headers that are included indirectly (default none)
|
# proto .pro files for this module (default generated from $objects)
|
||||||
|
# headers extra headers for this module (default none)
|
||||||
|
# hdrdeps extra headers on which the .mdh depends (default none)
|
||||||
|
# otherincs extra headers that are included indirectly (default none)
|
||||||
#
|
#
|
||||||
# The .mdd file may also include a Makefile.in fragment between lines
|
# The .mdd file may also include a Makefile.in fragment between lines
|
||||||
# `:<<\Make' and `Make' -- this will be copied into Makemod.in.
|
# `:<<\Make' and `Make' -- this will be copied into Makemod.in.
|
||||||
|
|
@ -167,7 +170,7 @@ if $first_stage; then
|
||||||
for module in $here_modules; do
|
for module in $here_modules; do
|
||||||
|
|
||||||
unset moddeps nozshdep alwayslink hasexport
|
unset moddeps nozshdep alwayslink hasexport
|
||||||
unset autobins
|
unset autobins autoinfixconds autoprefixconds
|
||||||
unset objects proto headers hdrdeps otherincs
|
unset objects proto headers hdrdeps otherincs
|
||||||
. $top_srcdir/$the_subdir/${module}.mdd
|
. $top_srcdir/$the_subdir/${module}.mdd
|
||||||
test -n "${moddeps+set}" || moddeps=
|
test -n "${moddeps+set}" || moddeps=
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,6 @@ deletewrapper(Module m, FuncWrap w)
|
||||||
|
|
||||||
static char *dlerrstr[256];
|
static char *dlerrstr[256];
|
||||||
|
|
||||||
/**/
|
|
||||||
static void *
|
static void *
|
||||||
load_and_bind(const char *fn)
|
load_and_bind(const char *fn)
|
||||||
{
|
{
|
||||||
|
|
@ -277,7 +276,6 @@ load_and_bind(const char *fn)
|
||||||
# define dlopen(file,mode) (void *)shl_load((file), (mode), (long) 0)
|
# define dlopen(file,mode) (void *)shl_load((file), (mode), (long) 0)
|
||||||
# define dlclose(handle) shl_unload((shl_t)(handle))
|
# define dlclose(handle) shl_unload((shl_t)(handle))
|
||||||
|
|
||||||
/**/
|
|
||||||
static
|
static
|
||||||
void *
|
void *
|
||||||
hpux_dlsym(void *handle, char *name)
|
hpux_dlsym(void *handle, char *name)
|
||||||
|
|
|
||||||
12
Src/params.c
12
Src/params.c
|
|
@ -765,7 +765,7 @@ getarg(char **str, int *inv, Value v, int a2, long *w)
|
||||||
} else if (rev) {
|
} else if (rev) {
|
||||||
v->isarr |= SCANPM_WANTVALS;
|
v->isarr |= SCANPM_WANTVALS;
|
||||||
}
|
}
|
||||||
if (!down)
|
if (!down && PM_TYPE(v->pm->flags) == PM_HASHED)
|
||||||
v->isarr &= ~SCANPM_MATCHMANY;
|
v->isarr &= ~SCANPM_MATCHMANY;
|
||||||
*inv = ind;
|
*inv = ind;
|
||||||
}
|
}
|
||||||
|
|
@ -1534,6 +1534,12 @@ setaparam(char *s, char **val)
|
||||||
if (!(v = getvalue(&s, 1)))
|
if (!(v = getvalue(&s, 1)))
|
||||||
createparam(t, PM_ARRAY);
|
createparam(t, PM_ARRAY);
|
||||||
*ss = '[';
|
*ss = '[';
|
||||||
|
if (PM_TYPE(v->pm->flags) == PM_HASHED) {
|
||||||
|
zerr("attempt to set slice of associative array", NULL, 0);
|
||||||
|
freearray(val);
|
||||||
|
errflag = 1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
v = NULL;
|
v = NULL;
|
||||||
} else {
|
} else {
|
||||||
if (!(v = getvalue(&s, 1)))
|
if (!(v = getvalue(&s, 1)))
|
||||||
|
|
@ -1571,13 +1577,13 @@ sethparam(char *s, char **val)
|
||||||
}
|
}
|
||||||
if (strchr(s, '[')) {
|
if (strchr(s, '[')) {
|
||||||
freearray(val);
|
freearray(val);
|
||||||
zerr("attempt to set slice of associative array", NULL, 0);
|
zerr("nested associative arrays not yet supported", NULL, 0);
|
||||||
errflag = 1;
|
errflag = 1;
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
if (!(v = getvalue(&s, 1)))
|
if (!(v = getvalue(&s, 1)))
|
||||||
createparam(t, PM_HASHED);
|
createparam(t, PM_HASHED);
|
||||||
else if (!(PM_TYPE(v->pm->flags) & (PM_ARRAY|PM_HASHED)) &&
|
else if (!(PM_TYPE(v->pm->flags) & PM_HASHED) &&
|
||||||
!(v->pm->flags & PM_SPECIAL)) {
|
!(v->pm->flags & PM_SPECIAL)) {
|
||||||
unsetparam(t);
|
unsetparam(t);
|
||||||
createparam(t, PM_HASHED);
|
createparam(t, PM_HASHED);
|
||||||
|
|
|
||||||
|
|
@ -387,11 +387,11 @@ filesubstr(char **namptr, int assign)
|
||||||
for (pp = str + 1; !isend2(*pp); pp++);
|
for (pp = str + 1; !isend2(*pp); pp++);
|
||||||
sav = *pp;
|
sav = *pp;
|
||||||
*pp = 0;
|
*pp = 0;
|
||||||
if (!(cnam = findcmd(str + 1))) {
|
if (!(cnam = findcmd(str + 1, 1))) {
|
||||||
Alias a = (Alias) aliastab->getnode(aliastab, str + 1);
|
Alias a = (Alias) aliastab->getnode(aliastab, str + 1);
|
||||||
|
|
||||||
if (a)
|
if (a)
|
||||||
cnam = ztrdup(a->text);
|
cnam = a->text;
|
||||||
else {
|
else {
|
||||||
if (isset(NOMATCH))
|
if (isset(NOMATCH))
|
||||||
zerr("%s not found", str + 1, 0);
|
zerr("%s not found", str + 1, 0);
|
||||||
|
|
@ -399,7 +399,6 @@ filesubstr(char **namptr, int assign)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*namptr = dupstring(cnam);
|
*namptr = dupstring(cnam);
|
||||||
zsfree(cnam);
|
|
||||||
if (sav) {
|
if (sav) {
|
||||||
*pp = sav;
|
*pp = sav;
|
||||||
*namptr = dyncat(*namptr, pp);
|
*namptr = dyncat(*namptr, pp);
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini)
|
||||||
# endif /* WATCH_UTMP_UT_HOST */
|
# endif /* WATCH_UTMP_UT_HOST */
|
||||||
|
|
||||||
while (*fmt)
|
while (*fmt)
|
||||||
if (*fmt == '\\')
|
if (*fmt == '\\') {
|
||||||
if (*++fmt) {
|
if (*++fmt) {
|
||||||
if (prnt)
|
if (prnt)
|
||||||
putchar(*fmt);
|
putchar(*fmt);
|
||||||
|
|
@ -244,6 +244,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini)
|
||||||
return fmt;
|
return fmt;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
else if (*fmt == fini)
|
else if (*fmt == fini)
|
||||||
return ++fmt;
|
return ++fmt;
|
||||||
else if (*fmt != '%') {
|
else if (*fmt != '%') {
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ closem
|
||||||
cmdnamtab
|
cmdnamtab
|
||||||
columns
|
columns
|
||||||
compctlreadptr
|
compctlreadptr
|
||||||
|
cond_match
|
||||||
cond_str
|
cond_str
|
||||||
cond_val
|
cond_val
|
||||||
coprocin
|
coprocin
|
||||||
|
|
@ -104,6 +105,8 @@ inredir
|
||||||
insertlinknode
|
insertlinknode
|
||||||
install_handler
|
install_handler
|
||||||
intr
|
intr
|
||||||
|
intvargetfn
|
||||||
|
intvarsetfn
|
||||||
inwhat
|
inwhat
|
||||||
isfirstln
|
isfirstln
|
||||||
jobtab
|
jobtab
|
||||||
|
|
@ -126,6 +129,7 @@ mypgrp
|
||||||
mypid
|
mypid
|
||||||
nameddirtab
|
nameddirtab
|
||||||
ncalloc
|
ncalloc
|
||||||
|
new_heaps
|
||||||
newhashtable
|
newhashtable
|
||||||
newlinklist
|
newlinklist
|
||||||
nicechar
|
nicechar
|
||||||
|
|
@ -137,6 +141,7 @@ noerrs
|
||||||
noholdintr
|
noholdintr
|
||||||
noop_function
|
noop_function
|
||||||
noop_function_int
|
noop_function_int
|
||||||
|
old_heaps
|
||||||
optiontab
|
optiontab
|
||||||
opts
|
opts
|
||||||
paramtab
|
paramtab
|
||||||
|
|
@ -148,6 +153,7 @@ path
|
||||||
pathchecked
|
pathchecked
|
||||||
popheap
|
popheap
|
||||||
postedit
|
postedit
|
||||||
|
pparams
|
||||||
ppid
|
ppid
|
||||||
prefork
|
prefork
|
||||||
prepromptfns
|
prepromptfns
|
||||||
|
|
@ -197,6 +203,9 @@ strpfx
|
||||||
strsfx
|
strsfx
|
||||||
strucpy
|
strucpy
|
||||||
struncpy
|
struncpy
|
||||||
|
strvargetfn
|
||||||
|
strvarsetfn
|
||||||
|
switch_heaps
|
||||||
tclen
|
tclen
|
||||||
tcstr
|
tcstr
|
||||||
termflags
|
termflags
|
||||||
|
|
|
||||||
34
Src/zsh.h
34
Src/zsh.h
|
|
@ -1305,6 +1305,22 @@ struct ttyinfo {
|
||||||
* Memory management *
|
* Memory management *
|
||||||
*********************/
|
*********************/
|
||||||
|
|
||||||
|
/* heappush saves the current heap state using this structure */
|
||||||
|
|
||||||
|
struct heapstack {
|
||||||
|
struct heapstack *next; /* next one in list for this heap */
|
||||||
|
size_t used;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A zsh heap. */
|
||||||
|
|
||||||
|
struct heap {
|
||||||
|
struct heap *next; /* next one */
|
||||||
|
size_t used; /* bytes used from the heap */
|
||||||
|
struct heapstack *sp; /* used by pushheap() to save the value used */
|
||||||
|
#define arena(X) ((char *) (X) + sizeof(struct heap))
|
||||||
|
};
|
||||||
|
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
# define HEAPALLOC do { int nonlocal_useheap = global_heapalloc(); do
|
# define HEAPALLOC do { int nonlocal_useheap = global_heapalloc(); do
|
||||||
|
|
||||||
|
|
@ -1318,6 +1334,13 @@ struct ttyinfo {
|
||||||
# define LASTALLOC_RETURN \
|
# define LASTALLOC_RETURN \
|
||||||
if ((nonlocal_useheap ? global_heapalloc() : \
|
if ((nonlocal_useheap ? global_heapalloc() : \
|
||||||
global_permalloc()), 0) {;} else return
|
global_permalloc()), 0) {;} else return
|
||||||
|
|
||||||
|
# define NEWHEAPS(h) do { Heap oldheaps = h = new_heaps(); do
|
||||||
|
# define OLDHEAPS while (0); old_heaps(oldheaps); } while (0);
|
||||||
|
|
||||||
|
# define SWITCHHEAPS(h) do { Heap oldheaps = switch_heaps(h); do
|
||||||
|
# define SWITCHBACKHEAPS while (0); switch_heaps(oldheaps); } while (0);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# define HEAPALLOC do { int nonlocal_useheap = global_heapalloc(); \
|
# define HEAPALLOC do { int nonlocal_useheap = global_heapalloc(); \
|
||||||
alloc_stackp++; do
|
alloc_stackp++; do
|
||||||
|
|
@ -1333,6 +1356,17 @@ struct ttyinfo {
|
||||||
# define LASTALLOC_RETURN \
|
# define LASTALLOC_RETURN \
|
||||||
if ((nonlocal_useheap ? global_heapalloc() : \
|
if ((nonlocal_useheap ? global_heapalloc() : \
|
||||||
global_permalloc()),alloc_stackp--,0){;}else return
|
global_permalloc()),alloc_stackp--,0){;}else return
|
||||||
|
|
||||||
|
# define NEWHEAPS(h) do { Heap oldheaps = h = new_heaps(); \
|
||||||
|
alloc_stackp++; do
|
||||||
|
# define OLDHEAPS while (0); alloc_stackp--; \
|
||||||
|
old_heaps(oldheaps); } while (0);
|
||||||
|
|
||||||
|
# define SWITCHHEAPS(h) do { Heap oldheaps = switch_heaps(h); \
|
||||||
|
alloc_stackp++; do
|
||||||
|
# define SWITCHBACKHEAPS while (0); alloc_stackp--; \
|
||||||
|
switch_heaps(oldheaps); } while (0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************/
|
/****************/
|
||||||
|
|
|
||||||
|
|
@ -120,15 +120,18 @@ Modules are described by a file named `foo.mdd' for a module
|
||||||
is build. To describe the module it can/should set the following shell
|
is build. To describe the module it can/should set the following shell
|
||||||
variables:
|
variables:
|
||||||
|
|
||||||
- moddeps modules on which this module depends (default none)
|
- moddeps modules on which this module depends (default none)
|
||||||
- nozshdep non-empty indicates no dependence on the `zsh' pseudo-module
|
- nozshdep non-empty indicates no dependence on the `zsh' pseudo-module
|
||||||
- alwayslink if non-empty, always link the module into the executable
|
- alwayslink if non-empty, always link the module into the executable
|
||||||
- autobins builtins defined by the module, for autoloading
|
- autobins builtins defined by the module, for autoloading
|
||||||
- objects .o files making up this module (*must* be defined)
|
- autoinfixconds infix condition codes defined by the module, for
|
||||||
- proto .pro files for this module (default generated from $objects)
|
autoloading (without the leading `-')
|
||||||
- headers extra headers for this module (default none)
|
- autoprefixconds like autoinfixconds, but for prefix condition codes
|
||||||
- hdrdeps extra headers on which the .mdh depends (default none)
|
- objects .o files making up this module (*must* be defined)
|
||||||
- otherincs extra headers that are included indirectly (default none)
|
- proto .pro files for this module (default generated from $objects)
|
||||||
|
- headers extra headers for this module (default none)
|
||||||
|
- hdrdeps extra headers on which the .mdh depends (default none)
|
||||||
|
- otherincs extra headers that are included indirectly (default none)
|
||||||
|
|
||||||
Be sure to put the values in quotes. For further enlightenment have a
|
Be sure to put the values in quotes. For further enlightenment have a
|
||||||
look at the `mkmakemod.sh' script in the Src directory of the
|
look at the `mkmakemod.sh' script in the Src directory of the
|
||||||
|
|
|
||||||
2
aczsh.m4
2
aczsh.m4
|
|
@ -45,7 +45,7 @@ else
|
||||||
fi
|
fi
|
||||||
echo '
|
echo '
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
void *symlist1[] = {
|
void *symlist1[[]] = {
|
||||||
(void *)&environ,
|
(void *)&environ,
|
||||||
(void *)0
|
(void *)0
|
||||||
};
|
};
|
||||||
|
|
|
||||||
19
configure.in
19
configure.in
|
|
@ -340,7 +340,7 @@ AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \
|
||||||
termios.h sys/param.h sys/filio.h string.h memory.h \
|
termios.h sys/param.h sys/filio.h string.h memory.h \
|
||||||
limits.h fcntl.h libc.h sys/utsname.h sys/resource.h \
|
limits.h fcntl.h libc.h sys/utsname.h sys/resource.h \
|
||||||
locale.h errno.h stdlib.h unistd.h sys/capability.h \
|
locale.h errno.h stdlib.h unistd.h sys/capability.h \
|
||||||
utmp.h utmpx.h sys/types.h pwd.h grp.h)
|
utmp.h utmpx.h sys/types.h pwd.h grp.h poll.h)
|
||||||
if test $dynamic = yes; then
|
if test $dynamic = yes; then
|
||||||
AC_CHECK_HEADERS(dlfcn.h)
|
AC_CHECK_HEADERS(dlfcn.h)
|
||||||
AC_CHECK_HEADERS(dl.h)
|
AC_CHECK_HEADERS(dl.h)
|
||||||
|
|
@ -467,9 +467,22 @@ elif test $zsh_cv_decl_ospeed_must_define = yes; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl Check if tgetent accepts NULL (and will allocate its own termcap buffer)
|
dnl Check if tgetent accepts NULL (and will allocate its own termcap buffer)
|
||||||
|
dnl Some termcaps reportedly accept a zero buffer, but then dump core
|
||||||
|
dnl in tgetstr().
|
||||||
AC_CACHE_CHECK(if tgetent accepts NULL,
|
AC_CACHE_CHECK(if tgetent accepts NULL,
|
||||||
zsh_cv_func_tgetent_accepts_null,
|
zsh_cv_func_tgetent_accepts_null,
|
||||||
[AC_TRY_RUN([main(){int i = tgetent((char*)0,"vt100");exit(!i || i == -1);}],
|
[AC_TRY_RUN([
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
int i = tgetent((char*)0,"vt100");
|
||||||
|
if (i > 0) {
|
||||||
|
char tbuf[1024], *u;
|
||||||
|
u = tbuf;
|
||||||
|
tgetstr("cl", &u);
|
||||||
|
}
|
||||||
|
exit(!i || i == -1);
|
||||||
|
}
|
||||||
|
],
|
||||||
zsh_cv_func_tgetent_accepts_null=yes,
|
zsh_cv_func_tgetent_accepts_null=yes,
|
||||||
zsh_cv_func_tgetent_accepts_null=no,
|
zsh_cv_func_tgetent_accepts_null=no,
|
||||||
zsh_cv_func_tgetent_accepts_null=no)])
|
zsh_cv_func_tgetent_accepts_null=no)])
|
||||||
|
|
@ -615,7 +628,7 @@ dnl need to integrate this function
|
||||||
dnl AC_FUNC_STRFTIME
|
dnl AC_FUNC_STRFTIME
|
||||||
|
|
||||||
AC_CHECK_FUNCS(memcpy memmove \
|
AC_CHECK_FUNCS(memcpy memmove \
|
||||||
strftime waitpid select tcsetpgrp tcgetattr strstr lstat \
|
strftime waitpid select poll tcsetpgrp tcgetattr strstr lstat \
|
||||||
getlogin setpgid gettimeofday gethostname mkfifo wait3 difftime \
|
getlogin setpgid gettimeofday gethostname mkfifo wait3 difftime \
|
||||||
sigblock sigsetmask sigrelse sighold killpg sigaction getrlimit \
|
sigblock sigsetmask sigrelse sighold killpg sigaction getrlimit \
|
||||||
sigprocmask setuid seteuid setreuid setresuid setsid strerror \
|
sigprocmask setuid seteuid setreuid setresuid setsid strerror \
|
||||||
|
|
|
||||||
|
|
@ -213,3 +213,56 @@ Sven's ignored character fix, 4828
|
||||||
More Sven condition patches, 4837, 4842
|
More Sven condition patches, 4837, 4842
|
||||||
|
|
||||||
Final (???) isident() fix from Sven, 4845
|
Final (???) isident() fix from Sven, 4845
|
||||||
|
|
||||||
|
pws-5
|
||||||
|
|
||||||
|
Name of top level directory is now zsh-3.1.5-pws-5
|
||||||
|
|
||||||
|
Missing part of Bart's sethparam() changes, 4851
|
||||||
|
|
||||||
|
zftp test subcommand, 4852
|
||||||
|
|
||||||
|
Geoff's refresh fix for a line the same length as the terminal width,
|
||||||
|
4855
|
||||||
|
|
||||||
|
Bart's fix for array slices, 4874
|
||||||
|
|
||||||
|
Sven's accept-and-menu-complete-fix, 4878
|
||||||
|
|
||||||
|
Sven's group completion fix, 4879
|
||||||
|
|
||||||
|
Sven's module condition fixes, 4880
|
||||||
|
|
||||||
|
Oliver Kiddle's autoconf fix, 4887
|
||||||
|
|
||||||
|
My zftp fix (actually due to Andrej Borsenkow) for systems which only
|
||||||
|
allow dup'ing sockets after they are connected, 4888.
|
||||||
|
|
||||||
|
Bart's fix to making setting associative array elements inside
|
||||||
|
substitutions consistent, 4893
|
||||||
|
|
||||||
|
My typeset neatness and -a and -m fix, 4902
|
||||||
|
|
||||||
|
My brief Etc/MACHINES addition, 4912
|
||||||
|
|
||||||
|
My modification to findcmd() for memory leaks, 4923, plus comment
|
||||||
|
alteration by Bart, 4924
|
||||||
|
|
||||||
|
Sven's patch for completion after various reserved words, 4930
|
||||||
|
|
||||||
|
My patch for compiler warnings, 4931
|
||||||
|
|
||||||
|
My configuration fix for when tgetent() accepts a null argument but
|
||||||
|
then tgetstr() dumps core, 4939
|
||||||
|
|
||||||
|
Sven's alteration of `-t' behaviour, 4940. This is slightly
|
||||||
|
incompatible with previous patched versions of 3.1.5 since now you don't
|
||||||
|
need '-tc' with -T. However, you now do need '-tn' in cases where you
|
||||||
|
don't want normal completion tried after a -T matches.
|
||||||
|
|
||||||
|
Sven's new completion functions, 4850, 4881, 4941, 4942, 4943, 4944,
|
||||||
|
4946, 4949, plus my addition of function pointers, 4945. The example
|
||||||
|
file is now in Misc/new-completion-examples.
|
||||||
|
|
||||||
|
(Effect of) fix from Helmut Jarausch in 4947 partly due to change
|
||||||
|
missed in patch.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue