1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-06-16 08:48:06 +02:00

zsh-3.1.6-test-2

This commit is contained in:
Tanaka Akira 1999-07-19 14:26:14 +00:00
parent 1f6786ef7a
commit d6d4a3abfc
50 changed files with 821 additions and 295 deletions

141
ChangeLog
View file

@ -1,5 +1,146 @@
1999-07-19 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: version 3.1.6-test-2
* pws: 7192: Src/glob.c: bug with null in pattern if at end of
test string (matched as if a real character).
1999-07-18 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 7185: Src/glob.c: don't use strcoll() for character
ranges [...] because it can have side effects.
* pws: 7184: Src/lex.c: histactive didn't get get zeroed before
non-interactive history use, hence interactive lines with
remhist() were junked more than once.
* Wayne: 7181: Doc/Zsh/options.y, Doc/Zsh/params.yo: history docs.
* Wayne: 7180: Src/Zle/complist.c, Src/utils.c: warnings.
1999-07-16 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 7172: Doc/Zsh/options.yo, Src/builtin.c, Src/exec.c,
Src/options.c, Src/utils.c, Src/zsh.h: minor bugs with
7164 fixed; CHASE_DOTS resolves ..'s to physical path;
CHASE_LINKS doesn't do logical path rationalization;
xsymlink() and xsymlinks() simplified and option-dependence
removed.
* Sven: 7171: Src/builtin.c: alternate form of Digital/gcc
bug workaround.
1999-07-15 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 7164: Src/builtin.c, Src/exec.c: AUTOCD now allows
paths with symlinks (as real cd always did); simplify code
for testing for existing directory on foo/.. before removing
foo/..; as a side effect, relative cd's from directory which
has been deleted don't work.
* Sven: 7161: Src/Zle/comp.h, Src/Zle/complist.c,
Src/Zle/zle_tricky.c, Completion/Base/_brace_parameter:
be more careful with quote-prefix/suffix and path-prefix/suffix
especially with accept-and-menu-complete.
* pws: 7155: Functions/Zftp/zfgoto, Functions/Zftp/zfinit:
zfgoto can cd without needing to re-login; zfinit uses
zmodload -e to check for zftp.
* Sven: 7154: Src/Zle/complist.c, Src/Zle/zle_refresh.c,
Src/Zle/zle_tricky.c, Doc/Zsh/mod_complist.yo: don't
list too many times on ambiguous completion; don't do
menu-selection if no alwayslastprompt behaviour.
1999-07-14 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 7148: INSTALL: User subdirectory
* Thomas Köhler: 7146: Completion/User/_make: didn't work.
* pws: 7145: Completion/User/_sh: use compset -q for completing
after -c option
* Sven: 7143: Src/Zle/complist.c, Src/Zle/zle_tricky.c:
listing got confused with only hidden matches.
* Sven: 7141: Completion/Core/_path_files: if there are
no completions in a valid directory when we have a path ending
in /, use the directory as a completion, to avoid
correction/approximation of the existing directory.
* pws: 7139: Src/builtin.c: not particularly pleasant fix
to problem that `cd nonexistent/..' silently did nothing, while
making `cd ..' work even if current directory has gone.
* Sven: 7138: Completion/User/_hosts, Completion/User/_x_options:
_hosts passes arguments as options to compadd.
* Oliver: 7136: Completion/User/_rlogin,
Completion/User/_x_options: use _hosts.
* Sven: 7135: Src/Zle/zle_tricky.c, Completion/Core/_path_files:
change quoting of files again.
* Sven: 7133: Doc/Zsh/expn.yo, Doc/Zsh/mod_complist.yo:
ZLS_COLOURS not required for complist to work.
* pws: 7127: configure.in: help now shows --disable-dynamic
and --disable-lfs.
* Sven: 7126: Src/Zle/comp.h, Src/Zle/comp1.c, Src/Zle/compctl.c,
Src/Zle/zle_tricky.c, Doc/Zsh/compwid.yo,
Functions/Zle/incremental-complete-word: compstate key
normal_nmatches; more i-c-w prompt escapes
* Sven: 7123: Src/Zle/zle_tricky.c: clear list on expansion
failure.
1999-07-13 Peter Stephenson <pws@ibmth.df.unipi.it>
* pws: 7119: Src/Zle/zle_tricky.c: status from expansion
functions.
* Sven: 7116: Doc/Zsh/compwid.yo, Doc/Zsh/expn.yo: minor
changes.
* pws: 7114: Src/parse.c, Src/utils.c: line numbers again:
flushing line in a script made lineno appear one too large;
introduce zwarn() function.
* Sven/pws: 7112: Src/Zle/zle_params.c, Doc/Zsh/zle.yo: change
array keys to scalar KEYS, works more like read -k;
documentation.
* Sven: 7110: Src/Modules/zftp.c, Doc/Zsh/compsys.yo,
Etc/MACHINES: signed char warnings in zftp; document
_long_options options; Digital UNIX problem.
* Sven: 2432: Src/builtin.c: workaround Digital UNIX 4.0 +
gcc 2.8.1 bug.
* Sven: zsh-users/2430: Etc/NEWS: mention chmod-like mode glob
qualifier.
* Sven: 7108: Misc/job-control-tests: more tests
* Bart: 7107: configure.in: too many x's in lfs handling.
* Sven: 7106: Functions/Zle/incremental-complete-word: prompting
changes.
* pws: unposted: update .distfiles and .cvsignore: _sh, _su
zshcompsys.yo, zshcompwid.yo, zshzftp.yo, zshcompsys.1,
zshcompwid.1, zshzftp.1 were missing from the distribution.
* Sven: 7105: Src/Zle/Zle_tricky.c: restore the command line
in more places.
1999-07-12 Peter Stephenson <pws@ibmth.df.unipi.it>
* Sven: 7103: Src/Zle/zle_tricky.c, Doc/Zsh/compwid.yo: update
CURRENT with compset -q; modify test for quoted delimiters.
* pws: version 3.1.6-test-1
* Sven: 7099: Completion/Core/_main_complete, Doc/Zsh/compsys.yo:

1
Completion/.cvsignore Normal file
View file

@ -0,0 +1 @@
Makefile

View file

@ -1,3 +1,3 @@
DISTFILES_SRC='
.distfiles README Makefile.in
.cvsignore .distfiles README Makefile.in
'

View file

@ -18,4 +18,4 @@ q=${(M)lp%%\"#}
[[ n -gt 0 ]] && suf=''
_parameters -s "${q[1,-n-1]}" -S "$suf" -r '-:?#%+=[/'
_parameters -Qs "${q[1,-n-1]}" -S "$suf" -r '-:?#%+=[/'

View file

@ -244,7 +244,7 @@ for prepath in "$prepaths[@]"; do
if [[ "$tmp2[1]" = */* ]]; then
tmp2=( "${(@)tmp2#${prepath}${realpath}}" )
if [[ "$tmp2[1]" = */* ]]; then
exppaths=( "$exppaths[@]" ${^tmp2:h}/${tpre}${tsuf} )
exppaths=( "$exppaths[@]" ${^tmp2:h:q}/${tpre}${tsuf} )
else
exppaths=( "$exppaths[@]" ${tpre}${tsuf} )
fi
@ -252,6 +252,18 @@ for prepath in "$prepaths[@]"; do
continue 2
fi
elif (( ! $#tmp1 )); then
# A little extra hack: if we were completing `foo/<TAB>' and `foo'
# contains no files, this will normally produce no matches and other
# completers might think that's it's their time now. But if the next
# completer is _correct or something like that, this will result in
# an attempt to correct a valid directory name. So we just add the
# original string in such a case so that the command line doesn't
# change but other completers still think there are matches.
if [[ -z "$tpre$tsuf" && "$pre" = */ && -z "$suf" ]]; then
compadd -nQS '' - "$linepath$donepath$orig"
tmp4=-
fi
continue 2
fi
@ -310,33 +322,33 @@ for prepath in "$prepaths[@]"; do
if [[ -n $menu ]]; then
[[ -n "$compconfig[path_cursor]" ]] && compstate[to_end]=''
if [[ "$tmp3" = */* ]]; then
compadd -Uf -p "$linepath$testpath" -s "/${tmp3#*/}" \
compadd -QUf -p "$linepath${testpath:q}" -s "/${tmp3#*/}" \
-W "$prepath$realpath$testpath" "$ignore[@]" \
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" -M 'r:|/=* r:|=*' \
"$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
- "${(@)tmp1%%/*}"
- "${(@)${(@)tmp1%%/*}:q}"
else
compadd -Uf -p "$linepath$testpath" \
compadd -QUf -p "$linepath${testpath:q}" \
-W "$prepath$realpath$testpath" "$ignore[@]" \
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" \
"$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
- "$tmp1[@]"
- "${(@)tmp1:q}"
fi
else
if [[ "$tmp3" = */* ]]; then
for i in "$tmp1[@]"; do
compadd -Uf -p "$linepath$testpath" -s "/${i#*/}" \
compadd -QUf -p "$linepath${testpath:q}" -s "/${${i#*/}:q}" \
-W "$prepath$realpath$testpath" "$ignore[@]" \
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" -M 'r:|/=* r:|=*' \
"$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
- "${i%%/*}"
- "${${i%%/*}:q}"
done
else
compadd -Uf -p "$linepath$testpath" \
compadd -QUf -p "$linepath${testpath:q}" \
-W "$prepath$realpath$testpath" "$ignore[@]" \
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" \
"$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
- "$tmp1[@]"
- "${(@)tmp1:q}"
fi
fi
tmp4=-
@ -361,11 +373,11 @@ for prepath in "$prepaths[@]"; do
done
if [[ -z "$tmp4" ]]; then
compadd -Uf -p "$linepath$testpath" \
compadd -QUf -p "$linepath${testpath:q}" \
-W "$prepath$realpath$testpath" "$ignore[@]" \
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" \
"$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
- "$tmp1[@]"
- "${(@)tmp1:q}"
fi
done
@ -376,9 +388,9 @@ done
exppaths=( "${(@)exppaths:#$orig}" )
if [[ -n "$compconfig[path_expand]" &&
$#exppaths -eq 1 && nm -eq compstate[nmatches] ]]; then
$#exppaths -gt 0 && nm -eq compstate[nmatches] ]]; then
compadd -QU -S '' "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
-M 'r:|/=* r:|=*' -p "$linepath" - "${(@)exppaths}"
-M 'r:|/=* r:|=*' -p "$linepath" - "$exppaths[@]"
fi
[[ nm -ne compstate[nmatches] ]]

View file

@ -1,6 +1,8 @@
DISTFILES_SRC='
.distfiles
_a2ps _chown _compress _configure _dd _dvi _find _groups _gunzip _gzip
_hosts _use_lo _make _man _mh _pdf _ps _rcs _rlogin _strip _stty
_a2ps _chown _compress _configure _dd _dvi _find
_gdb _groups _gunzip _gzip
_hosts _use_lo _make _man _mh _pdf _ps
_rcs _rlogin _sh _strip _stty _su
_tar _tar_archive _tex _uncompress _x_options _xfig
'

50
Completion/User/_gdb Normal file
View file

@ -0,0 +1,50 @@
#compdef gdb
# This uses the configuration keys `ps_args' and `ps_listargs'
# described in the `_wait' function.
local cur="$words[CURRENT]" prev w list ret=1
_long_options -t '*=(CORE|SYM)FILE' '_files' \
'*=EXECFILE' '_files *(*)' \
'*=TTY' 'compadd /dev/tty*' && return 0
if compset -P '-(cd|directory)='; then
_files -/
elif compset -P '-tty='; then
compadd - /dev/tty*
elif compset -P '-(exec|se)='; then
_files -/g '*(*)'
elif compset -P '-(symbols|core|command)='; then
_files
elif compset -P -; then
compadd -QS '' - symbols\= exec\= se\= core\= command\= directory\= \
cd\= tty\=
compadd - help h s e c x d nx n quiet q batch fullname f b
else
prev="$words[CURRENT-1]"
case "$prev" in
(-d) _files -/ && return 0 ;;
(-e) _files -/g '*(*)' && return 0 ;;
(-[csx]) _files && return 0 ;;
(-b) compadd -V baud 0 50 75 110 134 150 200 300 600 1200 1800 2400 4800 \
9600 19200 38400 57600 115200 230400 && return 0 ;;
esac
w=( "${(@)words[2,-1]}" )
while [[ "$w[1]" = -* ]]; do
[[ "$w[1]" = -[decsxb] ]] && shift 1 w
shift 1 w
done
if [[ $#w -gt 1 ]]; then
_files && ret=0
list=("${(F)${(@Mr:COLUMNS-1:)${(f)$(ps ${compconfig[ps_listargs]:-$compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ ]#${PREFIX}[0-9]#${SUFFIX}[ ]*${w[1]:t}}}
")
compadd -y list - ${${${(M)${(f)"$(ps $compconfig[ps_args] 2>/dev/null)"}:#*${w[1]:t}*}## #}%% *} && ret=0
return ret
else
_files -/g '*(*)'
fi
fi

View file

@ -2,4 +2,4 @@
: ${(A)hosts:=${(s: :)${(ps:\t:)${${(f)"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}}
compgen -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' -k hosts
compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' "$@" - "$hosts[@]"

View file

@ -19,6 +19,6 @@ else
fi
[[ -n "$file" ]] &&
compadd - $(awk '/^[a-zA-Z0-9][^/ ]+:/ {print $1}' FS=: $file) && ret=0
compadd - $(awk '/^[a-zA-Z0-9][^\/ ]+:/ {print $1}' FS=: $file) && ret=0
(( ret )) && _files
fi

View file

@ -1,7 +1,7 @@
#compdef rlogin rsh ssh
if [[ CURRENT -eq 2 ]]; then
compgen -k hosts
_hosts
elif [[ CURRENT -eq 3 ]]; then
compadd - -l
else

8
Completion/User/_sh Normal file
View file

@ -0,0 +1,8 @@
#compdef sh ksh bash zsh csh tcsh rc
if (( CURRENT == ${words[(i)-c]} + 1 )); then
compset -q
_normal
else
_default
fi

22
Completion/User/_su Normal file
View file

@ -0,0 +1,22 @@
#compdef su
local shell comp name usr base
[[ $words[2] != - ]]
(( base=$?+2 ))
if [[ CURRENT -eq base ]]; then
compgen -u && return
usr=root
elif [[ CURRENT -ge base+1 ]]; then
usr=$words[base]
else
return
fi
shell=${"$(egrep "^$usr:" </etc/passwd)"##*:}
compset -n $base
for name in $shell $shell:t -default-; do
comp="$_comps[$name]"
[[ ! -z "$comp" ]] && "$comp" && return
done

View file

@ -3,7 +3,8 @@
# A simple pattern completion, just as an example.
if [ "$words[CURRENT-1]" = "-display" ]; then
compgen -k hosts -S':0'
_compskip=''
_hosts -S :0
else
compadd -J options - -display -name -xrm
compadd -P- -J options - display name xrm
fi

View file

@ -27,5 +27,5 @@
# This must also serve as a shell script, so do not add spaces around the
# `=' signs.
VERSION=3.1.6-test-1
VERSION_DATE='July 9, 1999'
VERSION=3.1.6-test-2
VERSION_DATE='July 19, 1999'

View file

@ -2,11 +2,13 @@ DISTFILES_SRC='
.cvsignore .distfiles Makefile.in
META-FAQ.yo intro.ms
version.yo zmacros.yo zman.yo ztexi.yo
zsh.yo zshbuiltins.yo zshcompctl.yo zshexpn.yo zshmisc.yo
zshmodules.yo zshoptions.yo zshparam.yo zshzle.yo
zsh.yo zshbuiltins.yo zshcompctl.yo zshcompsys.yo zshcompwid.yo
zshexpn.yo zshmisc.yo zshmodules.yo zshoptions.yo zshparam.yo
zshzftpsys.yo zshzle.yo
zsh.texi
zsh.1 zshbuiltins.1 zshcompctl.1 zshexpn.1 zshmisc.1 zshmodules.1
zshoptions.1 zshparam.1 zshzle.1 zshall.1
zsh.1 zshbuiltins.1 zshcompctl.1 zshcompsys.1 zshcompwid.1 zshexpn.1
zshmisc.1 zshmodules.1 zshoptions.1 zshparam.1 zshzle.1 zshall.1
zshzftpsys.1
'
DISTFILES_DOC='

View file

@ -31,7 +31,7 @@ next section.
Usually, tt(compinstall) will insert code into tt(.zshrc), although if
that is not writable it will save it in another file and tell you that
file's locations. Note that it is up to you to make sure that the lines
file's location. Note that it is up to you to make sure that the lines
added to tt(.zshrc) are actually run; you may, for example, need to move
them to an earlier place in the file if tt(.zshrc) usually returns early.
So long as you keep them all together (including the comment lines at the
@ -92,7 +92,7 @@ will only need to run this yourself if you change the configuration
(e.g. using tt(compdef)) and then want to dump the new one. The name of
the old dumped file will be remembered for this purpose.
If the parameter tt(_compdir) is set, tt(compinit) uses it has a directory
If the parameter tt(_compdir) is set, tt(compinit) uses it as a directory
where completion functions can be found; this is only necessary if they are
not already in the function search path.
@ -489,7 +489,7 @@ non-empty string it should be an expression usable inside a `tt($((...)))'
arithmetical expression. In this case, expansion of substitutions will
be done if the expression evaluates to `tt(1)'. For example, with
example(compconf expand_substitute='NUMERIC != 1')
example(compconf expand_substitute='${NUMERIC:-1} != 1')
substitution will be performed only if given an explicit numeric
argument other than `tt(1)', as by typing `tt(ESC 2 TAB)'.
@ -720,8 +720,8 @@ is used.
)
item(tt(_parameters))(
This should be used to complete parameter names if you need some of the
extra options of tt(compadd). It first tries to complete only non-local
parameters. All arguments are passed unchanged to the tt(compadd) builtin.
extra options of tt(compadd). All arguments are passed unchanged to
the tt(compadd) builtin.
)
item(tt(_options))(
This can be used to complete option names. The difference to the
@ -780,9 +780,19 @@ descriptions that contain `tt(=DIR)' or `tt(=PATH)'. These builtin
patterns can be overridden by patterns given as arguments, however.
This function also accepts the `tt(-X)', `tt(-J)', and `tt(-V)'
options which are passed unchanged to `tt(compadd)'. Finally, it
accepts the option `tt(-t)'; if this is given, completion is only done
on words starting with two hyphens.
options which are passed unchanged to `tt(compadd)'. If the
option `tt(-t)' is given, completion is only done on words starting
with two hyphens. The option `tt(-i) var(patterns)' can be used to
give patterns for options which should not be completed. The patterns
can be given as the name of an array parameter or as a literal list in
parentheses. E.g. `tt(-i "(--(en|dis)able-FEATURE*)")' will ignore the
options `tt(--enable-FEATURE)' and `tt(--diable-FEATURE)'. Finally,
the option `tt(-s) var(pairs)' can be used to describe options
aliases. Each var(pair) consists of a pattern and a
replacement. E.g. some tt(configure)-scripts describe options only as
`tt(--enable-foo)', but also accept `tt(disable-foo)'. To allow
completion of the second form, one would use
`tt(-s "(#--enable- --disable-)")'.
)
enditem()

View file

@ -175,6 +175,12 @@ is unset.
item(tt(nmatches))(
The number of matches generated and accepted by the completion code so far.
)
item(tt(normal_nmatches))(
Like tt(nmatches), but counts only matches in the normal set. I.e. file
names with one of the suffixes from the tt(fignore) array and matches
put into the alternate set using the tt(-a) option of the tt(compadd)
builtin command (see below) are not counted.
)
item(tt(matcher))(
When completion is performed with a global match specification as defined
by
@ -410,7 +416,7 @@ item(tt(-I) var(ignored-suffix))(
Like tt(-i), but gives an ignored suffix.
)
item(tt(-y) var(array))(
This gives a number of string to display instead of the matches. This
This gives a number of strings to display instead of the matches. This
is like the tt(-y) option of the tt(compctl) builtin command but the
var(array) argument may only be the name of an array parameter or a
literal array in parentheses containing the strings to display.
@ -483,7 +489,7 @@ from the first set are stored. Normally only the matches in the first
set are used, but if this set is empty, the words from the alternate
set are used.
The tt(compadd) builtin does not use tt(fignore) parameter and
The tt(compadd) builtin does not use the tt(fignore) parameter and
normally stores all words in the first set. With the tt(-a)-flag
given, however, the given var(words) are stored in the alternate set unless
this flag is overridden by the tt(-F) option.
@ -518,7 +524,7 @@ will be done by the completion code. Normally this is used in
functions that do the matching themselves.
Note that with tt(compadd) this option does not automatically turn on
menu completion if tt(AUTO_LIST), unlike the corresponding option of
menu completion if tt(AUTO_LIST) is set, unlike the corresponding option of
tt(compctl) and tt(compgen) commands.
)
item(tt(-O) var(array))(
@ -622,9 +628,9 @@ testing and modification is performed as if it were not given.
item(tt(-q))(
The word
currently being completed is split in separate words at the spaces. The
resulting words are stored in the tt(words) array, and tt(PREFIX),
tt(SUFFIX), tt(QIPREFIX), and tt(QISUFFIX) are modified to reflect the
word part that is completed.
resulting words are stored in the tt(words) array, and tt(CURRENT),
tt(PREFIX), tt(SUFFIX), tt(QIPREFIX), and tt(QISUFFIX) are modified to
reflect the word part that is completed.
)
enditem()

View file

@ -1192,7 +1192,7 @@ grouping the string as tt([d][cb][a]) and tt([a][bc][d]).
Non-literal parts of the pattern must match exactly, including characters
in character ranges: hence tt(LPAR()#a1)tt(RPAR()???) matches strings of
length four, by applying rule 4 to an empty part of the pattern, but not
strings of length three, since all the tt(?) must match. Other characters
strings of length two, since all the tt(?) must match. Other characters
which must match exactly are initial dots in filenames (unless the
tt(GLOB_DOTS) option is set), and all slashes in file names, so that
tt(a/bc) is two errors from tt(ab/c) (the slash cannot be transposed with
@ -1351,7 +1351,7 @@ bit.
Thus, `tt(*(f70?))' gives the files for which the owner has read,
write, and execute permission, and for which other group members have
no rights, independent of the permissions for other user. The pattern
no rights, independent of the permissions for other users. The pattern
`tt(*(f-100))' gives all files for which the owner does not have
execute permission, and `tt(*(f:gu+w,o-rx))' gives the files for which
the owner and the other members of the group have at least write
@ -1455,7 +1455,7 @@ returned list. The syntax is the same as for array
subscripts. var(beg) and the optional var(end) may be mathematical
expressions. As in parameter subscripting they may be negative to make
them count from the last match backward. E.g.: `tt(*(-OL[1,3]))'
gives a list of the names of three biggest files.
gives a list of the names of the three largest files.
)
enditem()

View file

@ -12,9 +12,9 @@ not automatically be loaded if it is not linked in: on systems with
dynamic loading, `tt(zmodload complist)' is required.
subsect(Parameters)
For both extensions one of the parameters tt(ZLS_COLORS) or tt(ZLS_COLOURS)
must be set, even if the value is empty (which uses all the default values
given below). These describe how matches are highlighted. The format of the
The parameters tt(ZLS_COLORS) and tt(ZLS_COLOURS) describe how matches
are highlighted. To turn on highlighting an empty value suffices, in
which case all the default values given below will be used. The format of the
value of these parameters is the same as used by the GNU version of the
tt(ls) command: a colon-separated list of specifications of the form
`var(name)=var(value)'. The var(name) may be one of the following strings,
@ -79,7 +79,12 @@ the default values will have no visual effect.
subsect(Menu selection)
The tt(complist) module also offers an alternative style of selecting
matches from a list, called menu-selection. It can be invoked directly by
matches from a list, called menu-selection, which can be used if the
shell is set up to return to the last prompt after showing a
completion list (see the tt(ALWAYS_LAST_PROMPT) option in
ifzman(zmanref(zshoptions))\
ifnzman(noderef(Options))\
). It can be invoked directly by
the widget tt(menu-select) defined by the module. Alternatively,
the parameter tt(SELECTMIN) can be set to an integer, which give the
minimum number of matches that must be present before menu selection is

View file

@ -205,11 +205,30 @@ tt(AUTO_CD) option set) is not a directory, and does not begin with a
slash, try to expand the expression as if it were preceded by a `tt(~)' (see
noderef(Filename Expansion)).
)
pindex(CHASE_DOTS)
cindex(cd, with .. in argument)
item(tt(CHASE_DOTS))(
When changing to a directory containing a path segment `tt(..)' which would
otherwise be treated as cancelling the previous segment in the path (in
other words, `tt(foo/..)' would be removed from the path, or if `tt(..)' is
the first part of the path, the last part of tt($PWD) would be deleted),
instead resolve the path to the physical directory. This option is
overridden by tt(CHASE_LINKS).
For example, suppose tt(/foo/bar) is a link to the directory tt(/alt/rod).
Without this option set, `tt(cd /foo/bar/..)' changes to tt(/foo); with it
set, it changes to tt(/alt). The same applies if the current directory
is tt(/foo/bar) and `tt(cd ..)' is used. Note that all other symbolic
links in the path will also be resolved.
)
pindex(CHASE_LINKS)
cindex(links, symbolic)
cindex(symbolic links)
item(tt(CHASE_LINKS) (tt(-w)))(
Resolve symbolic links to their true values when changing directory.
This also has the effect of tt(CHASE_DOTS), i.e. a `tt(..)' path segment
will be treated as referring to the physical parent, even if the preceeding
path segment is a symbolic link.
)
pindex(CLOBBER)
cindex(clobbering, of files)
@ -416,9 +435,13 @@ isn't there.
pindex(HIST_EXPIRE_DUPS_FIRST)
cindex(history, expiring duplicates)
item(tt(HIST_EXPIRE_DUPS_FIRST))(
If the internal history needs to be trimmed to add a new line,
setting this option will cause the oldest duplicate history line to
be lost before losing a unique line from the list.
If the internal history needs to be trimmed to add the current command line,
setting this option will cause the oldest history event that has a duplicate
to be lost before losing a unique event from the list.
You should be sure to set the value of tt(HISTSIZE) to a larger number
than tt(SAVEHIST) in order to give you some room for the duplicated
events, otherwise this option will behave just like
tt(HIST_IGNORE_ALL_DUPS) once the history fills up with unique events.
)
pindex(HIST_IGNORE_ALL_DUPS)
cindex(history, ignoring all duplicates)

View file

@ -507,7 +507,10 @@ If unset, the history is not saved.
)
vindex(HISTSIZE)
item(tt(HISTSIZE) <S>)(
The maximum size of the history list.
The maximum number of events stored in the internal history list.
If you use the tt(HIST_EXPIRE_DUPS_FIRST) option, setting this value
larger than the tt(SAVEHIST) size will give you the difference as a
cushion for saving duplicated history events.
)
vindex(HOME)
item(tt(HOME) <S>)(

View file

@ -154,12 +154,9 @@ vindex(LASTWIDGET)
item(tt(LASTWIDGET) (scalar))(
The name of the last widget that was executed.
)
vindex(keys)
item(tt(keys) (array))(
The keys typed to invoke this widget, one element per
key. Control-keys are reported with a leading `tt(^)', as in `tt(^A)',
and meta-keys are reported with a leading `tt(M-)', as in `tt(M-a)' and
`tt(M-^A)'.
vindex(KEYS)
item(tt(KEYS) (scalar))(
The keys typed to invoke this widget, as a literal string.
)
vindex(NUMERIC)
item(tt(NUMERIC) (integer))(

View file

@ -39,15 +39,21 @@ DEC: OSF/1 1.2, 1.3, 2.0, 3.*, DEC Unix 4.* (Alpha)
remove the bogus strip and use /bin/strip instead.
On Digital UNIX 4.0, compilation with gcc and with --enable-dynamic
apparently needs configuring with explicit flags:
apparently needs configuring with explicit flags when compiling
with debugging enabled:
DLLD=gcc LDFLAGS='-g -rpath <path-to-.so-files>' ./configure ...
FreeBSD: FreeBSD 2.2.7 [3.1.4]
Should build `out-of-the-box'.
HP: HP-UX 9, 10.20
HP: HP-UX 9, 10.20, 11.0
Should build `out-of-the-box'.
Problems with dynamic loading have been reported under 11, but
this should compile using the standard dlopen() function set
(rather than the 10.20 shl_load() function set). More details of
any difficulties would be appreciated.
IBM: AIX
Should build `out-of-the-box'. On AIX 3.x (at least),
--enable-zsh-mem will not work.
@ -87,9 +93,6 @@ SGI: IRIX 5.1.1.1, 5.2, 5.3, 6.2, 6.3, 6.5
full optimization (cc -O3 -OPT:Olimit=0) causes problems.
Sun: SunOS 4.1.*
Dynamic loading does not work under SunOS 4.1. Sometimes,
you may need to turn it off explicitly with --disable-dynamic.
Under 4.1.3 if yellow pages is used, username completion may cause
segmentation violation. This is a bug in the shared library not
in zsh. Some libc.so.1.9.* has this bug (it fails in yp_all).

View file

@ -34,6 +34,7 @@ Globbing changes:
- Case-insensitive and approximate globbing.
- Ordering and indexing of globbing matches, e.g. *(om[1]) picks
most recently modified file.
- General file mode qualifier with chmod(1)-like syntax, e.g. *(f:u+wx:)
New loadable modules:
- zftp, plus associated function suite, for turning your zsh session

1
Functions/.cvsignore Normal file
View file

@ -0,0 +1 @@
Makefile

View file

@ -1,3 +1,3 @@
DISTFILES_SRC='
.distfiles Makefile.in README.zftp
.cvsignore .distfiles Makefile.in README.zftp
'

View file

@ -67,7 +67,10 @@ line=${line#*@}
host=${line%%:*}
dir=${line#*:}
if [[ $user = ftp || $user = anonymous ]]; then
if [[ $ZFTP_USER = $user && $ZFTP_HOST = $host ]]; then
# We're already there, just change directory
zfcd ${dir:-~}
elif [[ $user = ftp || $user = anonymous ]]; then
# Anonymous ftp, so we don't need password etc.
zfanon $host && [[ -n $dir ]] && zfcd $dir
elif [[ $zflastsession = ${host}:* && $user = $zflastuser ]]; then

View file

@ -1,6 +1,6 @@
emulate -L zsh
[[ $1 = -n ]] || zmodload -ia zftp
[[ $1 = -n ]] || zmodload -e zftp || zmodload -ia zftp
alias zfcd='noglob zfcd'
alias zfget='noglob zfget'

View file

@ -4,32 +4,55 @@
# to a key.
# This allows incremental completion of a word. After starting this
# command, a list of completion choices is shown after every character you
# type, which you can delete with ^h or DEL. RET will accept the
# completion so far. You can hit TAB to do normal completion and ^g to
# abort back to the state when you started.
# command, a list of completion choices can be shown after every character
# you type, which you can delete with ^h or DEL. RET will accept the
# completion so far. You can hit TAB to do normal completion, ^g to
# abort back to the state when you started, and ^d to list the matches.
#
# Completion keys:
# incremental_prompt Prompt to show in status line during icompletion;
# the sequence `%u' is replaced by the unambiguous
# part of all matches if there is any and it is
# different from the word on the line
# incremental_stop Pattern matching keys which will cause icompletion
# to stop and the key to be re-executed
# incremental_break Pattern matching keys which will cause icompletion
# to stop and the key to be discarded
# incremental_completer Set of completers, like the `completer' key
# incremental_list If set to a non-empty string, the matches will be
# listed on every key-press
# This works best with the new function based completion system.
#
# Configuration keys:
#
# incremental_prompt
# Prompt to show in status line during icompletion. The sequence `%u'
# is replaced by the unambiguous part of all matches if there is any
# and it is different from the word on the line. A `%s' is replaced
# with `-no match-', `-no prefix-', or an empty string if there is
# no completion matching the word on the line, if the matches have
# no common prefix different from the word on the line or if there is
# such a common prefix, respectively. The sequence `%c' is replaced
# by the name of the completer function that generated the matches
# (without the leading underscore). Finally, `%n' is replaced by the
# number of matches generated and `%a' is replaced by an empty string
# if the matches are in the normal set (i.e. the one without file names
# with one of the suffixes from `fignore') and with ` -alt-' if the
# matches are in the alternate set.
#
# incremental_stop
# Pattern matching keys which will cause icompletion to stop and the
# key to be re-executed.
#
# incremental_break
# Pattern matching keys which will cause icompletion to stop and the
# key to be discarded.
#
# incremental_completer
# Set of completers, like the `completer' key for normal completion.
#
# incremental_list
# If set to a non-empty string, the matches will be listed on every
# key-press.
emulate -L zsh
unsetopt autolist menucomplete automenu # doesn't work well
local key lbuf="$LBUFFER" rbuf="$RBUFFER" pmpt word lastl lastr wid twid
local key lbuf="$LBUFFER" rbuf="$RBUFFER" pmpt word
local lastl lastr wid twid num alt
[[ -n "$compconfig[incremental_completer]" ]] &&
set ${(s.:.)compconfig[incremental_completer]}
pmpt="${compconfig[incremental_prompt]-incremental completion...}"
set ${(s.:.)compconfig[incremental_completer]}
pmpt="${compconfig[incremental_prompt]-incremental (%c): %u%s}"
if [[ -n "$compconfig[incremental_list]" ]]; then
wid=list-choices
@ -40,12 +63,22 @@ fi
zle $wid "$@"
LBUFFER="$lbuf"
RBUFFER="$rbuf"
if [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
if (( ! _lastcomp[nmatches] )); then
word=''
state='-no match-'
elif [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
word=''
state='-no prefix-'
else
word="${_lastcomp[unambiguous]}"
state=''
fi
zle -R "${pmpt//\\%u/$word}"
num=$_lastcomp[normal_nmatches]
if (( ! num )); then
num="${_lastcomp[nmatches]}"
alt=' -alt-'
fi
zle -R "${${${${${pmpt//\\%u/$word}//\\%s/$state}//\\%c/${_lastcomp[completer][2,-1]}}//\\%n/$num}//\\%a/$alt}"
read -k key
while [[ '#key' -ne '#\\r' && '#key' -ne '#\\n' &&
@ -72,12 +105,24 @@ while [[ '#key' -ne '#\\r' && '#key' -ne '#\\n' &&
zle $twid "$@"
LBUFFER="$lastl"
RBUFFER="$lastr"
if [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
if (( ! _lastcomp[nmatches] )); then
word=''
state='-no match-'
elif [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
word=''
state='-no prefix-'
else
word="${_lastcomp[unambiguous]}"
state=''
fi
zle -R "${pmpt//\\%u/$word}"
num=$_lastcomp[normal_nmatches]
if (( ! num )); then
num="${_lastcomp[nmatches]}"
alt=' -alt-'
else
alt=''
fi
zle -R "${${${${${pmpt//\\%u/$word}//\\%s/$state}//\\%c/${_lastcomp[completer][2,-1]}}//\\%n/$num}//\\%a/$alt}"
read -k key
done

View file

@ -246,9 +246,12 @@ plus those provide functions for the line editor, i.e.
FUNCTIONS_INSTALL='Core/* Base/* Builtins/* User/* Commands/* Zle/*'
and if the --enable-dynamic option was given, the functions in
Functions/Zftp, which require the zftp module to be available (see the
zshzftpsys manual page), will be included as well. There are also some
miscellaneous functions with documentation in comments; the complete set
of functions can be installed with
zshzftpsys manual page), will be included as well. Note, however, that
some of the functions in the User subdirectory are version- and
system-specific.
There are also some miscellaneous functions with documentation in comments;
the complete set of functions can be installed with
FUNCTIONS_INSTALL='Core/* Base/* Builtins/* User/* Commands/* \
Misc/* Zftp/* Zle/*'
Note you should set this by hand to include `Zftp/*' if you have zftp

View file

@ -29,3 +29,48 @@ while true; do sed -e 's/foo/bar/' Src/builtin.c >/dev/null; done
# ignoring the error messages from sed.
# ^Z is more of a problem since you have to catch the sed.
while true; do sed -e 's/foo/bar/' non-existent-file >/dev/null; done
# Try
# ^Z
# fg
# ^Z
# fg
fn() {
local a
while read a; do :; done
less "$@"
}
cat foo | fn bar
# Try
# ^Z
# fg
fn() {
cat builtin.c
}
fn | while read a; do :; done
# Try
# ^Z
# fg
# q
# ^Z
# fg
# q
fn() {
less builtin.c
echo done
}
x=2; while (( x-- )); do f; done
# Try
# ^C
# This won't work because zcat doesn't tell us that it received a signal.
# But
# ^Z
# fg
# ^C (probably a second ^C is needed: if the continued zcat is still running)
# works.
# (See also the file Etc/BUGS)
while true; do zcat foo.gz > /dev/null; done

View file

@ -2261,7 +2261,7 @@ zftp_type(char *name, char **args, int flags)
fflush(stdout);
return 0;
} else {
nt = toupper(*str);
nt = toupper(STOUC(*str));
/*
* RFC959 specifies other types, but these are the only
* ones we know what to do with.
@ -2294,7 +2294,7 @@ zftp_mode(char *name, char **args, int flags)
fflush(stdout);
return 0;
}
nt = str[0] = toupper(*str);
nt = str[0] = toupper(STOUC(*str));
if (str[1] || (nt != 'S' && nt != 'B')) {
zwarnnam(name, "transfer mode %s not recognised", str, 0);
return 1;
@ -2651,7 +2651,7 @@ bin_zftp(char *name, char **args, char *ops, int func)
if ((prefs = getsparam("ZFTP_PREFS"))) {
zfprefs = 0;
for (ptr = prefs; *ptr; ptr++) {
switch (toupper(*ptr)) {
switch (toupper(STOUC(*ptr))) {
case 'S':
/* sendport */
zfprefs |= ZFPF_SNDP;

View file

@ -218,6 +218,8 @@ struct cmatch {
int brsl; /* ...and the suffix */
char *rems; /* when to remove the suffix */
char *remf; /* shell function to call for suffix-removal */
int qipl; /* length of quote-prefix */
int qisl; /* length of quote-suffix */
int rnum; /* group relative number */
int gnum; /* global number */
};
@ -349,25 +351,25 @@ struct chdata {
#define CPN_NMATCHES 0
#define CP_NMATCHES (1 << CPN_NMATCHES)
#define CP_NMATCHES (1 << CPN_NMATCHES)
#define CPN_MATCHER 1
#define CP_MATCHER (1 << CPN_MATCHER)
#define CP_MATCHER (1 << CPN_MATCHER)
#define CPN_MATCHERSTR 2
#define CP_MATCHERSTR (1 << CPN_MATCHERSTR)
#define CP_MATCHERSTR (1 << CPN_MATCHERSTR)
#define CPN_MATCHERTOT 3
#define CP_MATCHERTOT (1 << CPN_MATCHERTOT)
#define CP_MATCHERTOT (1 << CPN_MATCHERTOT)
#define CPN_CONTEXT 4
#define CP_CONTEXT (1 << CPN_CONTEXT)
#define CP_CONTEXT (1 << CPN_CONTEXT)
#define CPN_PARAMETER 5
#define CP_PARAMETER (1 << CPN_PARAMETER)
#define CP_PARAMETER (1 << CPN_PARAMETER)
#define CPN_REDIRECT 6
#define CP_REDIRECT (1 << CPN_REDIRECT)
#define CP_REDIRECT (1 << CPN_REDIRECT)
#define CPN_QUOTE 7
#define CP_QUOTE (1 << CPN_QUOTE)
#define CP_QUOTE (1 << CPN_QUOTE)
#define CPN_QUOTING 8
#define CP_QUOTING (1 << CPN_QUOTING)
#define CP_QUOTING (1 << CPN_QUOTING)
#define CPN_RESTORE 9
#define CP_RESTORE (1 << CPN_RESTORE)
#define CP_RESTORE (1 << CPN_RESTORE)
#define CPN_LIST 10
#define CP_LIST (1 << CPN_LIST)
#define CPN_FORCELIST 11
@ -398,6 +400,8 @@ struct chdata {
#define CP_OLDINS (1 << CPN_OLDINS)
#define CPN_VARED 24
#define CP_VARED (1 << CPN_VARED)
#define CPN_NNMATCHES 25
#define CP_NNMATCHES (1 << CPN_NNMATCHES)
#define CP_KEYPARAMS 25
#define CP_KEYPARAMS 26
#define CP_ALLKEYS ((unsigned int) 0xffffff)

View file

@ -105,6 +105,7 @@ int incompfunc;
/**/
zlong compcurrent,
compnmatches,
compnnmatches,
compmatcher,
compmatchertot,
complistmax;

View file

@ -27,6 +27,7 @@ compmatcher
compmatcherstr
compmatchertot
compnmatches
compnnmatches
compoldlist
compoldins
compparameter

View file

@ -2210,6 +2210,7 @@ static struct compparam compkparams[] = {
{ "old_list", PM_SCALAR, VAL(compoldlist), NULL, NULL },
{ "old_insert", PM_SCALAR, VAL(compoldins), NULL, NULL },
{ "vared", PM_SCALAR, VAL(compvared), NULL, NULL },
{ "normal_nmatches", PM_INTEGER, VAL(compnnmatches), NULL, NULL },
{ NULL, 0, NULL, NULL, NULL }
};

View file

@ -308,8 +308,8 @@ complistmatches(Hookdef dummy, Chdata dat)
Cmatch *p, m;
Cexpl *e;
int nlines = 0, ncols, nlist = 0, longest = 1, pnl = 0, opl = 0;
int of = isset(LISTTYPES);
int mc, ml = 0, cc, hasm = 0, cl;
int of = isset(LISTTYPES), cf;
int mc, ml = 0, cc, hasm = 0, cl = -1;
struct listcols col;
if (minfo.asked == 2) {
@ -318,15 +318,6 @@ complistmatches(Hookdef dummy, Chdata dat)
}
getcols(&col);
/* Set the cursor below the prompt. */
if (inselect)
clearflag = 0;
trashzle();
showinglist = listshown = 0;
clearflag = (isset(USEZLE) && !termflags &&
complastprompt && *complastprompt);
for (g = amatches; g; g = g->next) {
char **pp = g->ylist;
int nl = 0, l;
@ -403,6 +394,19 @@ complistmatches(Hookdef dummy, Chdata dat)
nlines += 1 + ((1 + niceztrlen(m->str)) / columns);
}
}
cf = (isset(USEZLE) && !termflags && complastprompt && *complastprompt);
if (!nlines || (mselect >= 0 && (!cf || (nlines + nlnct - 1) >= lines))) {
showinglist = listshown = 0;
noselect = 1;
return 1;
}
/* Set the cursor below the prompt. */
if (inselect)
clearflag = 0;
trashzle();
showinglist = listshown = 0;
clearflag = cf;
/* Maybe we have to ask if the user wants to see the list. */
if ((!minfo.cur || !minfo.asked) &&
@ -654,20 +658,20 @@ complistmatches(Hookdef dummy, Chdata dat)
pnl = 1;
g = g->next;
}
if (clearflag) {
/* Move the cursor up to the prompt, if always_last_prompt *
* is set and all that... */
if ((nlines += nlnct - 1) < lines) {
tcmultout(TCUP, TCMULTUP, nlines);
showinglist = -1;
listshown = 1;
} else
clearflag = 0, putc('\n', shout);
} else
putc('\n', shout);
listshown = (clearflag ? 1 : -1);
if (!hasm || nlines >= lines)
noselect = 1;
return noselect;
}
@ -676,7 +680,7 @@ typedef struct menustack *Menustack;
struct menustack {
Menustack prev;
char *line;
int cs;
int cs, acc;
struct menuinfo info;
Cmgroup amatches, pmatches, lmatches;
};
@ -742,19 +746,19 @@ domenuselect(Hookdef dummy, Chdata dat)
s->amatches = amatches;
s->pmatches = pmatches;
s->lmatches = lmatches;
menucmp = 0;
s->acc = menuacc;
menucmp = menuacc = 0;
fixsuffix();
validlist = 0;
pmatches = NULL;
invalidatelist();
menucomplete(zlenoargs);
if (dat->num < 2 || !minfo.cur || !*(minfo.cur)) {
noselect = 1;
clearlist = 1;
noselect = clearlist = listshown = 1;
zrefresh();
break;
}
clearlist = 1;
clearlist = listshown = 1;
mselect = (*(minfo.cur))->gnum;
continue;
} else if (cmd == Th(z_acceptandhold) ||
@ -767,6 +771,7 @@ domenuselect(Hookdef dummy, Chdata dat)
s->cs = cs;
memcpy(&(s->info), &minfo, sizeof(struct menuinfo));
s->amatches = s->pmatches = s->lmatches = NULL;
s->acc = menuacc;
acceptlast();
do_menucmp(0);
mselect = (*(minfo.cur))->gnum;
@ -782,6 +787,7 @@ domenuselect(Hookdef dummy, Chdata dat)
spaceinline(l = strlen(u->line));
strncpy((char *) line, u->line, l);
cs = u->cs;
menuacc = u->acc;
memcpy(&minfo, &(u->info), sizeof(struct menuinfo));
p = &(minfo.cur);
if (u->pmatches && pmatches != u->pmatches) {

View file

@ -24,6 +24,7 @@ lastambig
linkkeymap
listshown
lmatches
menuacc
menucmp
menucomplete
menucur

View file

@ -67,7 +67,7 @@ static struct zleparam {
zleunsetfn, NULL },
{ "LASTWIDGET", PM_SCALAR | PM_READONLY, NULL, FN(get_lwidget),
zleunsetfn, NULL },
{ "keys", PM_ARRAY | PM_READONLY, NULL, FN(get_keys),
{ "KEYS", PM_SCALAR | PM_READONLY, NULL, FN(get_keys),
zleunsetfn, NULL },
{ "NUMERIC", PM_INTEGER | PM_UNSET, FN(set_numeric), FN(get_numeric),
unset_numeric, NULL },
@ -247,29 +247,10 @@ get_lwidget(Param pm)
}
/**/
static char **
static char *
get_keys(Param pm)
{
char **r, **q, *p, *k, c;
r = (char **) zhalloc((strlen(keybuf) + 1) * sizeof(char *));
for (q = r, p = keybuf; (c = *p); q++, p++) {
k = *q = (char *) zhalloc(5);
if (c & 0x80) {
*k++ = 'M';
*k++ = '-';
c &= 0x7f;
}
if (c < 32 || c == 0x7f) {
*k++ = '^';
c ^= 64;
}
*k++ = c;
*k = '\0';
}
*q = NULL;
return r;
return keybuf;
}
/**/

View file

@ -53,7 +53,8 @@ int nlnct;
/**/
int showinglist;
/* Non-zero if a completion list was displayed. */
/* > 0 if a completion list is displayed below the prompt,
* < 0 if a list is displayed above the prompt. */
/**/
int listshown;
@ -265,7 +266,7 @@ zrefresh(void)
if (inlist)
return;
if (clearlist && listshown) {
if (clearlist && listshown > 0) {
if (tccan(TCCLEAREOD)) {
int ovln = vln, ovcs = vcs;
char *nb = nbuf[vln];
@ -331,7 +332,8 @@ zrefresh(void)
tcout(TCCLEAREOD);
else
cleareol = 1; /* request: clear to end of line */
listshown = 0;
if (listshown > 0)
listshown = 0;
}
if (t0 > -1)
olnct = t0;

View file

@ -106,10 +106,11 @@ static int insmnum, insgnum, insgroup, insspace;
static int movetoend;
/* != 0 if we are in the middle of a menu completion */
/* != 0 if we are in the middle of a menu completion and number of matches
* accepted with accept-and-menu-complete */
/**/
int menucmp;
int menucmp, menuacc;
/* Information about menucompletion. */
@ -192,6 +193,10 @@ static char *qipre, *qisuf, autoq;
static int lpl, lsl, rpl, rsl, fpl, fsl, lppl, lpsl;
static int noreal;
/* A parameter expansion prefix (like ${). */
static char *parpre;
/* This is either zero or equal to the special character the word we are *
* trying to complete starts with (e.g. Tilde or Equals). */
@ -209,9 +214,9 @@ static char *qword;
static Cmgroup mgroup;
/* A match counter. */
/* Match counters: all matches, normal matches (not alternate set). */
static int mnum;
static int mnum, nmnum;
/* The match counter when unambig_data() was called. */
@ -540,6 +545,8 @@ reversemenucomplete(char **args)
void
acceptlast(void)
{
menuacc++;
if (brbeg && *brbeg) {
int l;
@ -553,10 +560,16 @@ acceptlast(void)
brbeg[l] = ',';
brbeg[l + 1] = '\0';
} else {
int l;
cs = minfo.pos + minfo.len + minfo.insc;
iremovesuffix(' ', 1);
l = cs;
cs = minfo.pos + minfo.len - (*(minfo.cur))->qisl;
foredel(l - cs);
inststrlen(" ", 1, 1);
if (parpre)
inststr(parpre);
minfo.insc = minfo.len = 0;
minfo.pos = cs;
minfo.we = 1;
@ -694,6 +707,9 @@ check_param(char *s, int set, int test)
{
char *p;
zsfree(parpre);
parpre = NULL;
if (!test)
ispar = parq = eparq = 0;
/* Try to find a `$'. */
@ -755,6 +771,8 @@ check_param(char *s, int set, int test)
/* Now make sure that the cursor is inside the name. */
if (offs <= e - s && offs >= b - s && n <= 0) {
char sav;
if (br) {
p = e;
while (*p == (test ? Dnull : '"'))
@ -782,6 +800,12 @@ check_param(char *s, int set, int test)
else
parq = eparq = 0;
/* Save the prefix. */
sav = *b;
*b = '\0';
untokenize(parpre = ztrdup(s));
*b = sav;
/* And adjust wb, we, and offs again. */
offs -= b - s;
wb = cs - offs;
@ -1017,7 +1041,7 @@ docomplete(int lst)
int ocs = cs, ne = noerrs;
noerrs = 1;
doexpansion(s, lst, olst, lincmd);
ret = doexpansion(s, lst, olst, lincmd);
lastambig = 0;
noerrs = ne;
@ -1043,8 +1067,8 @@ docomplete(int lst)
}
}
ret = docompletion(s, lst, lincmd);
} else
ret = !strcmp(ol, (char *) line);
} else if (ret)
clearlist = 1;
} else
/* Just do completion. */
ret = docompletion(s, lst, lincmd);
@ -1064,7 +1088,7 @@ docomplete(int lst)
dat.num = nmatches;
dat.cur = NULL;
if (runhookdef(MENUSTARTHOOK, (void *) &dat))
menucmp = 0;
menucmp = menuacc = 0;
}
return ret;
}
@ -1736,9 +1760,10 @@ get_comp_string(void)
/* Expand the current word. */
/**/
static void
static int
doexpansion(char *s, int lst, int olst, int explincmd)
{
int ret = 1;
LinkList vl;
char *ss;
@ -1775,7 +1800,7 @@ doexpansion(char *s, int lst, int olst, int explincmd)
}
if (lst == COMP_LIST_EXPAND) {
/* Only the list of expansions was requested. */
listlist(vl);
ret = listlist(vl);
showinglist = 0;
goto end;
}
@ -1783,6 +1808,7 @@ doexpansion(char *s, int lst, int olst, int explincmd)
cs = wb;
foredel(we - wb);
while ((ss = (char *)ugetnode(vl))) {
ret = 0;
untokenize(ss);
ss = quotename(ss, NULL);
inststr(ss);
@ -1801,6 +1827,8 @@ doexpansion(char *s, int lst, int olst, int explincmd)
end:
popheap();
} LASTALLOC;
return ret;
}
/* This is called from the lexer to give us word positions. */
@ -3547,6 +3575,8 @@ add_match_data(int alt, char *str, Cline line,
ai->line = join_clines(ai->line, line);
mnum++;
if (!alt)
nmnum++;
ai->count++;
/* Allocate and fill the match structure. */
@ -3569,6 +3599,8 @@ add_match_data(int alt, char *str, Cline line,
cm->flags = flags;
cm->brpl = bpl;
cm->brsl = bsl;
cm->qipl = qipl;
cm->qisl = qisl;
cm->autoq = (autoq ? autoq : (inbackt ? '`' : '\0'));
cm->rems = cm->remf = NULL;
addlinknode((alt ? fmatches : matches), cm);
@ -3896,6 +3928,7 @@ addmatches(Cadata dat, char **argv)
}
}
compnmatches = mnum;
compnnmatches = nmnum;
if (dat->exp)
addexpl();
if (dat->apar)
@ -4380,10 +4413,14 @@ docompletion(char *s, int lst, int incmd)
}
if (comppatmatch && *comppatmatch && comppatmatch != opm)
haspattern = 1;
if (!useline && uselist)
if (!useline && uselist) {
/* All this and the guy only wants to see the list, sigh. */
cs = 0;
foredel(ll);
inststr(origline);
cs = origcs;
showinglist = -2;
else if (useline) {
} else if (useline) {
/* We have matches. */
if (nmatches > 1) {
/* There is more than one match. */
@ -4399,9 +4436,13 @@ docompletion(char *s, int lst, int incmd)
do_single(m->matches[0]);
invalidatelist();
}
} else
} else {
invalidatelist();
cs = 0;
foredel(ll);
inststr(origline);
cs = origcs;
}
/* Print the explanation strings if needed. */
if (!showinglist && validlist && usemenu != 2 && nmatches != 1) {
Cmgroup g = amatches;
@ -4582,22 +4623,22 @@ callcompfunc(char *s, char *fn)
zsfree(compprefix);
zsfree(compsuffix);
if (unset(COMPLETEINWORD)) {
/* Maybe we'll have to do quoting here some time. */
tmp = dupstring(s);
tmp = quotename(s, NULL);
untokenize(tmp);
compprefix = ztrdup(tmp);
compsuffix = ztrdup("");
} else {
char *ss, sav;
tmp = dupstring(s);
ss = tmp + offs;
ss = s + offs;
sav = *ss;
*ss = '\0';
tmp = quotename(s, NULL);
untokenize(tmp);
compprefix = ztrdup(tmp);
*ss = sav;
ss = quotename(ss, NULL);
untokenize(ss);
compsuffix = ztrdup(ss);
}
@ -4611,6 +4652,7 @@ callcompfunc(char *s, char *fn)
compqisuffix = ztrdup(qisuf ? qisuf : "");
compcurrent = (usea ? (clwpos + 1 - aadd) : 0);
compnmatches = mnum;
compnnmatches = nmnum;
zsfree(complist);
switch (uselist) {
@ -4825,13 +4867,13 @@ makecomplist(char *s, int incmd, int lst)
if (!validlist)
lastambig = 0;
amatches = NULL;
mnum = 0;
mnum = nmnum = 0;
unambig_mnum = -1;
isuf = NULL;
insmnum = insgnum = 1;
insgroup = oldlist = oldins = 0;
begcmgroup("default", 0);
menucmp = 0;
menucmp = menuacc = 0;
ccused = newlinklist();
ccstack = newlinklist();
@ -4984,6 +5026,8 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
memcpy(tmp + sl + 1, s, noffs);
tmp[(scs = cs = sl + 1 + noffs)] = 'x';
strcpy(tmp + sl + 2 + noffs, s + noffs);
if (incompfunc)
tmp = rembslash(tmp);
inpush(dupstrspace(tmp), 0, NULL);
line = (unsigned char *) tmp;
ll = tl - 1;
@ -5013,6 +5057,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
p = NULL;
if (!got && !zleparse) {
DPUTS(!p, "no current word in substr");
got = 1;
cur = i;
swb = wb - 1;
swe = we - 1;
@ -5077,7 +5122,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
}
sav = s[(i = swb - sl - 1)];
s[i] = '\0';
qp = tricat(qipre, s, "");
qp = tricat(qipre, (incompfunc ? rembslash(s) : s), "");
s[i] = sav;
if (swe < swb)
swe = swb;
@ -5085,7 +5130,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
sl = strlen(s);
if (swe > sl)
swe = sl, ns[swe - swb + 1] = '\0';
qs = tricat(s + swe, qisuf, "");
qs = tricat((incompfunc ? rembslash(s + swe) : s + swe), qisuf, "");
sl = strlen(ns);
if (soffs > sl)
soffs = sl;
@ -5172,7 +5217,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
compisuffix = ztrdup("");
zsfree(compqiprefix);
zsfree(compqisuffix);
if (instring) {
if (ois) {
compqiprefix = qp;
compqisuffix = qs;
} else {
@ -5188,6 +5233,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
p = compwords[i] = (char *) getdata(n);
untokenize(p);
}
compcurrent = cur + 1;
compwords[i] = NULL;
}
autoq = oaq;
@ -5242,6 +5288,7 @@ makecomplistcall(Compctl cc)
inbackt = oib;
autoq = oaq;
compnmatches = mnum;
compnnmatches = nmnum;
} LASTALLOC;
} SWITCHBACKHEAPS;
@ -5317,6 +5364,7 @@ makecomplistctl(int flags)
autoq = oaq;
offs = ooffs;
compnmatches = mnum;
compnnmatches = nmnum;
zsfree(cmdstr);
freearray(clwords);
cmdstr = os;
@ -5979,7 +6027,10 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
char save = line[cs];
line[cs] = 0;
lppre = dupstring((char *) (line + wb));
lppre = dupstring((char *) line + wb +
(qipre && *qipre ?
(strlen(qipre) -
(*qipre == '\'' || *qipre == '\"')) : 0));
line[cs] = save;
if (brbeg && *brbeg)
strcpy(lppre + qbrpl, lppre + qbrpl + strlen(brbeg));
@ -5998,11 +6049,17 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
lppl = 0;
}
if (cs != we) {
char save = line[we];
int end = we;
char save = line[end];
line[we] = 0;
if (qisuf && *qisuf) {
int ql = strlen(qisuf);
end -= ql - (qisuf[ql-1] == '\'' || qisuf[ql-1] == '"');
}
line[end] = 0;
lpsuf = dupstring((char *) (line + cs));
line[we] = save;
line[end] = save;
if (brend && *brend) {
char *p = lpsuf + qbrsl - (cs - wb);
@ -6640,7 +6697,8 @@ invalidatelist(void)
listmatches();
if (validlist)
freematches();
lastambig = menucmp = validlist = showinglist = fromcomp = 0;
lastambig = menucmp = menuacc = validlist = showinglist =
fromcomp = listshown = 0;
minfo.cur = NULL;
minfo.asked = 0;
compwidget = NULL;
@ -6917,6 +6975,8 @@ dupmatch(Cmatch m)
r->rems = ztrdup(m->rems);
r->remf = ztrdup(m->remf);
r->autoq = m->autoq;
r->qipl = m->qipl;
r->qisl = m->qisl;
return r;
}
@ -7346,7 +7406,9 @@ instmatch(Cmatch m, int *scs)
/* Ignored prefix. */
if (m->ipre) {
inststrlen(m->ipre, 1, (l = strlen(m->ipre)));
char *p = m->ipre + (menuacc ? m->qipl : 0);
inststrlen(p, 1, (l = strlen(p)));
r += l;
}
/* -P prefix. */
@ -7413,7 +7475,8 @@ static int
do_ambiguous(void)
{
int ret = 0;
menucmp = 0;
menucmp = menuacc = 0;
/* If we have to insert the first match, call do_single(). This is *
* how REC_EXACT takes effect. We effectively turn the ambiguous *
@ -7501,11 +7564,13 @@ do_ambiguous(void)
* if it is needed. */
if (isset(LISTBEEP))
ret = 1;
if (uselist && (usemenu != 2 || (!showinglist && !oldlist)) &&
if (uselist && (usemenu != 2 || (!listshown && !oldlist)) &&
((!showinglist && (!listshown || !oldlist)) ||
(usemenu == 3 && !oldlist)) &&
(smatches >= 2 || (compforcelist && *compforcelist)))
showinglist = -2;
return ret;
}
@ -7649,7 +7714,7 @@ do_single(Cmatch m)
}
}
if (!minfo.insc)
cs = minfo.pos + minfo.len;
cs = minfo.pos + minfo.len - m->qisl;
}
/* If completing in a brace expansion... */
if (brbeg) {
@ -7688,8 +7753,11 @@ do_single(Cmatch m)
if (minfo.we && m->ripre && isset(AUTOPARAMKEYS))
makeparamsuffix(((m->flags & CMF_PARBR) ? 1 : 0), minfo.insc - parq);
if ((menucmp && !minfo.we) || !movetoend)
if ((menucmp && !minfo.we) || !movetoend) {
cs = minfo.end;
if (cs + m->qisl == lastend)
cs += minfo.insc;
}
{
Cmatch *om = minfo.cur;
struct chdata dat;
@ -7732,6 +7800,7 @@ do_ambig_menu(void)
if (usemenu != 3) {
menucmp = 1;
menuacc = 0;
minfo.cur = NULL;
} else {
if (oldlist) {
@ -7931,13 +8000,6 @@ ilistmatches(Hookdef dummy, Chdata dat)
int nlines = 0, ncols, nlist = 0, longest = 1, pnl = 0;
int of = isset(LISTTYPES), opl = 0;
/* Set the cursor below the prompt. */
trashzle();
showinglist = listshown = 0;
clearflag = (isset(USEZLE) && !termflags &&
complastprompt && *complastprompt);
for (g = amatches; g; g = g->next) {
char **pp = g->ylist;
int nl = 0, l;
@ -8013,6 +8075,16 @@ ilistmatches(Hookdef dummy, Chdata dat)
nlines += 1 + ((1 + niceztrlen(m->str)) / columns);
}
}
if (!nlines) {
showinglist = listshown = 0;
return 1;
}
/* Set the cursor below the prompt. */
trashzle();
showinglist = listshown = 0;
clearflag = (isset(USEZLE) && !termflags &&
complastprompt && *complastprompt);
/* Maybe we have to ask if the user wants to see the list. */
if ((!minfo.cur || !minfo.asked) &&
@ -8152,25 +8224,25 @@ ilistmatches(Hookdef dummy, Chdata dat)
pnl = 1;
g = g->next;
}
if (clearflag) {
/* Move the cursor up to the prompt, if always_last_prompt *
* is set and all that... */
if ((nlines += nlnct - 1) < lines) {
tcmultout(TCUP, TCMULTUP, nlines);
showinglist = -1;
listshown = 1;
} else
clearflag = 0, putc('\n', shout);
} else
putc('\n', shout);
listshown = (clearflag ? 1 : -1);
return 0;
}
/* This is used to print expansions. */
/**/
void
int
listlist(LinkList l)
{
struct cmgroup dg;
@ -8193,6 +8265,8 @@ listlist(LinkList l)
validlist = vl;
smatches = sm;
complastprompt = oclp;
return !dg.lcount;
}
/* Expand the history references. */

View file

@ -658,6 +658,9 @@ set_pwd_env(void)
}
}
/* set if we are resolving links to their true paths */
static int chasinglinks;
/* The main pwd changing function. The real work is done by other *
* functions. cd_get_dest() does the initial argument processing; *
* cd_do_chdir() actually changes directory, if possible; cd_new_pwd() *
@ -670,7 +673,6 @@ bin_cd(char *nam, char **argv, char *ops, int func)
{
LinkNode dir;
struct stat st1, st2;
int chaselinks;
if (isset(RESTRICTED)) {
zwarnnam(nam, "restricted", NULL, 0);
@ -694,7 +696,7 @@ bin_cd(char *nam, char **argv, char *ops, int func)
for (s = *argv; *++s; ops[STOUC(*s)] = 1);
}
brk:
chaselinks = ops['P'] || (isset(CHASELINKS) && !ops['L']);
chasinglinks = ops['P'] || (isset(CHASELINKS) && !ops['L']);
PERMALLOC {
pushnode(dirstack, ztrdup(pwd));
if (!(dir = cd_get_dest(nam, argv, ops, func))) {
@ -702,7 +704,7 @@ bin_cd(char *nam, char **argv, char *ops, int func)
LASTALLOC_RETURN 1;
}
} LASTALLOC;
cd_new_pwd(func, dir, chaselinks);
cd_new_pwd(func, dir);
if (stat(unmeta(pwd), &st1) < 0) {
zsfree(pwd);
@ -710,7 +712,7 @@ bin_cd(char *nam, char **argv, char *ops, int func)
} else if (stat(".", &st2) < 0)
chdir(unmeta(pwd));
else if (st1.st_ino != st2.st_ino || st1.st_dev != st2.st_dev) {
if (chaselinks) {
if (chasinglinks) {
zsfree(pwd);
pwd = metafy(zgetcwd(), -1, META_DUP);
} else {
@ -915,40 +917,49 @@ static char *
cd_try_chdir(char *pfix, char *dest, int hard)
{
char *buf;
int dlen, dochaselinks = 0;
/* handle directory prefix */
if (pfix && *pfix) {
if (*pfix == '/')
buf = tricat(pfix, "/", dest);
else {
int pwl = strlen(pwd);
int pfl = strlen(pfix);
dlen = strlen(pwd);
buf = zalloc(pwl + pfl + strlen(dest) + 3);
buf = zalloc(dlen + pfl + strlen(dest) + 3);
strcpy(buf, pwd);
buf[pwl] = '/';
strcpy(buf + pwl + 1, pfix);
buf[pwl + 1 + pfl] = '/';
strcpy(buf + pwl + pfl + 2, dest);
buf[dlen] = '/';
strcpy(buf + dlen + 1, pfix);
buf[dlen + 1 + pfl] = '/';
strcpy(buf + dlen + pfl + 2, dest);
}
} else if (*dest == '/')
buf = ztrdup(dest);
else {
int pwl = strlen(pwd);
dlen = strlen(pwd);
buf = zalloc(pwl + strlen(dest) + 2);
buf = zalloc(dlen + strlen(dest) + 2);
strcpy(buf, pwd);
buf[pwl] = '/';
strcpy(buf + pwl + 1, dest);
buf[dlen] = '/';
strcpy(buf + dlen + 1, dest);
}
/* Normalise path. See the definition of fixdir() for what this means. */
fixdir(buf);
/* Normalise path. See the definition of fixdir() for what this means.
* We do not do this if we are chasing links.
*/
if (!chasinglinks)
dochaselinks = fixdir(buf);
else
unmetafy(buf, &dlen);
if (lchdir(buf, NULL, hard)) {
zsfree(buf);
free(buf);
return NULL;
}
/* the chdir succeeded, so decide if we should force links to be chased */
if (dochaselinks)
chasinglinks = 1;
return metafy(buf, -1, META_NOALLOC);
}
@ -956,7 +967,7 @@ cd_try_chdir(char *pfix, char *dest, int hard)
/**/
static void
cd_new_pwd(int func, LinkNode dir, int chaselinks)
cd_new_pwd(int func, LinkNode dir)
{
List l;
char *new_pwd, *s;
@ -972,7 +983,7 @@ cd_new_pwd(int func, LinkNode dir, int chaselinks)
} else if (func == BIN_CD && unset(AUTOPUSHD))
zsfree(getlinknode(dirstack));
if (chaselinks) {
if (chasinglinks) {
s = new_pwd;
new_pwd = findpwd(s);
zsfree(s);
@ -1039,17 +1050,20 @@ printdirstack(void)
}
/* Normalise a path. Segments consisting of ., and foo/.. *
* combinations, are removed and the path is unmetafied. */
* combinations, are removed and the path is unmetafied.
* Returns 1 if we found a ../ path which should force links to
* be chased, 0 otherwise.
*/
/**/
static void
int
fixdir(char *src)
{
char *dest = src;
char *d0 = dest;
#ifdef __CYGWIN__
char *dest = src, *d0 = dest;
#ifdef __CYGWIN
char *s0 = src;
#endif
int ret = 0;
/*** if have RFS superroot directory ***/
#ifdef HAVE_SUPERROOT
@ -1081,19 +1095,40 @@ fixdir(char *src)
while (dest > d0 + 1 && dest[-1] == '/')
dest--;
*dest = '\0';
return;
return ret;
}
if (src[0] == '.' && src[1] == '.' &&
(src[2] == '\0' || src[2] == '/')) {
if (dest > d0 + 1) {
/* remove a foo/.. combination */
for (dest--; dest > d0 + 1 && dest[-1] != '/'; dest--);
if (dest[-1] != '/')
dest--;
(src[2] == '\0' || src[2] == '/')) {
if (isset(CHASEDOTS)) {
ret = 1;
/* and treat as normal path segment */
} else {
if (dest > d0 + 1) {
/*
* remove a foo/.. combination:
* first check foo exists, else return.
*/
struct stat st;
*dest = '\0';
if (stat(d0, &st) < 0 || !S_ISDIR(st.st_mode)) {
char *ptrd, *ptrs;
if (dest == src)
*dest = '.';
for (ptrs = src, ptrd = dest; *ptrs; ptrs++, ptrd++)
*ptrd = (*ptrs == Meta) ? (*++ptrs ^ 32) : *ptrs;
*ptrd = '\0';
return 1;
}
for (dest--; dest > d0 + 1 && dest[-1] != '/'; dest--);
if (dest[-1] != '/')
dest--;
}
src++;
while (*++src == '/');
continue;
}
src++;
while (*++src == '/');
} else if (src[0] == '.' && (src[1] == '/' || src[1] == '\0')) {
}
if (src[0] == '.' && (src[1] == '/' || src[1] == '\0')) {
/* skip a . section */
while (*++src == '/');
} else {
@ -3249,12 +3284,11 @@ bin_read(char *name, char **args, char *ops, int func)
nchars = 1;
args++;
}
firstarg = *args;
if (*args && **args == '?')
args++;
/* default result parameter */
/* This `*args++ : *args' looks a bit weird, but it works around a bug
* in gcc-2.8.1 under DU 4.0. */
firstarg = (*args && **args == '?' ? *args++ : *args);
reply = *args ? *args++ : ops['A'] ? "reply" : "REPLY";
if (ops['A'] && *args) {
zwarnnam(name, "only one array argument allowed", NULL, 0);
return 1;

View file

@ -3144,9 +3144,24 @@ static int
cancd2(char *s)
{
struct stat buf;
char *us = unmeta(s);
char *us, *us2 = NULL;
/*
* If CHASEDOTS and CHASELINKS are not set, we want to rationalize the
* path by removing foo/.. combinations in the logical rather than
* the physical path. If either is set, we test the physical path.
*/
if (!isset(CHASEDOTS) && !isset(CHASELINKS)) {
if (*s != '/')
us = tricat(pwd[1] ? pwd : "", "/", s);
else
us = ztrdup(s);
fixdir(us2 = us);
} else
us = unmeta(s);
return !(access(us, X_OK) || stat(us, &buf) || !S_ISDIR(buf.st_mode));
if (us2)
free(us2);
}
/**/

View file

@ -2724,6 +2724,9 @@ charmatch(Comp c, char *x, char *y)
* Here we bypass tulower() and tuupper() for speed.
*/
int xi = (STOUC(UNMETA(x)) & 0xff), yi = (STOUC(UNMETA(y)) & 0xff);
/* A NULL is a real null, since a \000 would be metafied. */
if (!*x || !*y)
return 0;
return xi == yi ||
(((c->stat & C_IGNCASE) ?
((isupper(xi) ? tolower(xi) : xi) ==
@ -2926,7 +2929,10 @@ rangematch(char **patptr, int ch, int rchar)
* and optional ^ have already been skipped. */
char *pat = *patptr;
#ifdef HAVE_STRCOLL
/* We don't use strcoll() for ranges, since it can have side
* effects. It's less necessary now we have [:posix:] ranges.
*/
#if 0
char l_buf[2], r_buf[2], ch_buf[2];
ch_buf[0] = ch;
@ -2944,7 +2950,7 @@ rangematch(char **patptr, int ch, int rchar)
break;
} else if (*pat == '-' && pat[-1] != rchar &&
pat[1] != Outbrack) {
#ifdef HAVE_STRCOLL
#if 0
l_buf[0] = PPAT(-1);
r_buf[0] = PAT(1);
if (strcoll(l_buf, ch_buf) <= 0 &&

View file

@ -241,6 +241,7 @@ lexsave(void)
cmdsp = 0;
inredir = 0;
hdocs = NULL;
histactive = 0;
ls->next = lstack;
lstack = ls;

View file

@ -91,6 +91,7 @@ static struct optname optns[] = {
{NULL, "braceccl", 0, BRACECCL},
{NULL, "bsdecho", OPT_EMULATE|OPT_SH, BSDECHO},
{NULL, "cdablevars", 0, CDABLEVARS},
{NULL, "chasedots", 0, CHASEDOTS},
{NULL, "chaselinks", 0, CHASELINKS},
{NULL, "clobber", OPT_ALL, CLOBBER},
{NULL, "completealiases", 0, COMPLETEALIASES},

View file

@ -72,7 +72,13 @@ struct list dummy_list;
#define YYERROR { tok = LEXERR; return NULL; }
#define YYERRORV { tok = LEXERR; return; }
#define COND_ERROR(X,Y) do{herrflush();zerr(X,Y,0);YYERROR}while(0)
#define COND_ERROR(X,Y) do { \
zwarn(X,Y,0); \
herrflush(); \
if (noerrs != 2) \
errflag = 1; \
YYERROR \
} while(0)
#define make_list() allocnode(N_LIST)
#define make_sublist() allocnode(N_SUBLIST)
@ -140,11 +146,13 @@ par_event(void)
}
if (!l) {
if (errflag) {
yyerror();
yyerror(0);
return NULL;
}
yyerror(1);
herrflush();
yyerror();
if (noerrs != 2)
errflag = 1;
return NULL;
} else {
l->right = par_event();
@ -163,7 +171,7 @@ parse_list(void)
yylex();
ret = par_list();
if (tok == LEXERR) {
yyerror();
yyerror(0);
return NULL;
}
return ret;
@ -1480,7 +1488,7 @@ par_cond_multi(char *a, LinkList l)
/**/
static void
yyerror(void)
yyerror(int noerr)
{
int t0;
@ -1488,9 +1496,11 @@ yyerror(void)
if (!yytext || !yytext[t0] || yytext[t0] == '\n')
break;
if (t0 == 20)
zerr("parse error near `%l...'", yytext, 20);
zwarn("parse error near `%l...'", yytext, 20);
else if (t0)
zerr("parse error near `%l'", yytext, t0);
zwarn("parse error near `%l'", yytext, t0);
else
zerr("parse error", NULL, 0);
zwarn("parse error", NULL, 0);
if (!noerr && noerrs != 2)
errflag = 1;
}

View file

@ -30,23 +30,12 @@
#include "zsh.mdh"
#include "utils.pro"
/* Print an error */
/**/
void
zwarnnam(const char *cmd, const char *fmt, const char *str, int num)
{
int waserr;
waserr = errflag;
zerrnam(cmd, fmt, str, num);
errflag = waserr;
}
/* name of script being sourced */
/**/
char *scriptname;
/* Print an error */
/**/
void
@ -57,7 +46,27 @@ zerr(const char *fmt, const char *str, int num)
errflag = 1;
return;
}
zwarn(fmt, str, num);
errflag = 1;
}
/**/
void
zerrnam(const char *cmd, const char *fmt, const char *str, int num)
{
if (errflag || noerrs)
return;
zwarnnam(cmd, fmt, str, num);
errflag = 1;
}
/**/
void
zwarn(const char *fmt, const char *str, int num)
{
if (errflag || noerrs)
return;
trashzle();
/*
* scriptname is set when sourcing scripts, so that we get the
@ -68,25 +77,29 @@ zerr(const char *fmt, const char *str, int num)
nicezputs((isset(SHINSTDIN) && !locallevel) ? "zsh" :
scriptname ? scriptname : argzero, stderr);
fputs(": ", stderr);
zerrnam(NULL, fmt, str, num);
zerrmsg(fmt, str, num);
}
/**/
void
zerrnam(const char *cmd, const char *fmt, const char *str, int num)
zwarnnam(const char *cmd, const char *fmt, const char *str, int num)
{
if (cmd) {
if (errflag || noerrs)
return;
errflag = 1;
trashzle();
if (unset(SHINSTDIN) || locallevel) {
nicezputs(scriptname ? scriptname : argzero, stderr);
fputs(": ", stderr);
}
nicezputs(cmd, stderr);
if (errflag || noerrs)
return;
trashzle();
if (unset(SHINSTDIN) || locallevel) {
nicezputs(scriptname ? scriptname : argzero, stderr);
fputs(": ", stderr);
}
nicezputs(cmd, stderr);
fputs(": ", stderr);
zerrmsg(fmt, str, num);
}
/**/
void
zerrmsg(const char *fmt, const char *str, int num)
{
while (*fmt)
if (*fmt == '%') {
fmt++;
@ -302,7 +315,7 @@ slashsplit(char *s)
/**/
static int
xsymlinks(char *s, int flag)
xsymlinks(char *s)
{
char **pp, **opp;
char xbuf2[PATH_MAX*2], xbuf3[PATH_MAX*2];
@ -325,15 +338,9 @@ xsymlinks(char *s, int flag)
*p = '\0';
continue;
}
if (unset(CHASELINKS)) {
strcat(xbuf, "/");
strcat(xbuf, *pp);
zsfree(*pp);
continue;
}
sprintf(xbuf2, "%s/%s", xbuf, *pp);
t0 = readlink(unmeta(xbuf2), xbuf3, PATH_MAX);
if (t0 == -1 || !flag) {
if (t0 == -1) {
strcat(xbuf, "/");
strcat(xbuf, *pp);
zsfree(*pp);
@ -342,9 +349,9 @@ xsymlinks(char *s, int flag)
metafy(xbuf3, t0, META_NOALLOC);
if (*xbuf3 == '/') {
strcpy(xbuf, "");
xsymlinks(xbuf3 + 1, flag);
xsymlinks(xbuf3 + 1);
} else
xsymlinks(xbuf3, flag);
xsymlinks(xbuf3);
zsfree(*pp);
}
}
@ -352,19 +359,19 @@ xsymlinks(char *s, int flag)
return ret;
}
/* expand symlinks in s, and remove other weird things */
/*
* expand symlinks in s, and remove other weird things:
* note that this always expands symlinks.
*/
/**/
char *
xsymlink(char *s)
{
if (unset(CHASELINKS))
return ztrdup(s);
if (*s != '/')
return NULL;
*xbuf = '\0';
if (!xsymlinks(s + 1, 1))
return ztrdup(s);
xsymlinks(s + 1);
if (!*xbuf)
return ztrdup("/");
return ztrdup(xbuf);
@ -374,15 +381,10 @@ xsymlink(char *s)
void
print_if_link(char *s)
{
int chase;
if (*s == '/') {
chase = opts[CHASELINKS];
opts[CHASELINKS] = 1;
*xbuf = '\0';
if (xsymlinks(s + 1, 1))
if (xsymlinks(s + 1))
printf(" -> "), zputs(*xbuf ? xbuf : "/", stdout);
opts[CHASELINKS] = chase;
}
}
@ -573,7 +575,8 @@ getnameddir(char *name)
/* Retrieve an entry from the password table/database for this user. */
struct passwd *pw;
if ((pw = getpwnam(name))) {
char *dir = xsymlink(pw->pw_dir);
char *dir = isset(CHASELINKS) ? xsymlink(pw->pw_dir)
: ztrdup(pw->pw_dir);
adduserdir(name, dir, ND_USERNAME, 1);
str = dupstring(dir);
zsfree(dir);
@ -3202,7 +3205,7 @@ getkeystring(char *s, int *len, int fromwhere, int *misc)
int meta = 0, control = 0;
if (fromwhere == 6)
t = tmp;
t = buf = tmp;
else if (fromwhere != 4)
t = buf = zhalloc(strlen(s) + 1);
else {

View file

@ -1171,6 +1171,7 @@ enum {
BRACECCL,
BSDECHO,
CDABLEVARS,
CHASEDOTS,
CHASELINKS,
CLOBBER,
COMPLETEALIASES,

View file

@ -100,7 +100,7 @@ fi])
dnl Do you want large file support, if available?
undefine([lfs])dnl
AC_ARG_ENABLE(lfs,
[ --enable-lfs turn on support for large files],
[ --disable-lfs turn off support for large files],
[lfs="$enableval"], [lfs=yes])
dnl Pathnames for global zsh scripts
@ -183,7 +183,7 @@ AC_SUBST(zlogout)dnl
dnl Do you want dynamically loaded binary modules.
undefine([dynamic])dnl
AC_ARG_ENABLE(dynamic,
[ --enable-dynamic allow dynamically loaded binary modules],
[ --disable-dynamic turn off dynamically loaded binary modules],
[dynamic="$enableval"], [dynamic=yes])
dnl Do you want to compile as K&R C.
@ -599,7 +599,7 @@ main() { return sizeof(ino_t) < 8; }
if test $lfs != no -o $zsh_cv_off_t_is_64_bit = yes \
-o $zsh_cv_ino_t_is_64_bit = yes; then
AC_CACHE_CHECK(if compiler has a 64 bit type, zsh_cv_64_bit_type,
[if test $lfs != xyes -a $lfs != xno; then
[if test $lfs != yes -a $lfs != no; then
zsh_64_BIT_TYPE(${lfs}, zsh_cv_64_bit_type, force)
else
zsh_64_BIT_TYPE(long long, zsh_cv_64_bit_type)