mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-08-13 15:41:01 +02:00
zsh-3.1.5-pws-22
This commit is contained in:
parent
805381040d
commit
a2159285e8
77 changed files with 1651 additions and 1236 deletions
ChangeLog
Completion
Config
Doc
Makefile.in
Zsh
arith.yobuiltins.yocompctl.yocompsys.yocompwid.yoexpn.yofiles.yofunc.yogrammar.yoguide.yojobs.yometafaq.yomod_compctl.yomod_mapfile.yomod_zftp.yoparams.yoredirect.yozftpsys.yozle.yo
zman.yozsh.yoztexi.yoEtc
Functions
INSTALLSrc
Builtins
Makefile.inModules
Zle
builtin.ccond.cexec.cglob.chashtable.chist.cinit.cjobs.clex.clinklist.cloop.cmath.cmem.cparams.cparse.csignals.csubst.ctext.cutils.czsh.exportzsh.hzsh.mddUtil
acconfig.haczsh.m4configure.in
179
ChangeLog
179
ChangeLog
|
@ -1,5 +1,182 @@
|
||||||
|
1999-06-15 Peter Stephenson <pws@ibmth.difi.unipi.it>
|
||||||
|
|
||||||
|
* Oliver: 6636: Completion/Builtins/_limits: wasn't working
|
||||||
|
|
||||||
|
* Bart: 6617 + minor changes: Src/utils.c: Be more careful keeping
|
||||||
|
$COLUMNS and $LINES correct, particularly if exported.
|
||||||
|
|
||||||
|
* Sven: zsh-users/2388: Src/jobs.c: while loops etc. in shells
|
||||||
|
running without MONITOR were hard to kill.
|
||||||
|
|
||||||
|
* Bart: 6628: Src/params.c: setting slices of unset array
|
||||||
|
caused a crash.
|
||||||
|
|
||||||
|
1999-06-14 Peter Stephenson <pws@ibmth.difi.unipi.it>
|
||||||
|
|
||||||
|
* pws: 6626: Src/mem.c: in zsh's malloc, try to make sure when
|
||||||
|
sbrk'ing that it's sufficiently well aligned.
|
||||||
|
|
||||||
|
* Oliver: 6624: Completion/Builtins/_kill,
|
||||||
|
Completion/Builtins/_wait: more widely functioning process
|
||||||
|
handling
|
||||||
|
|
||||||
|
* pws: 6623: Completion/Makefile.in, Config/defs.mk.in,
|
||||||
|
Functions/Makefile.in, INSTALL, Src/init.c, Src/zsh.mdd,
|
||||||
|
configure.in: --enable-function-subdirs allows installation
|
||||||
|
into subdirectories of the function directory and sets the
|
||||||
|
initial $fpath appropriately.
|
||||||
|
|
||||||
|
* Oliver: 6620: Completion/Builtins/_jobs: handle disown, too.
|
||||||
|
|
||||||
|
* pws: 6618: Doc/Zsh/func.yo, Doc/Zsh/grammar.yo, Src/lex.c:
|
||||||
|
with SH_GLOB set, function definition parentheses after the
|
||||||
|
first word on the line allow spaces inside.
|
||||||
|
|
||||||
|
* Sven: 6614: Src/Zle/zle_tricky.c, Completion/Brace/_brace_parameter:
|
||||||
|
completion after quotes in parameters
|
||||||
|
|
||||||
|
* pws: 6610: Src/glob.c: globbing flags shouldn't be active
|
||||||
|
without extendedglob.
|
||||||
|
|
||||||
|
* Bart: 6608: Doc/Zsh files compctl.yo, compsys.yo, compwid.yo,
|
||||||
|
expn.yo, files.yo, mod_mapfile.yo, mod_zftp.yo, params.yo,
|
||||||
|
zftpsys.yo, zle.yo: spelling corrections
|
||||||
|
|
||||||
|
1999-06-12 Peter Stephenson <pws@ibmth.difi.unipi.it>
|
||||||
|
|
||||||
|
* pws: 6601: Src/Makefile.in: don't remake Makemod just
|
||||||
|
to clean up files
|
||||||
|
|
||||||
|
* pws: 6600: Doc/Zsh/arith.yo, Doc/Zsh/compctl.yo,
|
||||||
|
Doc/Zsh/compsys.yo, Doc/Zsh/compwid.yo, Doc/Zsh/expn.yo,
|
||||||
|
Doc/Zsh/guide.yo, Doc/Zsh/jobs.yo, Doc/Zsh/metafaq.yo,
|
||||||
|
Doc/Zsh/mod_compctl.yo, Doc/Zsh/mod_zftp.yo, Doc/Zsh/params.yo,
|
||||||
|
Doc/Zsh/redirect.yo, Doc/Zsh/zftpsys.yo, Doc/Zsh/zle.yo,
|
||||||
|
Doc/zman.yo, Doc/ztexi.yo, Util/zsh-development-guide:
|
||||||
|
Formatting of unfilled text now handled by three distinct
|
||||||
|
macros example(), indent(), nofill(); compctl description node
|
||||||
|
is now called `Programmable Completion Using compctl' to
|
||||||
|
distinguish it from widget completion; don't put chapters on
|
||||||
|
separate pages because many are too short.
|
||||||
|
|
||||||
|
* Wayne: 6599: Src/Zle/zle_tricky.c: unitialised variable warnings
|
||||||
|
from gcc
|
||||||
|
|
||||||
|
1999-06-11 Peter Stephenson <pws@ibmth.difi.unipi.it>
|
||||||
|
|
||||||
|
* pws: 6598: Doc/Zsh/zftpsys.yo, Functions/Zftp/zfinit,
|
||||||
|
Functions/Zftp/zfgoto, Functions/Zftp/zfmark,
|
||||||
|
Functions/Zftp/zftp_chpwd, Completion/Builtins/_zftp:
|
||||||
|
add zfmark and zfgoto implementing bookmarks (including use
|
||||||
|
ncftp bookmarks) for zftp function suite; autoload functions
|
||||||
|
from zfinit; patcomps -> _patcomps.
|
||||||
|
|
||||||
|
* pws: 6596: Doc/Zsh/arith.yo: update on size of integers and
|
||||||
|
increase in clarity of presentation
|
||||||
|
|
||||||
|
* Sven: 6589: Completion/Core/_path_files: use :h and :t instead
|
||||||
|
of pattern matching
|
||||||
|
|
||||||
|
* Sven: 6587, 6588: Src/Zle/zle_misc.c, Doc/Zsh/options.yo: < and
|
||||||
|
> shouldn't remove a suffix, but | does
|
||||||
|
|
||||||
|
* Sven: 6586: Src/exec.c, Src/lex.c, Src/loop.c: don't modify
|
||||||
|
struct cmd to insert cmd args and flags, always pass those
|
||||||
|
separately
|
||||||
|
|
||||||
|
1999-06-10 Peter Stephenson <pws@ibmth.difi.unipi.it>
|
||||||
|
|
||||||
|
* Andrej: 6581: Doc/Makefile: dependencies for manuals
|
||||||
|
|
||||||
|
* Sven: 6579: Src/exec.c: old hack of storing shell function
|
||||||
|
args in struct cmd doesn't work any more
|
||||||
|
|
||||||
|
* Sven: 6577: Src/exec.c, Src/text.c, Src/utils.c: expunge
|
||||||
|
simplifyright(), which appears no longer to have an effect
|
||||||
|
|
||||||
|
* pws: 6575: Doc/Zsh/mod_mapfile.yo: avoid mapping long files
|
||||||
|
|
||||||
|
* pws: 6571: Src/Builtins/rlimits.c: use appropriate printf()
|
||||||
|
routine in printulimit() instead of just casting to long
|
||||||
|
|
||||||
|
* pws: 6570: configure.in, INSTALL: some systems have
|
||||||
|
sizeof(off_t) or sizeof(ino_t) == 8 and sizeof(long) == 4 even
|
||||||
|
without explicit enabling, so check and if so use the
|
||||||
|
--enable-lfs code.
|
||||||
|
|
||||||
|
* pws/Sven: 6567, 6568: Completion/Base/_vars: complete assoc
|
||||||
|
array keys
|
||||||
|
|
||||||
|
* pws: 6566: Src/params.c: junk testhash assoc array
|
||||||
|
|
||||||
|
* pws: 6563: sporadic: minor changes affecting casts, sizes
|
||||||
|
of integers, unused variables; add index for subscripts in
|
||||||
|
manual
|
||||||
|
|
||||||
|
* Bart: email: Src/zsh.h: alternative definition for zulong
|
||||||
|
|
||||||
|
* Bart: 6558: Src/builtins.c: printing functions with the
|
||||||
|
UNALIASED flag
|
||||||
|
|
||||||
|
* Sven: 6557: Doc/zsh/compsys.yo: a few typos
|
||||||
|
|
||||||
|
1999-06-09 Peter Stephenson <pws@ibmth.difi.unipi.it>
|
||||||
|
|
||||||
|
* Andrej: 6556: aczsh.m4: don't disable setting variables
|
||||||
|
for --enable-lfs just because some other variables were set
|
||||||
|
|
||||||
|
* Sven: 6554: Src/Zle/zle_tricky.c: display bugs with compadd -X:
|
||||||
|
newline missing and display unnecessarily altered
|
||||||
|
|
||||||
|
* pws: 6552: configure.in, aczsh.m4, acconfig.h, Src/zsh.h:
|
||||||
|
define separate unsigned 64-bit integer; try __int64_t and
|
||||||
|
__uint64_t.
|
||||||
|
|
||||||
|
* Sven: 6548: Src/Zle/zle_tricky.c: fix `compctl -l'
|
||||||
|
|
||||||
|
* Andrej: 6544: configure displays info on function installation
|
||||||
|
|
||||||
|
* Sven: 6542: Src/builtin.c, Src/exec.c, Src/hist.c, Src/init.c,
|
||||||
|
Src/lex.c: when not using interactive history, don't allocate
|
||||||
|
history at all
|
||||||
|
|
||||||
|
* Andrej: 6541: configure.in: add missing `test'
|
||||||
|
|
||||||
|
* Sven: 6535: Completion/core/_normal: an eval was unnecessary
|
||||||
|
|
||||||
|
* Bart: 6534: Completion/Core/compdump, Completion/Core/compinit,
|
||||||
|
Doc/Zsh/builtins.yo, Src/builtin.c, Src/exec.c, Src/zsh.h:
|
||||||
|
autoload -U defines functions which don't use expand aliases
|
||||||
|
during loading; used in new completion code to protect
|
||||||
|
functions.
|
||||||
|
|
||||||
|
* Sven: 6527: Src/builtin.c, Src/cond.c, Src/exec.c, Src/glob.c,
|
||||||
|
Src/hashtable.c, Src/init.c, Src/jobs.c, Src/lex.c,
|
||||||
|
Src/linklist.c, Src/loop.c, Src/math.c, Src/mem.c, Src/params.c,
|
||||||
|
Src/parse.c, Src/signals.c, Src/text.c, Src/utils.c, Src/zsh.h:
|
||||||
|
various sets of patches:
|
||||||
|
- make zhalloc() use a pointer to the first free heap
|
||||||
|
- make zsh-mem allocators keep some memory back when freeing
|
||||||
|
- reduce the amount of allocation work done in the exec.c
|
||||||
|
execution hierarchy
|
||||||
|
- don't duplicate execution trees any more than necessary, e.g.
|
||||||
|
execute functions from stored tree
|
||||||
|
|
||||||
|
* pws: Etc/MACHINES: Danek Duvall reports --enable-dynamic OK
|
||||||
|
on Solaris 2.7, despite previous reports; Sven says on Digital
|
||||||
|
UNIX 4.0, you need special DLLD and LDFLAGS.
|
||||||
|
|
||||||
1999-06-08 Peter Stephenson <pws@ibmth.difi.unipi.it>
|
1999-06-08 Peter Stephenson <pws@ibmth.difi.unipi.it>
|
||||||
|
|
||||||
|
* pws: 6525: Src/lex.c (gettokstr): allow parentheses after
|
||||||
|
first character in command word
|
||||||
|
|
||||||
|
* Tanaka Akira: 6522: configure.in: help string for --enable-fndir
|
||||||
|
had wrong default directory
|
||||||
|
|
||||||
|
* pws: 6520: configure.in: --enable-fndir might be yes,
|
||||||
|
so turn it into ${datadir}/zsh/functions
|
||||||
|
|
||||||
* 3.1.5-pws-21 made available
|
* 3.1.5-pws-21 made available
|
||||||
|
|
||||||
* Sven: 6515: Src/Zle/zle_tricky.c: fix memory problems with 6492
|
* Sven: 6515: Src/Zle/zle_tricky.c: fix memory problems with 6492
|
||||||
|
@ -38,7 +215,7 @@
|
||||||
`compctl -h' takes a command line from inside a quoted string;
|
`compctl -h' takes a command line from inside a quoted string;
|
||||||
the compctl tests q[s], q[d], q[b] are true if we are in single,
|
the compctl tests q[s], q[d], q[b] are true if we are in single,
|
||||||
double, back quotes; compset -q tests quotes and splits the word,
|
double, back quotes; compset -q tests quotes and splits the word,
|
||||||
affecting $PREFIX, $SUFFX and setting $IQPREFIX, $IQSUFFIX for
|
affecting $PREFIX, $SUFFIX and setting $IQPREFIX, $IQSUFFIX for
|
||||||
the bits which will now be ignored.
|
the bits which will now be ignored.
|
||||||
|
|
||||||
* pws: 6490: Completion/Core/compinit: nounset workaround
|
* pws: 6490: Completion/Core/compinit: nounset workaround
|
||||||
|
|
|
@ -16,4 +16,6 @@ ls="$RBUFFER[${#SUFFIX}+1,-1]"
|
||||||
n=${(M)#ls##\"#}
|
n=${(M)#ls##\"#}
|
||||||
q=${(M)lp%%\"#}
|
q=${(M)lp%%\"#}
|
||||||
|
|
||||||
|
[[ n -gt 0 ]] && suf=''
|
||||||
|
|
||||||
_parameters -s "${q[1,-n-1]}" -S "$suf" -r '-:?#%+=[/'
|
_parameters -s "${q[1,-n-1]}" -S "$suf" -r '-:?#%+=[/'
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
#compdef getopts read unset vared
|
#compdef getopts read unset vared
|
||||||
|
|
||||||
compgen -v
|
# This will handle completion of keys of associative arrays, e.g. at
|
||||||
|
# `vared compconfig[<TAB>'. However, in this version the [ must be
|
||||||
|
# added by hand.
|
||||||
|
|
||||||
|
if [[ $PREFIX = *\[* ]]; then
|
||||||
|
local var=${PREFIX%%\[*}
|
||||||
|
local elt="${PREFIX#*\]}${SUFFIX%\]}"
|
||||||
|
local addclose
|
||||||
|
compset -p $(( ${#var} + 1 ))
|
||||||
|
if ! compset -S \]; then
|
||||||
|
addclose=(-S ']')
|
||||||
|
fi
|
||||||
|
if [[ ${(tP)var} = assoc* ]]; then
|
||||||
|
compadd $addclose - ${(kP)var}
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
compgen -v
|
||||||
|
fi
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#compdef fg jobs
|
#compdef disown fg jobs
|
||||||
|
|
||||||
compgen -j -P '%'
|
compgen -j -P '%'
|
||||||
|
|
|
@ -9,7 +9,8 @@ else
|
||||||
|
|
||||||
compgen -P '%' -j && ret=0
|
compgen -P '%' -j && ret=0
|
||||||
list=("$(ps 2>/dev/null)")
|
list=("$(ps 2>/dev/null)")
|
||||||
compgen -y '$list' -s '`ps 2>/dev/null | tail +2 | cut -c1-5`' && ret=0
|
compgen -y '$list' -s '${${${(f)"$(ps 2>/dev/null)"}[2,-1]## #}%% *}' &&
|
||||||
|
ret=0
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#compdef limit unlimit
|
#compdef limit unlimit
|
||||||
|
|
||||||
compgen -k "(${(j: :)${(f)$(limit)}%% *})"
|
compgen -s '${${(f)"$(limit)"}%% *}'
|
||||||
|
|
|
@ -4,6 +4,6 @@ local list ret=1
|
||||||
|
|
||||||
compgen -P '%' -j && ret=0
|
compgen -P '%' -j && ret=0
|
||||||
list=("$(ps 2>/dev/null)")
|
list=("$(ps 2>/dev/null)")
|
||||||
compgen -y '$list' -s '`ps 2>/dev/null | tail +2 | cut -c1-5`' && ret=0
|
compgen -y '$list' -s '${${${(f)"$(ps 2>/dev/null)"}[2,-1]## #}%% *}' && ret=0
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
|
@ -43,6 +43,19 @@ case $subcom in
|
||||||
compgen -k hosts
|
compgen -k hosts
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
*(goto|mark))
|
||||||
|
# complete bookmarks. First decide if ncftp mode is go.
|
||||||
|
if [[ $words[2] = -*n* ]]; then
|
||||||
|
if [[ -f ~/.ncftp/bookmarks ]]; then
|
||||||
|
compadd - $(awk -F, 'NR > 2 { print $1 }' ~/.ncftp/bookmarks)
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ -f ${ZFTP_BMFILE:=${ZDOTDIR:-$HOME}/.zfbkmarks} ]]; then
|
||||||
|
compadd - $(awk '{print $1}' $ZFTP_BMFILE)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
# dunno... try ordinary completion after all.
|
# dunno... try ordinary completion after all.
|
||||||
unset _compskip
|
unset _compskip
|
||||||
|
|
|
@ -20,7 +20,7 @@ elif [[ "$command" == */* ]]; then
|
||||||
cmd2="${command:t}"
|
cmd2="${command:t}"
|
||||||
else
|
else
|
||||||
cmd1="$command"
|
cmd1="$command"
|
||||||
eval cmd2=$(whence -p $command)
|
cmd2=$(whence -p $command)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# See if there are any matching pattern completions.
|
# See if there are any matching pattern completions.
|
||||||
|
|
|
@ -231,7 +231,7 @@ for prepath in "$prepaths[@]"; do
|
||||||
# See which of them match what's on the line.
|
# See which of them match what's on the line.
|
||||||
|
|
||||||
tmp2=("$tmp1[@]")
|
tmp2=("$tmp1[@]")
|
||||||
compadd -D tmp1 "$ignore[@]" - "${(@)tmp1##*/}"
|
compadd -D tmp1 "$ignore[@]" - "${(@)tmp1:t}"
|
||||||
|
|
||||||
# If no file matches, save the expanded path and continue with
|
# If no file matches, save the expanded path and continue with
|
||||||
# the outer loop.
|
# the outer loop.
|
||||||
|
@ -240,7 +240,7 @@ for prepath in "$prepaths[@]"; do
|
||||||
if [[ "$tmp2[1]" = */* ]]; then
|
if [[ "$tmp2[1]" = */* ]]; then
|
||||||
tmp2=( "${(@)tmp2#${prepath}${realpath}}" )
|
tmp2=( "${(@)tmp2#${prepath}${realpath}}" )
|
||||||
if [[ "$tmp2[1]" = */* ]]; then
|
if [[ "$tmp2[1]" = */* ]]; then
|
||||||
exppaths=( "$exppaths[@]" ${^tmp2%/*}/${tpre}${tsuf} )
|
exppaths=( "$exppaths[@]" ${^tmp2:h}/${tpre}${tsuf} )
|
||||||
else
|
else
|
||||||
exppaths=( "$exppaths[@]" ${tpre}${tsuf} )
|
exppaths=( "$exppaths[@]" ${tpre}${tsuf} )
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -74,7 +74,7 @@ done))
|
||||||
# print them out: about five to a line looks neat
|
# print them out: about five to a line looks neat
|
||||||
|
|
||||||
while (( $#_d_als )); do
|
while (( $#_d_als )); do
|
||||||
print -n autoload
|
print -n autoload -U
|
||||||
for (( _i = 0; _i < 5; _i++ )); do
|
for (( _i = 0; _i < 5; _i++ )); do
|
||||||
if (( $#_d_als )); then
|
if (( $#_d_als )); then
|
||||||
print -n " $_d_als[1]"
|
print -n " $_d_als[1]"
|
||||||
|
|
|
@ -194,7 +194,7 @@ compdef() {
|
||||||
# and probably do autoloading.
|
# and probably do autoloading.
|
||||||
|
|
||||||
func="$1"
|
func="$1"
|
||||||
[[ -n "$autol" ]] && autoload "$func"
|
[[ -n "$autol" ]] && autoload -U "$func"
|
||||||
shift
|
shift
|
||||||
|
|
||||||
case "$type" in
|
case "$type" in
|
||||||
|
@ -363,7 +363,7 @@ if [[ -z "$_i_done" ]]; then
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
(\#autoload)
|
(\#autoload)
|
||||||
autoload ${_i_file:t}
|
autoload -U ${_i_file:t}
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
|
@ -55,7 +55,14 @@ install.fns:
|
||||||
$(sdir_top)/mkinstalldirs $(fndir) || exit 1; \
|
$(sdir_top)/mkinstalldirs $(fndir) || exit 1; \
|
||||||
for file in $(FUNCTIONS_INSTALL); do \
|
for file in $(FUNCTIONS_INSTALL); do \
|
||||||
if test -f $$file; then \
|
if test -f $$file; then \
|
||||||
$(INSTALL_DATA) $$file $(fndir) || exit 1; \
|
if test x$(FUNCTIONS_SUBDIRS) != x -a \
|
||||||
|
x$(FUNCTIONS_SUBDIRS) != xno; then \
|
||||||
|
subdir="`echo $$file | sed -e 's%/.*%%'`"; \
|
||||||
|
$(sdir_top)/mkinstalldirs $(fndir)/$$subdir || exit 1; \
|
||||||
|
$(INSTALL_DATA) $$file $(fndir)/$$subdir || exit 1; \
|
||||||
|
else \
|
||||||
|
$(INSTALL_DATA) $$file $(fndir) || exit 1; \
|
||||||
|
fi; \
|
||||||
fi; \
|
fi; \
|
||||||
done; \
|
done; \
|
||||||
fi; \
|
fi; \
|
||||||
|
@ -65,7 +72,12 @@ uninstall.fns:
|
||||||
if test x$(fndir) != x && test x$(fndir) != xno; then \
|
if test x$(fndir) != x && test x$(fndir) != xno; then \
|
||||||
for file in $(FUNCTIONS_INSTALL); do \
|
for file in $(FUNCTIONS_INSTALL); do \
|
||||||
if test -f $$file; then \
|
if test -f $$file; then \
|
||||||
rm -f "$(fndir)/`echo $$file | sed -e 's%^.*/%%'`"; \
|
if test x$(FUNCTIONS_SUBDIRS) != x -a \
|
||||||
|
x$(FUNCTIONS_SUBDIRS) != xno; then \
|
||||||
|
rm -f $(fndir)/$$file; \
|
||||||
|
else \
|
||||||
|
rm -f "$(fndir)/`echo $$file | sed -e 's%^.*/%%'`"; \
|
||||||
|
fi; \
|
||||||
fi; \
|
fi; \
|
||||||
done; \
|
done; \
|
||||||
fi; \
|
fi; \
|
||||||
|
|
|
@ -68,6 +68,7 @@ INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
|
||||||
# variables used in determining what to install
|
# variables used in determining what to install
|
||||||
FUNCTIONS_INSTALL = @FUNCTIONS_INSTALL@
|
FUNCTIONS_INSTALL = @FUNCTIONS_INSTALL@
|
||||||
|
FUNCTIONS_SUBDIRS = @FUNCTIONS_SUBDIRS@
|
||||||
|
|
||||||
# flags passed to recursive makes in subdirectories
|
# flags passed to recursive makes in subdirectories
|
||||||
MAKEDEFS = \
|
MAKEDEFS = \
|
||||||
|
|
|
@ -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-21
|
VERSION=3.1.5-pws-22
|
||||||
VERSION_DATE='June 6, 1999'
|
VERSION_DATE='June 13, 1999'
|
||||||
|
|
|
@ -57,7 +57,7 @@ Zsh/filelist.yo Zsh/files.yo Zsh/func.yo Zsh/grammar.yo Zsh/guide.yo \
|
||||||
Zsh/index.yo Zsh/intro.yo Zsh/invoke.yo Zsh/jobs.yo Zsh/metafaq.yo \
|
Zsh/index.yo Zsh/intro.yo Zsh/invoke.yo Zsh/jobs.yo Zsh/metafaq.yo \
|
||||||
Zsh/modules.yo Zsh/mod_cap.yo Zsh/compwid.yo Zsh/compsys.yo \
|
Zsh/modules.yo Zsh/mod_cap.yo Zsh/compwid.yo Zsh/compsys.yo \
|
||||||
Zsh/mod_clone.yo Zsh/mod_comp1.yo Zsh/mod_compctl.yo Zsh/mod_deltochar.yo \
|
Zsh/mod_clone.yo Zsh/mod_comp1.yo Zsh/mod_compctl.yo Zsh/mod_deltochar.yo \
|
||||||
Zsh/mod_example.yo Zsh/mod_files.yo Zsh/mod_stat.yo \
|
Zsh/mod_example.yo Zsh/mod_files.yo Zsh/mod_mapfile.yo Zsh/mod_stat.yo \
|
||||||
Zsh/mod_zle.yo Zsh/options.yo \
|
Zsh/mod_zle.yo Zsh/options.yo \
|
||||||
Zsh/params.yo Zsh/prompt.yo Zsh/redirect.yo Zsh/restricted.yo \
|
Zsh/params.yo Zsh/prompt.yo Zsh/redirect.yo Zsh/restricted.yo \
|
||||||
Zsh/seealso.yo Zsh/zftpsys.yo Zsh/zle.yo
|
Zsh/seealso.yo Zsh/zftpsys.yo Zsh/zle.yo
|
||||||
|
@ -132,8 +132,8 @@ zshmisc.1: Zsh/grammar.yo Zsh/redirect.yo Zsh/exec.yo Zsh/func.yo \
|
||||||
|
|
||||||
zshmodules.1: Zsh/modules.yo Zsh/mod_cap.yo Zsh/mod_clone.yo \
|
zshmodules.1: Zsh/modules.yo Zsh/mod_cap.yo Zsh/mod_clone.yo \
|
||||||
Zsh/mod_comp1.yo Zsh/mod_compctl.yo Zsh/mod_deltochar.yo \
|
Zsh/mod_comp1.yo Zsh/mod_compctl.yo Zsh/mod_deltochar.yo \
|
||||||
Zsh/mod_example.yo Zsh/mod_files.yo Zsh/mod_sched.yo \
|
Zsh/mod_example.yo Zsh/mod_files.yo Zsh/mod_mapfile.yo \
|
||||||
Zsh/mod_stat.yo Zsh/mod_zftp.yo Zsh/mod_zle.yo
|
Zsh/mod_sched.yo Zsh/mod_stat.yo Zsh/mod_zftp.yo Zsh/mod_zle.yo
|
||||||
|
|
||||||
zshoptions.1: Zsh/options.yo
|
zshoptions.1: Zsh/options.yo
|
||||||
|
|
||||||
|
|
|
@ -5,16 +5,42 @@ sect(Arithmetic Evaluation)
|
||||||
)\
|
)\
|
||||||
cindex(arithmetic evaluation)
|
cindex(arithmetic evaluation)
|
||||||
cindex(evaluation, arithmetic)
|
cindex(evaluation, arithmetic)
|
||||||
An ability to perform integer arithmetic is provided with the builtin tt(let).
|
|
||||||
findex(let, use of)
|
findex(let, use of)
|
||||||
Evaluations are performed using em(long) arithmetic.
|
The shell can perform integer arithmetic, either using the builtin tt(let),
|
||||||
|
or via a substitution of the form tt($((...))). Usually arithmetic is
|
||||||
|
performed with em(long) integers; however, on certain systems where a
|
||||||
|
em(long) has 4-byte precision, zsh may be compiled to use 8-byte precision
|
||||||
|
instead. This can be tested, for example, by giving the command
|
||||||
|
`tt(print - $(( 12345678901 )))'; if the number appears unchanged, the
|
||||||
|
precision is at least 8 bytes.
|
||||||
|
|
||||||
|
The tt(let) builtin command takes arithmetic expressions as arguments; each
|
||||||
|
is evaluated separately. Since many of the arithmetic operators, as well
|
||||||
|
as spaces, require quoting, an alternative form is provided: for any
|
||||||
|
command which begins with a `tt(LPAR()LPAR())', all the characters until a
|
||||||
|
matching `tt(RPAR()RPAR())' are treated as a quoted expression and
|
||||||
|
arithmetic expansion performed as for an argument of tt(let). More
|
||||||
|
precisely, `tt(LPAR()LPAR())var(...)tt(RPAR()RPAR())' is equivalent to
|
||||||
|
`tt(let ")var(...)tt(")'. For example, the following statement
|
||||||
|
|
||||||
|
example((( val = 2 + 1 )))
|
||||||
|
|
||||||
|
is equivalent to
|
||||||
|
|
||||||
|
example(let "val = 2 + 1")
|
||||||
|
|
||||||
|
both assigning the value 3 to the shell variable tt(foo) and returning a
|
||||||
|
zero status.
|
||||||
|
|
||||||
|
cindex(bases, in arithmetic)
|
||||||
|
Numbers can be in bases other than 10.
|
||||||
A leading `tt(0x)' or `tt(0X)' denotes hexadecimal.
|
A leading `tt(0x)' or `tt(0X)' denotes hexadecimal.
|
||||||
Otherwise, numbers are of the form `[var(base)tt(#)]var(n)',
|
Numbers may also be of the form `var(base)tt(#)var(n)',
|
||||||
where var(base) is a decimal number between two and thirty-six
|
where var(base) is a decimal number between two and thirty-six
|
||||||
representing the arithmetic base and var(n)
|
representing the arithmetic base and var(n)
|
||||||
is a number in that base (for example, `tt(16#ff)' is 255 in hexadecimal).
|
is a number in that base (for example, `tt(16#ff)' is 255 in hexadecimal).
|
||||||
If var(base) is omitted
|
The var(base)tt(#) may also be omitted, in which case
|
||||||
then base 10 is used. For backwards compatibility the form
|
base 10 is used. For backwards compatibility the form
|
||||||
`tt([)var(base)tt(])var(n)' is also accepted.
|
`tt([)var(base)tt(])var(n)' is also accepted.
|
||||||
|
|
||||||
cindex(arithmetic operators)
|
cindex(arithmetic operators)
|
||||||
|
@ -50,10 +76,17 @@ and XOR operators.
|
||||||
An expression of the form `tt(#\)var(x)' where var(x) is any character
|
An expression of the form `tt(#\)var(x)' where var(x) is any character
|
||||||
gives the ascii value of this character and an expression of the form
|
gives the ascii value of this character and an expression of the form
|
||||||
`tt(#)var(foo)' gives the ascii value of the first character of the value
|
`tt(#)var(foo)' gives the ascii value of the first character of the value
|
||||||
|
of the parameter var(foo). Note that this is different from the expression
|
||||||
|
`tt($#)var(foo)', a standard parameter substitution which gives the length
|
||||||
of the parameter var(foo).
|
of the parameter var(foo).
|
||||||
|
|
||||||
Named parameters and subscripted arrays can be referenced by name within an
|
Named parameters and subscripted arrays can be referenced by name within an
|
||||||
arithmetic expression without using the parameter expansion syntax.
|
arithmetic expression without using the parameter expansion syntax. For
|
||||||
|
example,
|
||||||
|
|
||||||
|
example((((val2 = val1 * 2))))
|
||||||
|
|
||||||
|
assigns twice the value of tt($val1) to the parameter named tt(val2).
|
||||||
|
|
||||||
An internal integer representation of a named parameter
|
An internal integer representation of a named parameter
|
||||||
can be specified with the tt(integer) builtin.
|
can be specified with the tt(integer) builtin.
|
||||||
|
@ -63,11 +96,3 @@ findex(integer, use of)
|
||||||
Arithmetic evaluation is performed on the value of each
|
Arithmetic evaluation is performed on the value of each
|
||||||
assignment to a named parameter declared integer
|
assignment to a named parameter declared integer
|
||||||
in this manner.
|
in this manner.
|
||||||
|
|
||||||
Since many of the arithmetic operators require
|
|
||||||
quoting, an alternative form of the tt(let) command is provided.
|
|
||||||
For any command which begins with a tt(LPAR()LPAR()),
|
|
||||||
all the characters until a matching tt(RPAR()RPAR())
|
|
||||||
are treated as a quoted expression.
|
|
||||||
More precisely, `tt(LPAR()LPAR()) ... tt(RPAR()RPAR())'
|
|
||||||
is equivalent to `tt(let ")...tt(")'.
|
|
||||||
|
|
|
@ -981,12 +981,13 @@ 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
|
||||||
can be made, and the only other valid flags are tt(-t)
|
can be made, and the only other valid flags are tt(-t), tt(-u) and
|
||||||
and tt(-u). The flag tt(-t) turns on execution tracing for this
|
tt(-U). The flag tt(-t) turns on execution tracing for this
|
||||||
function. The flag tt(-u) causes this function to be marked
|
function. The tt(-u) and tt(-U) flags cause the function to be
|
||||||
for autoloading. The tt(fpath) parameter will be searched to find the
|
marked for autoloading; tt(-U) also causes alias expansion to be
|
||||||
function definition when the function is first referenced; see
|
suppressed when the function is loaded. The tt(fpath) parameter
|
||||||
noderef(Functions).
|
will be searched to find the function definition when the function
|
||||||
|
is first referenced; see noderef(Functions).
|
||||||
)
|
)
|
||||||
item(tt(-i))(
|
item(tt(-i))(
|
||||||
Use an internal integer representation. If var(n) is nonzero it
|
Use an internal integer representation. If var(n) is nonzero it
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
texinode(Programmable Completion)(Completion Widgets)(Zsh Line Editor)(Top)
|
texinode(Programmable Completion Using compctl)(Completion Widgets)(Zsh Line Editor)(Top)
|
||||||
chapter(Programmable Completion)
|
chapter(Programmable Completion Using compctl)
|
||||||
cindex(completion, programmable)
|
cindex(completion, programmable)
|
||||||
cindex(completion, controlling)
|
cindex(completion, controlling)
|
||||||
findex(compctl)
|
findex(compctl)
|
||||||
|
@ -33,7 +33,7 @@ menu(Matching Control)
|
||||||
menu(Example)
|
menu(Example)
|
||||||
endmenu()
|
endmenu()
|
||||||
|
|
||||||
texinode(Command Flags)(Option Flags)()(Programmable Completion)
|
texinode(Command Flags)(Option Flags)()(Programmable Completion Using compctl)
|
||||||
sect(Command Flags)
|
sect(Command Flags)
|
||||||
Completion of the arguments of a command may be different for each
|
Completion of the arguments of a command may be different for each
|
||||||
command or may use the default. The behavior when completing the
|
command or may use the default. The behavior when completing the
|
||||||
|
@ -56,7 +56,7 @@ from immediate expansion; for example the command string tt('foo*')
|
||||||
arranges for completion of the words of any command beginning with
|
arranges for completion of the words of any command beginning with
|
||||||
tt(foo). When completion is attempted, all pattern completions are
|
tt(foo). When completion is attempted, all pattern completions are
|
||||||
tried in the reverse order of their definition until one matches. By
|
tried in the reverse order of their definition until one matches. By
|
||||||
default, completion then procedes as normal, i.e. the shell will try to
|
default, completion then proceeds as normal, i.e. the shell will try to
|
||||||
generate more matches for the specific command on the command line; this
|
generate more matches for the specific command on the command line; this
|
||||||
can be overridden by including tt(-tn) in the flags for the pattern
|
can be overridden by including tt(-tn) in the flags for the pattern
|
||||||
completion.
|
completion.
|
||||||
|
@ -88,9 +88,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
|
||||||
|
|
||||||
indent(
|
example(compctl -T -x 's[~] C[0,[^/]#]' -k friends -S/ -tn)
|
||||||
tt(compctl -T -x 's[~] C[0,[^/]#]' -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 tt(C[...]) argument is necessary so that this form of ~-completion is
|
The tt(C[...]) argument is necessary so that this form of ~-completion is
|
||||||
|
@ -118,7 +116,7 @@ options specified by the tt(-D) flag.
|
||||||
The form with tt(-M) as the first and only option defines global
|
The form with tt(-M) as the first and only option defines global
|
||||||
matching specifications, as described below in noderef(Matching Control).
|
matching specifications, as described below in noderef(Matching Control).
|
||||||
|
|
||||||
texinode(Option Flags)(Alternative Completion)(Command Flags)(Programmable Completion)
|
texinode(Option Flags)(Alternative Completion)(Command Flags)(Programmable Completion Using compctl)
|
||||||
sect(Option Flags)
|
sect(Option Flags)
|
||||||
startlist()
|
startlist()
|
||||||
list([ tt(-fcFBdeaRGovNAIOPZEnbjrzu/) ])
|
list([ tt(-fcFBdeaRGovNAIOPZEnbjrzu/) ])
|
||||||
|
@ -256,10 +254,8 @@ of space- or comma-separated values in parentheses, in which any
|
||||||
delimiter may be escaped with a backslash; in this case the argument
|
delimiter may be escaped with a backslash; in this case the argument
|
||||||
should be quoted. For example,
|
should be quoted. For example,
|
||||||
|
|
||||||
indent(
|
example(compctl -k "(cputime filesize datasize stacksize
|
||||||
nofill(tt(compctl -k "(cputime filesize datasize stacksize
|
coredumpsize resident descriptors)" limit)
|
||||||
coredumpsize resident descriptors)" limit))
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
item(tt(-g) var(globstring))(
|
item(tt(-g) var(globstring))(
|
||||||
The var(globstring) is expanded using filename globbing; it should be
|
The var(globstring) is expanded using filename globbing; it should be
|
||||||
|
@ -281,7 +277,7 @@ resulting files. Note that tt(-g) is faster for filenames.
|
||||||
)
|
)
|
||||||
item(tt(-K) var(function))(
|
item(tt(-K) var(function))(
|
||||||
Call the given function to get the completions. Unless the name
|
Call the given function to get the completions. Unless the name
|
||||||
starts with an underscode, the function is
|
starts with an underscore, the function is
|
||||||
passed two arguments: the prefix and the suffix of the word on which
|
passed two arguments: the prefix and the suffix of the word on which
|
||||||
completion is to be attempted, in other words those characters before
|
completion is to be attempted, in other words those characters before
|
||||||
the cursor position, and those from the cursor position onwards. The
|
the cursor position, and those from the cursor position onwards. The
|
||||||
|
@ -293,10 +289,8 @@ should not be made local to the function. From such a function the
|
||||||
command line can be accessed with the tt(-c) and tt(-l) flags to
|
command line can be accessed with the tt(-c) and tt(-l) flags to
|
||||||
the tt(read) builtin. For example,
|
the tt(read) builtin. For example,
|
||||||
|
|
||||||
indent(
|
example(function whoson { reply=(`users`); }
|
||||||
nofill(tt(function whoson { reply=(`users`); }
|
compctl -K whoson talk)
|
||||||
compctl -K whoson talk))
|
|
||||||
)
|
|
||||||
|
|
||||||
completes only logged-on users after `tt(talk)'. Note that `tt(whoson)' must
|
completes only logged-on users after `tt(talk)'. Note that `tt(whoson)' must
|
||||||
return an array, so `tt(reply=`users`)' would be incorrect.
|
return an array, so `tt(reply=`users`)' would be incorrect.
|
||||||
|
@ -315,9 +309,7 @@ zero or negative the whole history is searched and if var(pattern) is
|
||||||
the empty string all words are taken (as with `tt(*)'). A typical
|
the empty string all words are taken (as with `tt(*)'). A typical
|
||||||
use is
|
use is
|
||||||
|
|
||||||
indent(
|
example(compctl -D -f PLUS() -H 0 '')
|
||||||
tt(compctl -D -f PLUS() -H 0 '')
|
|
||||||
)
|
|
||||||
|
|
||||||
which forces completion to look back in the history list for a word if
|
which forces completion to look back in the history list for a word if
|
||||||
no filename matches.
|
no filename matches.
|
||||||
|
@ -345,9 +337,7 @@ The var(prefix) is inserted just before the completed string; any
|
||||||
initial part already typed will be completed and the whole var(prefix)
|
initial part already typed will be completed and the whole var(prefix)
|
||||||
ignored for completion purposes. For example,
|
ignored for completion purposes. For example,
|
||||||
|
|
||||||
indent(
|
example(compctl -j -P "%" kill)
|
||||||
tt(compctl -j -P "%" kill)
|
|
||||||
)
|
|
||||||
|
|
||||||
inserts a `%' after the kill command and then completes job names.
|
inserts a `%' after the kill command and then completes job names.
|
||||||
)
|
)
|
||||||
|
@ -362,9 +352,7 @@ With directory var(file-prefix): for command, file, directory and
|
||||||
globbing completion (options tt(-c), tt(-f), tt(-/), tt(-g)), the file
|
globbing completion (options tt(-c), tt(-f), tt(-/), tt(-g)), the file
|
||||||
prefix is implicitly added in front of the completion. For example,
|
prefix is implicitly added in front of the completion. For example,
|
||||||
|
|
||||||
indent(
|
example(compctl -/ -W ~/Mail maildirs)
|
||||||
tt(compctl -/ -W ~/Mail maildirs)
|
|
||||||
)
|
|
||||||
|
|
||||||
completes any subdirectories to any depth beneath the directory
|
completes any subdirectories to any depth beneath the directory
|
||||||
tt(~/Mail), although that prefix does not appear on the command line.
|
tt(~/Mail), although that prefix does not appear on the command line.
|
||||||
|
@ -393,9 +381,7 @@ option. If the var(cmd) string is empty the first word in the range
|
||||||
is instead taken as the command name, and command name completion
|
is instead taken as the command name, and command name completion
|
||||||
performed on the first word in the range. For example,
|
performed on the first word in the range. For example,
|
||||||
|
|
||||||
indent(
|
example(compctl -x 'r[-exec,;]' -l '' -- find)
|
||||||
tt(compctl -x 'r[-exec,;]' -l '' -- find)
|
|
||||||
)
|
|
||||||
|
|
||||||
completes arguments between `tt(-exec)' and the following `tt(;)' (or the end
|
completes arguments between `tt(-exec)' and the following `tt(;)' (or the end
|
||||||
of the command line if there is no such string) as if they were
|
of the command line if there is no such string) as if they were
|
||||||
|
@ -419,7 +405,7 @@ tt(-K) option) which can examine the word components passed to it
|
||||||
use its own criteria to decide what matches. If there is no
|
use its own criteria to decide what matches. If there is no
|
||||||
completion, the original word is retained. Since the produced
|
completion, the original word is retained. Since the produced
|
||||||
possible completions seldom seldom have interesting common prefixes
|
possible completions seldom seldom have interesting common prefixes
|
||||||
and suffixes, menucompletion is started immediatly if tt(AUTO_MENU) is
|
and suffixes, menucompletion is started immediately if tt(AUTO_MENU) is
|
||||||
set and this flag is used.
|
set and this flag is used.
|
||||||
)
|
)
|
||||||
item(tt(-y) var(func-or-var))(
|
item(tt(-y) var(func-or-var))(
|
||||||
|
@ -499,9 +485,7 @@ group name are stored in that group.
|
||||||
This can be useful with non-exclusive alternative completions. For
|
This can be useful with non-exclusive alternative completions. For
|
||||||
example, in
|
example, in
|
||||||
|
|
||||||
indent(
|
example(compctl -f -J files -t+ + -v -J variables foo)
|
||||||
tt(compctl -f -J files -t+ + -v -J variables foo)
|
|
||||||
)
|
|
||||||
|
|
||||||
both files and variables are possible completions, as the tt(-t+) forces
|
both files and variables are possible completions, as the tt(-t+) forces
|
||||||
both sets of alternatives before and after the tt(+) to be considered at
|
both sets of alternatives before and after the tt(+) to be considered at
|
||||||
|
@ -521,7 +505,7 @@ of the var(match-spec) string is described below in noderef(Matching Control).
|
||||||
)
|
)
|
||||||
enditem()
|
enditem()
|
||||||
|
|
||||||
texinode(Alternative Completion)(Extended Completion)(Option Flags)(Programmable Completion)
|
texinode(Alternative Completion)(Extended Completion)(Option Flags)(Programmable Completion Using compctl)
|
||||||
sect(Alternative Completion)
|
sect(Alternative Completion)
|
||||||
startlist()
|
startlist()
|
||||||
list(tt(compctl) [ tt(-CDT) ] var(options) tt(PLUS()) var(options) [ tt(PLUS()) ... ] \
|
list(tt(compctl) [ tt(-CDT) ] var(options) tt(PLUS()) var(options) [ tt(PLUS()) ... ] \
|
||||||
|
@ -536,7 +520,7 @@ up to that point, default completion is tried.
|
||||||
If the list of flags contains a tt(-t) with a tt(PLUS()) character, the next
|
If the list of flags contains a tt(-t) with a tt(PLUS()) character, the next
|
||||||
list of flags is used even if the current list produced matches.
|
list of flags is used even if the current list produced matches.
|
||||||
|
|
||||||
texinode(Extended Completion)(Matching Control)(Alternative Completion)(Programmable Completion)
|
texinode(Extended Completion)(Matching Control)(Alternative Completion)(Programmable Completion Using compctl)
|
||||||
sect(Extended Completion)
|
sect(Extended Completion)
|
||||||
startlist()
|
startlist()
|
||||||
list(nofill(tt(compctl) [ tt(-CDT) ] var(options) \
|
list(nofill(tt(compctl) [ tt(-CDT) ] var(options) \
|
||||||
|
@ -612,9 +596,7 @@ considered part of the completion, but the rest will. var(index) may
|
||||||
be negative to count from the end: in most cases, var(index) will be
|
be negative to count from the end: in most cases, var(index) will be
|
||||||
1 or -1. For example,
|
1 or -1. For example,
|
||||||
|
|
||||||
indent(
|
example(compctl -s '`users`' -x 'n[1,@]' -k hosts -- talk)
|
||||||
tt(compctl -s '`users`' -x 'n[1,@]' -k hosts -- talk)
|
|
||||||
)
|
|
||||||
|
|
||||||
will usually complete usernames, but if you insert an tt(@) after the
|
will usually complete usernames, but if you insert an tt(@) after the
|
||||||
name, names from the array var(hosts) (assumed to contain hostnames,
|
name, names from the array var(hosts) (assumed to contain hostnames,
|
||||||
|
@ -648,7 +630,7 @@ completion is done in backticks and var(str) starts with a `b'.
|
||||||
)
|
)
|
||||||
enditem()
|
enditem()
|
||||||
|
|
||||||
texinode(Matching Control)(Example)(Extended Completion)(Programmable Completion)
|
texinode(Matching Control)(Example)(Extended Completion)(Programmable Completion Using compctl)
|
||||||
sect(Matching Control)
|
sect(Matching Control)
|
||||||
|
|
||||||
It is possible by use of the tt(-M) var(spec) flag to specify how the
|
It is possible by use of the tt(-M) var(spec) flag to specify how the
|
||||||
|
@ -732,10 +714,10 @@ following alters the matching rules so that the prefix tt(no) and any
|
||||||
underscore are ignored when trying to match the trial completions
|
underscore are ignored when trying to match the trial completions
|
||||||
generated and uppercase letters on the line match the corresponding
|
generated and uppercase letters on the line match the corresponding
|
||||||
lowercase letters in the words:
|
lowercase letters in the words:
|
||||||
indent(
|
|
||||||
nofill(tt(compctl -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' \
|
example(compctl -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' \
|
||||||
-o setopt unsetopt))
|
-o setopt unsetopt)
|
||||||
)
|
|
||||||
The first part says that the pattern `tt([nN][oO])' at the beginning
|
The first part says that the pattern `tt([nN][oO])' at the beginning
|
||||||
(the empty anchor before the pipe symbol) of the string on the
|
(the empty anchor before the pipe symbol) of the string on the
|
||||||
line matches the empty string in the list of words generated by
|
line matches the empty string in the list of words generated by
|
||||||
|
@ -752,14 +734,13 @@ The second example makes completion case insensitive. By using
|
||||||
tt(compctl) with the tt(-M) option alone this applies to every
|
tt(compctl) with the tt(-M) option alone this applies to every
|
||||||
completion. This is just the same as in the tt(setopt) example, except
|
completion. This is just the same as in the tt(setopt) example, except
|
||||||
here we wish to retain the characters in the list of completions:
|
here we wish to retain the characters in the list of completions:
|
||||||
indent(
|
|
||||||
tt(compctl -M 'm:{a-z}={A-Z}')
|
example(compctl -M 'm:{a-z}={A-Z}')
|
||||||
)
|
|
||||||
This makes lowercase letters match their uppercase counterparts.
|
This makes lowercase letters match their uppercase counterparts.
|
||||||
To make uppercase letters match the lowercase forms as well:
|
To make uppercase letters match the lowercase forms as well:
|
||||||
indent(
|
|
||||||
tt(compctl -M 'm:{a-zA-Z}={A-Za-z}')
|
example(compctl -M 'm:{a-zA-Z}={A-Za-z}')
|
||||||
)
|
|
||||||
|
|
||||||
A nice example for the use of tt(*) patterns is partial word
|
A nice example for the use of tt(*) patterns is partial word
|
||||||
completion. Sometimes you would like to make strings like tt(c.s.u)
|
completion. Sometimes you would like to make strings like tt(c.s.u)
|
||||||
|
@ -770,10 +751,10 @@ however, that the case where each part of the word, i.e. tt(comp),
|
||||||
tt(source) and tt(unix) in this example, is to be completed separately
|
tt(source) and tt(unix) in this example, is to be completed separately
|
||||||
is a different problem to be solved by extended completion. The
|
is a different problem to be solved by extended completion. The
|
||||||
example can be handled by:
|
example can be handled by:
|
||||||
indent(
|
|
||||||
nofill(tt(compctl -M 'r:|.=* r:|=*' \
|
example(compctl -M 'r:|.=* r:|=*' \
|
||||||
-k '(comp.sources.unix comp.sources.misc ...)' ngroups))
|
-k '(comp.sources.unix comp.sources.misc ...)' ngroups)
|
||||||
)
|
|
||||||
The first specification says that tt(lpat) is the empty string, while
|
The first specification says that tt(lpat) is the empty string, while
|
||||||
tt(anchor) is a dot; tt(tpat) is tt(*), so this can match anything
|
tt(anchor) is a dot; tt(tpat) is tt(*), so this can match anything
|
||||||
except for the `tt(.)' from the anchor in
|
except for the `tt(.)' from the anchor in
|
||||||
|
@ -795,9 +776,9 @@ empty string at the end of the string on the line matches any characters
|
||||||
at the end of the trial completion.
|
at the end of the trial completion.
|
||||||
|
|
||||||
More generally, the specification
|
More generally, the specification
|
||||||
indent(
|
|
||||||
tt(compctl -M 'r:|[.,_-]=* r:|=*')
|
example(compctl -M 'r:|[.,_-]=* r:|=*')
|
||||||
)
|
|
||||||
allows one to complete words with abbreviations before any of the
|
allows one to complete words with abbreviations before any of the
|
||||||
characters in the square brackets in any completion. For example, to
|
characters in the square brackets in any completion. For example, to
|
||||||
complete tt(veryverylongfile.c) rather than tt(veryverylongheader.h)
|
complete tt(veryverylongfile.c) rather than tt(veryverylongheader.h)
|
||||||
|
@ -817,9 +798,9 @@ the string on the command line as a substring, not just at the
|
||||||
beginning. Since this might produce more matches than we want,
|
beginning. Since this might produce more matches than we want,
|
||||||
we arrange for it to be tried only if the matchers described above don't
|
we arrange for it to be tried only if the matchers described above don't
|
||||||
produce any matches:
|
produce any matches:
|
||||||
indent(
|
|
||||||
tt(compctl -M 'r:|[.,_-]=* r:|=*' 'l:|=* r:|=*')
|
example(compctl -M 'r:|[.,_-]=* r:|=*' 'l:|=* r:|=*')
|
||||||
)
|
|
||||||
Here, if the string on the command line is tt(foo.bar), tt(compctl)
|
Here, if the string on the command line is tt(foo.bar), tt(compctl)
|
||||||
first tries matching tt(foo)var(anything)tt(.bar)var(anything), as
|
first tries matching tt(foo)var(anything)tt(.bar)var(anything), as
|
||||||
with the previous example. If that fails, the two descriptions in the
|
with the previous example. If that fails, the two descriptions in the
|
||||||
|
@ -828,13 +809,12 @@ and end of the string on the command line can match any set of
|
||||||
characters at the beginning or end of the trial completion, so it will
|
characters at the beginning or end of the trial completion, so it will
|
||||||
look for var(anything)tt(foo.bar)var(anything).
|
look for var(anything)tt(foo.bar)var(anything).
|
||||||
|
|
||||||
texinode(Example)()(Matching Control)(Programmable Completion)
|
texinode(Example)()(Matching Control)(Programmable Completion Using compctl)
|
||||||
sect(Example)
|
sect(Example)
|
||||||
indent(
|
|
||||||
nofill(
|
example(compctl -u -x 's[tt(PLUS())] c[-1,-f],s[-f+PLUS()]' \
|
||||||
tt(compctl -u -x 's[tt(PLUS())] c[-1,-f],s[-f+PLUS()]' \
|
-g '~/Mail/*(:t)' - 's[-f],c[-1,-f]' -f -- mail)
|
||||||
-g '~/Mail/*(:t)' - 's[-f],c[-1,-f]' -f -- mail))
|
|
||||||
)
|
|
||||||
This is to be interpreted as follows:
|
This is to be interpreted as follows:
|
||||||
|
|
||||||
If the current command is tt(mail), then
|
If the current command is tt(mail), then
|
||||||
|
|
|
@ -51,7 +51,7 @@ sect(Initialisation)
|
||||||
|
|
||||||
The script tt(compinstall) can be run by a user to set up the completion
|
The script tt(compinstall) can be run by a user to set up the completion
|
||||||
system for use. It will usually insert code into tt(.zshrc), although if
|
system for use. It will usually insert code into tt(.zshrc), although if
|
||||||
that is not writeable it will save it in another file and tell you that
|
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 locations. 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
|
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.
|
them to an earlier place in the file if tt(.zshrc) usually returns early.
|
||||||
|
@ -89,13 +89,13 @@ To speed up the running of tt(compinit), it can be made to produce a dumped
|
||||||
configuration which will be read in on future invocations. The easiest way
|
configuration which will be read in on future invocations. The easiest way
|
||||||
to do this is by adding the option tt(-d) whenever tt(compinit) is sourced.
|
to do this is by adding the option tt(-d) whenever tt(compinit) is sourced.
|
||||||
In this case the dumped file will have the same name as the sourced file,
|
In this case the dumped file will have the same name as the sourced file,
|
||||||
but with tt(.dump) appended to the end, or, if that is not writeable by the
|
but with tt(.dump) appended to the end, or, if that is not writable by the
|
||||||
user, the file tt(.zcompdump) in the same directory as the startup files
|
user, the file tt(.zcompdump) in the same directory as the startup files
|
||||||
(i.e. tt($ZDOTDIR) or tt($HOME)); alternatively, an explicit file name can
|
(i.e. tt($ZDOTDIR) or tt($HOME)); alternatively, an explicit file name can
|
||||||
be given following the tt(-d). On the next call to tt(compinit -d), the
|
be given following the tt(-d). On the next call to tt(compinit -d), the
|
||||||
dumped file will be read instead.
|
dumped file will be read instead.
|
||||||
|
|
||||||
The other option accepted by tt(compinit) is tt(-f var(dir)), which gives
|
The other option accepted by tt(compinit) is tt(-f )var(dir), which gives
|
||||||
the directory in which tt(compinit) resides. If you source tt(compinit) by
|
the directory in which tt(compinit) resides. If you source tt(compinit) by
|
||||||
its full pathname, and the option tt(FUNCTION_ARGZERO) is set, as it is by
|
its full pathname, and the option tt(FUNCTION_ARGZERO) is set, as it is by
|
||||||
default unless tt(zsh) is emulating tt(sh) or tt(ksh), this is unnecessary
|
default unless tt(zsh) is emulating tt(sh) or tt(ksh), this is unnecessary
|
||||||
|
@ -106,7 +106,7 @@ the completion functions (see below).
|
||||||
|
|
||||||
If the number of completion files changes, tt(compinit) will recognise this
|
If the number of completion files changes, tt(compinit) will recognise this
|
||||||
and produce a new dump file. However, if the name of a function or the
|
and produce a new dump file. However, if the name of a function or the
|
||||||
arguments in the first line of a tt(#compdef) funcion (as described below)
|
arguments in the first line of a tt(#compdef) function (as described below)
|
||||||
change, it is easiest to delete the dump file by hand so that the next time
|
change, it is easiest to delete the dump file by hand so that the next time
|
||||||
tt(compinit) will re-create it.
|
tt(compinit) will re-create it.
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ var(pattern) (a standard globbing pattern). Note that only one
|
||||||
var(pattern) may be given.
|
var(pattern) may be given.
|
||||||
)
|
)
|
||||||
item(tt(#compdef -k) var(style key-sequences...))(
|
item(tt(#compdef -k) var(style key-sequences...))(
|
||||||
This can be used bind special completion functions to the
|
This can be used to bind special completion functions to the
|
||||||
var(key-sequences). It creates a widget behaving like the builtin widget
|
var(key-sequences). It creates a widget behaving like the builtin widget
|
||||||
var(style), which must be one of those that perform completion, namely
|
var(style), which must be one of those that perform completion, namely
|
||||||
tt(complete-word), tt(delete-char-or-list), tt(expand-or-complete),
|
tt(complete-word), tt(delete-char-or-list), tt(expand-or-complete),
|
||||||
|
@ -252,9 +252,7 @@ set of functions to try is taken from the colon-separated list in the
|
||||||
configuration key tt(completer). For example, to use normal
|
configuration key tt(completer). For example, to use normal
|
||||||
completion and correction if that doesn't generate any matches:
|
completion and correction if that doesn't generate any matches:
|
||||||
|
|
||||||
indent(
|
example(compconf completer=_complete:_correct)
|
||||||
nofill(tt(compconf completer=_complete:_correct))
|
|
||||||
)
|
|
||||||
|
|
||||||
after sourcing tt(compinit). The default value for this configuration key
|
after sourcing tt(compinit). The default value for this configuration key
|
||||||
set up in tt(compinit) is `tt(_complete)', i.e. normally only ordinary
|
set up in tt(compinit) is `tt(_complete)', i.e. normally only ordinary
|
||||||
|
@ -355,9 +353,7 @@ counted. The resulting list of corrected and completed strings is then
|
||||||
presented to the user. The intended use of this completer function is to
|
presented to the user. The intended use of this completer function is to
|
||||||
try after the normal tt(_complete) completer by setting:
|
try after the normal tt(_complete) completer by setting:
|
||||||
|
|
||||||
indent(
|
example(compconf completer=_complete:_approximate)
|
||||||
nofill(tt(compconf completer=_complete:_approximate))
|
|
||||||
)
|
|
||||||
|
|
||||||
This will give correcting completion if and only if
|
This will give correcting completion if and only if
|
||||||
normal completion doesn't yield any possible completions. When
|
normal completion doesn't yield any possible completions. When
|
||||||
|
@ -379,9 +375,7 @@ If the value for this key contains a lower- or upper-case `tt(n)', the
|
||||||
completer function will take any numeric argument as the
|
completer function will take any numeric argument as the
|
||||||
maximum number of errors allowed. For example, with
|
maximum number of errors allowed. For example, with
|
||||||
|
|
||||||
indent(
|
example(compconf approximate_accept=2n)
|
||||||
nofill(tt(compconf approximate_accept=2n))
|
|
||||||
)
|
|
||||||
|
|
||||||
two errors will be allowed if no numeric argument is given. However,
|
two errors will be allowed if no numeric argument is given. However,
|
||||||
with a numeric argument of six (as in `tt(ESC-6 TAB)'), up to six
|
with a numeric argument of six (as in `tt(ESC-6 TAB)'), up to six
|
||||||
|
@ -443,10 +437,8 @@ configuration parameters beginning tt(correct_) are used.
|
||||||
|
|
||||||
For example, with:
|
For example, with:
|
||||||
|
|
||||||
indent(tt(
|
example(compconf completer=_complete:_correct:_approximate
|
||||||
nofill(compconf completer=_complete:_correct:_approximate)
|
compconf correct_accept='2n!' approximate_accept=3n)
|
||||||
nofill(compconf correct_accept='2n!' approximate_accept=3n))
|
|
||||||
)
|
|
||||||
|
|
||||||
correction will accept up to two errors. If a numeric argument is
|
correction will accept up to two errors. If a numeric argument is
|
||||||
given, correction will not be performed, but correcting completion will be,
|
given, correction will not be performed, but correcting completion will be,
|
||||||
|
@ -464,7 +456,7 @@ generated by the tt(_correct) completer -- and probably more.
|
||||||
item(tt(_match))(
|
item(tt(_match))(
|
||||||
This completer is intended to be used after the tt(_complete)
|
This completer is intended to be used after the tt(_complete)
|
||||||
completer. It allows one to give patterns on the command line and
|
completer. It allows one to give patterns on the command line and
|
||||||
to complete all strings metching these patterns from the set of possible
|
to complete all strings matching these patterns from the set of possible
|
||||||
completions for the context the cursor is in, without having to set
|
completions for the context the cursor is in, without having to set
|
||||||
the tt(GLOB_COMPLETE) option.
|
the tt(GLOB_COMPLETE) option.
|
||||||
|
|
||||||
|
@ -498,9 +490,7 @@ non-empty string it should be an expression usable inside a `tt($((...)))'
|
||||||
arithmetical expression. In this case, expansion of substitutions will
|
arithmetical expression. In this case, expansion of substitutions will
|
||||||
be done if the expression evaluates to `tt(1)'. For example, with
|
be done if the expression evaluates to `tt(1)'. For example, with
|
||||||
|
|
||||||
indent(
|
example(compconf expand_substitute='NUMERIC != 1')
|
||||||
nofill(tt(compconf expand_substitute='NUMERIC != 1'))
|
|
||||||
)
|
|
||||||
|
|
||||||
substitution will be performed only if given an explicit numeric
|
substitution will be performed only if given an explicit numeric
|
||||||
argument other than `tt(1)', as by typing `tt(ESC 2 TAB)'.
|
argument other than `tt(1)', as by typing `tt(ESC 2 TAB)'.
|
||||||
|
@ -556,9 +546,7 @@ should be set to an expression usable inside a `tt($((...)))'
|
||||||
arithmetical expression. In this case, delaying will be done if the
|
arithmetical expression. In this case, delaying will be done if the
|
||||||
expression evaluates to `tt(1)'. For example, with
|
expression evaluates to `tt(1)'. For example, with
|
||||||
|
|
||||||
indent(
|
example(compconf list_condition='NUMERIC != 1')
|
||||||
nofill(tt(compconf list_condition='NUMERIC != 1'))
|
|
||||||
)
|
|
||||||
|
|
||||||
delaying will be done only if given an explicit numeric argument
|
delaying will be done only if given an explicit numeric argument
|
||||||
other than `tt(1)'.
|
other than `tt(1)'.
|
||||||
|
@ -614,6 +602,7 @@ continues with the existing list of completions. If this key is set to
|
||||||
tt(never), however, a new completion is started if the old list was
|
tt(never), however, a new completion is started if the old list was
|
||||||
generated by a different completion command (the behaviour without the
|
generated by a different completion command (the behaviour without the
|
||||||
tt(_oldlist) completer).
|
tt(_oldlist) completer).
|
||||||
|
|
||||||
For example, suppose you type tt(^Xc) to generate a list of corrections,
|
For example, suppose you type tt(^Xc) to generate a list of corrections,
|
||||||
and menu completion is started in one of the usual ways. Usually, typing
|
and menu completion is started in one of the usual ways. Usually, typing
|
||||||
tt(TAB) at this point would start trying to complete the line as it now
|
tt(TAB) at this point would start trying to complete the line as it now
|
||||||
|
@ -704,7 +693,7 @@ over which filenames should be ignored as done by the tt(fignore)
|
||||||
parameter in normal completion.
|
parameter in normal completion.
|
||||||
|
|
||||||
The function tt(_files) calls tt(_path_files) with all the arguments
|
The function tt(_files) calls tt(_path_files) with all the arguments
|
||||||
it was passed and, if that generated no matches, call tt(_path_files) again
|
it was passed and, if that generated no matches, calls tt(_path_files) again
|
||||||
without any tt(-g) or tt(-/) option, thus generating all filenames.
|
without any tt(-g) or tt(-/) option, thus generating all filenames.
|
||||||
|
|
||||||
These functions also accept the `tt(-J)', `tt(-V)', `tt(-X)', `tt(-P)',
|
These functions also accept the `tt(-J)', `tt(-V)', `tt(-X)', `tt(-P)',
|
||||||
|
@ -764,11 +753,9 @@ not start with a square bracket or parenthesis, it should be the name of a
|
||||||
command (probably with arguments) that should be invoked to complete
|
command (probably with arguments) that should be invoked to complete
|
||||||
after the equal sign. Example:
|
after the equal sign. Example:
|
||||||
|
|
||||||
indent(
|
example(_long_options '*\*' '(yes no)' \
|
||||||
nofill(tt(_long_options '*\*' '(yes no)' \))
|
'*=FILE*' '_files' \
|
||||||
nofill(tt( '*=FILE*' '_files' \))
|
'*=DIR*' '_files -/')
|
||||||
nofill(tt( '*=DIR*' '_files -/'))
|
|
||||||
)
|
|
||||||
|
|
||||||
Here, `tt(yes)' and `tt(no)' will be completed as the argument of
|
Here, `tt(yes)' and `tt(no)' will be completed as the argument of
|
||||||
options whose description ends in a star, file names for options that
|
options whose description ends in a star, file names for options that
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
texinode(Completion Widgets)(Zsh Modules)(Programmable Completion)(Top)
|
texinode(Completion Widgets)(Zsh Modules)(Programmable Completion Using compctl)(Top)
|
||||||
chapter(Completion Widgets)
|
chapter(Completion Widgets)
|
||||||
cindex(completion, widgets)
|
cindex(completion, widgets)
|
||||||
cindex(completion, programmable)
|
cindex(completion, programmable)
|
||||||
|
@ -10,9 +10,7 @@ ifzman(zmanref(zshzle))\
|
||||||
ifnzman(noderef(The zle Module))\
|
ifnzman(noderef(The zle Module))\
|
||||||
). For example,
|
). For example,
|
||||||
|
|
||||||
indent(
|
example(zle -C complete expand-or-complete completer)
|
||||||
nofill(tt(zle -C complete expand-or-complete completer))
|
|
||||||
)
|
|
||||||
|
|
||||||
defines a widget named tt(complete). When this widget is bound to a key
|
defines a widget named tt(complete). When this widget is bound to a key
|
||||||
using the tt(bindkey) builtin command defined in the tt(zle) module
|
using the tt(bindkey) builtin command defined in the tt(zle) module
|
||||||
|
@ -73,10 +71,8 @@ not considered part of the list of matches. Typically, a string is
|
||||||
transferred from the beginning of tt(PREFIX) to the end of tt(IPREFIX), for
|
transferred from the beginning of tt(PREFIX) to the end of tt(IPREFIX), for
|
||||||
example:
|
example:
|
||||||
|
|
||||||
tt(indent(
|
example(IPREFIX=${PREFIX%%\=*}=
|
||||||
nofill(IPREFIX=${PREFIX%%\=*}=)
|
PREFIX=${PREFIX#*=})
|
||||||
nofill(PREFIX=${PREFIX#*=})
|
|
||||||
))
|
|
||||||
|
|
||||||
causes the part of the prefix up to and including the first equal sign not
|
causes the part of the prefix up to and including the first equal sign not
|
||||||
to be treated as part of a matched string.
|
to be treated as part of a matched string.
|
||||||
|
@ -182,9 +178,7 @@ item(tt(matcher))(
|
||||||
When completion is performed with a global match specification as defined
|
When completion is performed with a global match specification as defined
|
||||||
by
|
by
|
||||||
|
|
||||||
indent(
|
indent(tt(compctl -M) var(spec1 ... specN ...))
|
||||||
nofill(tt(compctl -M) var(spec1 ... specN ...))
|
|
||||||
)
|
|
||||||
|
|
||||||
this gives the number of the specification string currently in use.
|
this gives the number of the specification string currently in use.
|
||||||
In this case, matching is performed with each specification in turn.
|
In this case, matching is performed with each specification in turn.
|
||||||
|
@ -229,7 +223,7 @@ the tt(ALWAYS_LAST_PROMPT) option.
|
||||||
)
|
)
|
||||||
item(tt(insert))(
|
item(tt(insert))(
|
||||||
This controls the manner in which a match is inserted into the command
|
This controls the manner in which a match is inserted into the command
|
||||||
line. On entry to the widget fuction, if it is unset the command line is
|
line. On entry to the widget function, if it is unset the command line is
|
||||||
not to be changed; if set to tt(unambiguous), any prefix common to all
|
not to be changed; if set to tt(unambiguous), any prefix common to all
|
||||||
matches is to be inserted; if set to tt(menu) or tt(automenu) the usual
|
matches is to be inserted; if set to tt(menu) or tt(automenu) the usual
|
||||||
behaviour of the tt(MENU_COMPLETE) or tt(AUTO_MENU) options, respectively,
|
behaviour of the tt(MENU_COMPLETE) or tt(AUTO_MENU) options, respectively,
|
||||||
|
@ -262,7 +256,7 @@ item(tt(old_list))(
|
||||||
This is set to tt(yes) if there is still a valid list of completions
|
This is set to tt(yes) if there is still a valid list of completions
|
||||||
from a previous completion at the time the widget is invoked. This will
|
from a previous completion at the time the widget is invoked. This will
|
||||||
usually be the case if and only if the previous editing operation was a
|
usually be the case if and only if the previous editing operation was a
|
||||||
completion widget or one of the builtin completion fuctions. If there is a
|
completion widget or one of the builtin completion functions. If there is a
|
||||||
valid list and it is also currently shown on the screen, the value of this
|
valid list and it is also currently shown on the screen, the value of this
|
||||||
key is tt(shown).
|
key is tt(shown).
|
||||||
|
|
||||||
|
@ -330,7 +324,7 @@ Generate matches according to the given var(flags). These can be any of
|
||||||
the normal option flags (not those for extended completion) supported by
|
the normal option flags (not those for extended completion) supported by
|
||||||
the tt(compctl) builtin command (see
|
the tt(compctl) builtin command (see
|
||||||
ifzman(zmanref(zshcompctl))\
|
ifzman(zmanref(zshcompctl))\
|
||||||
ifnzman(noderef(Programmable Completion))\
|
ifnzman(noderef(Programmable Completion Using compctl))\
|
||||||
) except for the tt(-t) and tt(-l) flags. However, when using the tt(-K)
|
) except for the tt(-t) and tt(-l) flags. However, when using the tt(-K)
|
||||||
flag, the function given as argument to it cannot access the command
|
flag, the function given as argument to it cannot access the command
|
||||||
line with the tt(read) builtin command.
|
line with the tt(read) builtin command.
|
||||||
|
@ -339,7 +333,7 @@ The matches will be generated in the same way as if the completion code
|
||||||
generated them directly from a tt(compctl)-definition with the same
|
generated them directly from a tt(compctl)-definition with the same
|
||||||
flags. The completion code will consider only those matches as
|
flags. The completion code will consider only those matches as
|
||||||
possible completions that match the prefix and suffix from the special
|
possible completions that match the prefix and suffix from the special
|
||||||
parameters desribed above. These strings will be compared with the
|
parameters described above. These strings will be compared with the
|
||||||
generated matches using the normal matching rules and any matching
|
generated matches using the normal matching rules and any matching
|
||||||
specifications given with the tt(-M) flag to tt(compgen) and the
|
specifications given with the tt(-M) flag to tt(compgen) and the
|
||||||
global matching specifications given via the tt(compctl -M )var(spec1 ...)
|
global matching specifications given via the tt(compctl -M )var(spec1 ...)
|
||||||
|
@ -366,9 +360,7 @@ non-zero if no matches were added.
|
||||||
The completion code breaks the string to complete into seven fields in
|
The completion code breaks the string to complete into seven fields in
|
||||||
the order:
|
the order:
|
||||||
|
|
||||||
indent(
|
indent(var(<ipre><apre><hpre><word><hsuf><asuf><isuf>))
|
||||||
var(<ipre><apre><hpre><word><hsuf><asuf><isuf>)
|
|
||||||
)
|
|
||||||
|
|
||||||
The first field
|
The first field
|
||||||
is an ignored prefix taken from the command line, the contents of the
|
is an ignored prefix taken from the command line, the contents of the
|
||||||
|
@ -620,20 +612,18 @@ testing and modification is performed as if it were not given.
|
||||||
)
|
)
|
||||||
item(tt(-q))(
|
item(tt(-q))(
|
||||||
If the cursor is currently inside single or double quotes, the word
|
If the cursor is currently inside single or double quotes, the word
|
||||||
currenly being completed is split in separate words at the spaces. The
|
currently being completed is split in separate words at the spaces. The
|
||||||
resulting words are stored in the tt(words) array, and tt(PREFIX),
|
resulting words are stored in the tt(words) array, and tt(PREFIX),
|
||||||
tt(SUFFIX), tt(QIPREFIX), and tt(QISUFFIX) are modified to reflect the
|
tt(SUFFIX), tt(QIPREFIX), and tt(QISUFFIX) are modified to reflect the
|
||||||
word part that is completed.
|
word part that is completed.
|
||||||
)
|
)
|
||||||
enditem()
|
enditem()
|
||||||
|
|
||||||
In all the above cases the return value is zero if the test succeded
|
In all the above cases the return value is zero if the test succeeded
|
||||||
and the parameters were modified and non-zero otherwise. This allows
|
and the parameters were modified and non-zero otherwise. This allows
|
||||||
one to use this builtin in tests such as:
|
one to use this builtin in tests such as:
|
||||||
|
|
||||||
indent(
|
example(if compset -P '*\='; then ...)
|
||||||
tt(if compset -P '*\='; then ...)
|
|
||||||
)
|
|
||||||
|
|
||||||
This forces anything up to and including the last equal sign to be
|
This forces anything up to and including the last equal sign to be
|
||||||
ignored by the completion code.
|
ignored by the completion code.
|
||||||
|
@ -685,21 +675,18 @@ sect(Examples)
|
||||||
|
|
||||||
The first step is to define the widget:
|
The first step is to define the widget:
|
||||||
|
|
||||||
indent(nofill(
|
example(zle -C complete complete-word complete-history)
|
||||||
tt(zle -C complete complete-word complete-history)))
|
|
||||||
|
|
||||||
Then the widget can be bound to a key using the tt(bindkey) builtin
|
Then the widget can be bound to a key using the tt(bindkey) builtin
|
||||||
command:
|
command:
|
||||||
|
|
||||||
indent(nofill(
|
example(bindkey '^X\t' complete)
|
||||||
tt(bindkey '^X\t' complete)))
|
|
||||||
|
|
||||||
After that the shell function tt(complete-history) will be invoked
|
After that the shell function tt(complete-history) will be invoked
|
||||||
after typing control-X and TAB. The function should then generate the
|
after typing control-X and TAB. The function should then generate the
|
||||||
matches, e.g.:
|
matches, e.g.:
|
||||||
|
|
||||||
indent(nofill(
|
example(complete-history LPAR()RPAR() { compgen -H 0 '' })
|
||||||
tt(complete-history LPAR()RPAR() { compgen -H 0 '' })))
|
|
||||||
|
|
||||||
This function will complete words from the history matching the
|
This function will complete words from the history matching the
|
||||||
current word.
|
current word.
|
||||||
|
|
|
@ -277,7 +277,8 @@ If tt(<) is used, then the file passed as an argument will
|
||||||
be a named pipe connected to the output of the var(list) process.
|
be a named pipe connected to the output of the var(list) process.
|
||||||
For example,
|
For example,
|
||||||
|
|
||||||
nofill(tt(paste <LPAR()cut -f1) var(file1)tt(RPAR() <LPAR()cut -f3) var(file2)tt(RPAR() | tee >LPAR())var(process1)tt(RPAR() >LPAR())var(process2)tt(RPAR() >/dev/null))
|
nofill(tt(paste <LPAR()cut -f1) var(file1)tt(RPAR() <LPAR()cut -f3) var(file2)tt(RPAR() |
|
||||||
|
tee >LPAR())var(process1)tt(RPAR() >LPAR())var(process2)tt(RPAR() >/dev/null))
|
||||||
|
|
||||||
cuts fields 1 and 3 from the files var(file1) and var(file2) respectively,
|
cuts fields 1 and 3 from the files var(file1) and var(file2) respectively,
|
||||||
pastes the results together, and sends it to the processes
|
pastes the results together, and sends it to the processes
|
||||||
|
@ -427,9 +428,9 @@ the flags tt(M), tt(R), tt(B), tt(E) and tt(N) are not useful.
|
||||||
|
|
||||||
For example,
|
For example,
|
||||||
|
|
||||||
nofill(tt(foo="twinkle twinkle little star" sub="t*e" rep="spy")
|
example(foo="twinkle twinkle little star" sub="t*e" rep="spy"
|
||||||
tt(print ${foo//${~sub}/$rep})
|
print ${foo//${~sub}/$rep}
|
||||||
tt(print ${(S)foo//${~sub}/$rep}))
|
print ${(S)foo//${~sub}/$rep})
|
||||||
|
|
||||||
Here, the `tt(~)' ensures that the text of tt($sub) is treated as a
|
Here, the `tt(~)' ensures that the text of tt($sub) is treated as a
|
||||||
pattern rather than a plain string. In the first case, the longest
|
pattern rather than a plain string. In the first case, the longest
|
||||||
|
@ -728,7 +729,7 @@ account of whether the current value is a scalar or an array, whether the
|
||||||
whole substitution is in double quotes, and what flags are supplied to the
|
whole substitution is in double quotes, and what flags are supplied to the
|
||||||
current level of substitution, just as if the nested substitution were the
|
current level of substitution, just as if the nested substitution were the
|
||||||
outermost. The flags are not propagated up to enclosing
|
outermost. The flags are not propagated up to enclosing
|
||||||
substitutions; the nested subsitution will return either a scalar or an
|
substitutions; the nested substitution will return either a scalar or an
|
||||||
array as determined by the flags, possibly adjusted for quoting. All the
|
array as determined by the flags, possibly adjusted for quoting. All the
|
||||||
following steps take place where applicable at all levels of substitution.
|
following steps take place where applicable at all levels of substitution.
|
||||||
Note that, unless the `tt((P))' flag is present, the flags and any subscripts
|
Note that, unless the `tt((P))' flag is present, the flags and any subscripts
|
||||||
|
@ -1221,11 +1222,11 @@ matching the pattern var(foo).
|
||||||
As a shorthand, `tt(**/)' is equivalent to `tt((*/)#)'.
|
As a shorthand, `tt(**/)' is equivalent to `tt((*/)#)'.
|
||||||
Thus:
|
Thus:
|
||||||
|
|
||||||
nofill(tt(ls (*/)#bar))
|
example(ls (*/)#bar)
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
nofill(tt(ls **/bar))
|
example(ls **/bar)
|
||||||
|
|
||||||
does a recursive directory search for files named `tt(bar)', not following
|
does a recursive directory search for files named `tt(bar)', not following
|
||||||
symbolic links. To follow links, use `tt(***/)'.
|
symbolic links. To follow links, use `tt(***/)'.
|
||||||
|
@ -1468,26 +1469,26 @@ name of any existing file can be followed by a modifier of the form
|
||||||
`tt((:..))' even if no actual filename generation is performed.
|
`tt((:..))' even if no actual filename generation is performed.
|
||||||
Thus:
|
Thus:
|
||||||
|
|
||||||
nofill(tt(ls *(-/)))
|
example(ls *(-/))
|
||||||
|
|
||||||
lists all directories and symbolic links that point to directories,
|
lists all directories and symbolic links that point to directories,
|
||||||
and
|
and
|
||||||
|
|
||||||
nofill(tt(ls *(%W)))
|
example(ls *(%W))
|
||||||
|
|
||||||
lists all world-writable device files in the current directory, and
|
lists all world-writable device files in the current directory, and
|
||||||
|
|
||||||
nofill(tt(ls *(W,X)))
|
example(ls *(W,X))
|
||||||
|
|
||||||
lists all files in the current directory that are
|
lists all files in the current directory that are
|
||||||
world-writable or world-executable, and
|
world-writable or world-executable, and
|
||||||
|
|
||||||
nofill(tt(echo /tmp/foo*(u0^@:t)))
|
example(echo /tmp/foo*(u0^@:t))
|
||||||
|
|
||||||
outputs the basename of all root-owned files beginning with the string
|
outputs the basename of all root-owned files beginning with the string
|
||||||
`tt(foo)' in tt(/tmp), ignoring symlinks, and
|
`tt(foo)' in tt(/tmp), ignoring symlinks, and
|
||||||
|
|
||||||
nofill(tt(ls *.*~(lex|parse).[ch](^D^l1)))
|
example(ls *.*~(lex|parse).[ch](^D^l1))
|
||||||
|
|
||||||
lists all files having a link count of one whose names contain a dot
|
lists all files having a link count of one whose names contain a dot
|
||||||
(but not those starting with a dot, since tt(GLOB_DOTS) is explicitly
|
(but not those starting with a dot, since tt(GLOB_DOTS) is explicitly
|
||||||
|
|
|
@ -26,7 +26,7 @@ tt($ZDOTDIR/.zlogin) are read.
|
||||||
|
|
||||||
When a login shell exits, the files tt($ZDOTDIR/.zlogout) and then
|
When a login shell exits, the files tt($ZDOTDIR/.zlogout) and then
|
||||||
tt(/etc/zlogout) are read. This happens with either an explicit exit
|
tt(/etc/zlogout) are read. This happens with either an explicit exit
|
||||||
via the tt(exit) or tt(logout) commands, or an implict exit by reading
|
via the tt(exit) or tt(logout) commands, or an implicit exit by reading
|
||||||
end-of-file from the terminal. However, if the shell terminates due
|
end-of-file from the terminal. However, if the shell terminates due
|
||||||
to tt(exec)'ing another process, the logout files are not read.
|
to tt(exec)'ing another process, the logout files are not read.
|
||||||
These are also affected by the tt(RCS) and tt(GLOBAL_RCS) options.
|
These are also affected by the tt(RCS) and tt(GLOBAL_RCS) options.
|
||||||
|
|
|
@ -5,7 +5,8 @@ sect(Functions)
|
||||||
)\
|
)\
|
||||||
cindex(functions)
|
cindex(functions)
|
||||||
findex(function)
|
findex(function)
|
||||||
The tt(function) reserved word is used to define shell functions.
|
Shell functions are defined with the tt(function) reserved word or the
|
||||||
|
special syntax `var(funcname) tt(())'.
|
||||||
Shell functions are read in and stored internally.
|
Shell functions are read in and stored internally.
|
||||||
Alias names are resolved when the function is read.
|
Alias names are resolved when the function is read.
|
||||||
Functions are executed like commands with the arguments
|
Functions are executed like commands with the arguments
|
||||||
|
|
|
@ -203,6 +203,11 @@ Normally, only one var(word) is provided; multiple var(word)s
|
||||||
are usually only useful for setting traps.
|
are usually only useful for setting traps.
|
||||||
The body of the function is the var(list) between
|
The body of the function is the var(list) between
|
||||||
the tt({) and tt(}). See noderef(Functions).
|
the tt({) and tt(}). See noderef(Functions).
|
||||||
|
|
||||||
|
If the option tt(SH_GLOB) is set for compatibility with other shells, then
|
||||||
|
whitespace may appear between between the left and right parentheses when
|
||||||
|
there is a single var(word); otherwise, the parentheses will be treated as
|
||||||
|
forming a globbing pattern in that case.
|
||||||
)
|
)
|
||||||
cindex(timing)
|
cindex(timing)
|
||||||
item(tt(time) [ var(pipeline) ])(
|
item(tt(time) [ var(pipeline) ])(
|
||||||
|
|
|
@ -28,7 +28,7 @@ menu(Parameters)
|
||||||
menu(Options)
|
menu(Options)
|
||||||
menu(Shell Builtin Commands)
|
menu(Shell Builtin Commands)
|
||||||
menu(Zsh Line Editor)
|
menu(Zsh Line Editor)
|
||||||
menu(Programmable Completion)
|
menu(Programmable Completion Using compctl)
|
||||||
menu(Completion Widgets)
|
menu(Completion Widgets)
|
||||||
menu(Zsh Modules)
|
menu(Zsh Modules)
|
||||||
menu(Completion System)
|
menu(Completion System)
|
||||||
|
@ -98,7 +98,7 @@ menu(Arguments)
|
||||||
menu(Completion)
|
menu(Completion)
|
||||||
menu(Miscellaneous)
|
menu(Miscellaneous)
|
||||||
|
|
||||||
Programmable Completion
|
Programmable Completion Using compctl
|
||||||
|
|
||||||
menu(Command Flags)
|
menu(Command Flags)
|
||||||
menu(Option Flags)
|
menu(Option Flags)
|
||||||
|
|
|
@ -9,7 +9,7 @@ command, and assigns them small integer numbers.
|
||||||
When a job is started asynchronously with `tt(&)',
|
When a job is started asynchronously with `tt(&)',
|
||||||
the shell prints a line which looks like:
|
the shell prints a line which looks like:
|
||||||
|
|
||||||
nofill(tt([1] 1234))
|
example([1] 1234)
|
||||||
|
|
||||||
indicating that the job which was started asynchronously was job number
|
indicating that the job which was started asynchronously was job number
|
||||||
1 and had one (top-level) process, whose process ID was 1234.
|
1 and had one (top-level) process, whose process ID was 1234.
|
||||||
|
|
|
@ -12,7 +12,7 @@ cindex(author)
|
||||||
Zsh was originally written by Paul Falstad tt(<pf@zsh.org>).
|
Zsh was originally written by Paul Falstad tt(<pf@zsh.org>).
|
||||||
Zsh is now maintained by the members of the zsh-workers mailing
|
Zsh is now maintained by the members of the zsh-workers mailing
|
||||||
list tt(<zsh-workers@sunsite.auc.dk>). The development is currently
|
list tt(<zsh-workers@sunsite.auc.dk>). The development is currently
|
||||||
coordinated by Andrew Main (Zefram) tt(<zefram@zsh.org>). The coordinator
|
coordinated by Peter Stephenson tt(<pws@zsh.org>). The coordinator
|
||||||
can be contacted at tt(<coordinator@zsh.org>), but matters relating to
|
can be contacted at tt(<coordinator@zsh.org>), but matters relating to
|
||||||
the code should generally go to the mailing list.
|
the code should generally go to the mailing list.
|
||||||
texinode(Availability)(Mailing Lists)(Author)(Introduction)
|
texinode(Availability)(Mailing Lists)(Author)(Introduction)
|
||||||
|
|
|
@ -3,7 +3,7 @@ sect(The compctl Module)
|
||||||
The tt(compctl) module makes available several builtin commands. tt(compctl),
|
The tt(compctl) module makes available several builtin commands. tt(compctl),
|
||||||
is the standard way to control completions for ZLE. See
|
is the standard way to control completions for ZLE. See
|
||||||
ifzman(zmanref(zshcompctl))\
|
ifzman(zmanref(zshcompctl))\
|
||||||
ifnzman(noderef(Programmable Completion))\
|
ifnzman(noderef(Programmable Completion Using compctl))\
|
||||||
.
|
.
|
||||||
The other builtin commands can be used in user-defined completion widgets,
|
The other builtin commands can be used in user-defined completion widgets,
|
||||||
see
|
see
|
||||||
|
|
|
@ -34,11 +34,13 @@ handled, zsh's internal memory management may be arbitrarily baroque. Thus
|
||||||
it should not automatically be assumed that use of tt(mapfile) represents a
|
it should not automatically be assumed that use of tt(mapfile) represents a
|
||||||
gain in efficiency over use of other mechanisms. Note in particular that
|
gain in efficiency over use of other mechanisms. Note in particular that
|
||||||
the whole contents of the file will always reside physically in memory when
|
the whole contents of the file will always reside physically in memory when
|
||||||
accessed (possibly multiple times, due to standard parameter subsitution
|
accessed (possibly multiple times, due to standard parameter substitution
|
||||||
operations).
|
operations). In particular, this means handling of sufficiently long files
|
||||||
|
(greater than the machine's swap space, or than the range of the pointer
|
||||||
|
type) will be incorrect.
|
||||||
|
|
||||||
No errors are printed or flagged for non-existent, unreadable, or
|
No errors are printed or flagged for non-existent, unreadable, or
|
||||||
unwriteable files, as the parameter mechanism is too low in the shell
|
unwritable files, as the parameter mechanism is too low in the shell
|
||||||
execution hierarchy to make this convenient.
|
execution hierarchy to make this convenient.
|
||||||
|
|
||||||
It is unfortunate that the mechanism for loading modules does not yet allow
|
It is unfortunate that the mechanism for loading modules does not yet allow
|
||||||
|
|
|
@ -80,7 +80,7 @@ will be deleted if the tt(zftp) module is unloaded.
|
||||||
|
|
||||||
For example,
|
For example,
|
||||||
|
|
||||||
nofill(tt(zftp params ftp.elsewhere.xx juser '?'))
|
example(zftp params ftp.elsewhere.xx juser '?')
|
||||||
|
|
||||||
will store the host tt(ftp.elsewhere.xx) and the user tt(juser) and
|
will store the host tt(ftp.elsewhere.xx) and the user tt(juser) and
|
||||||
then prompt the user for the corresponding password.
|
then prompt the user for the corresponding password.
|
||||||
|
@ -89,8 +89,8 @@ This command may also be used to set up a transfer which then takes
|
||||||
place completely in the background, freeing tt(zftp) for concurrent
|
place completely in the background, freeing tt(zftp) for concurrent
|
||||||
foreground use. For example,
|
foreground use. For example,
|
||||||
|
|
||||||
nofill(tt(zftp params ftp.soreeyes.ca bubble squeak))
|
example(zftp params ftp.soreeyes.ca bubble squeak
|
||||||
nofill(tt(LPAR()zftp open; zftp get foo >bar; zftp close)tt(RPAR() &))
|
(zftp open; zftp get foo >bar; zftp close) &)
|
||||||
|
|
||||||
--- 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.
|
||||||
|
@ -110,7 +110,7 @@ supported on this system) is printed instead.
|
||||||
|
|
||||||
It is useful to put the code
|
It is useful to put the code
|
||||||
|
|
||||||
nofill(tt([[ -n $ZFTP_HOST ]] && zftp test))
|
example([[ -n $ZFTP_HOST ]] && zftp test)
|
||||||
|
|
||||||
into the shell function tt(precmd) for testing the connection before
|
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
|
every prompt. However, tt(zftp) will call tt(test) at the start of any
|
||||||
|
@ -209,7 +209,7 @@ item(tt(mkdir) var(directory))(
|
||||||
Create a new directory var(directory) on the server.
|
Create a new directory var(directory) on the server.
|
||||||
)
|
)
|
||||||
item(tt(rmdir) var(directory))(
|
item(tt(rmdir) var(directory))(
|
||||||
Delete the diretory var(directory) on the server.
|
Delete the directory var(directory) on the server.
|
||||||
)
|
)
|
||||||
item(tt(rename) var(old-name) var(new-name))(
|
item(tt(rename) var(old-name) var(new-name))(
|
||||||
Rename file var(old-name) to var(new-name) on the server.
|
Rename file var(old-name) to var(new-name) on the server.
|
||||||
|
@ -221,7 +221,7 @@ only need this if instructed by the server to use it.
|
||||||
item(tt(quote) var(args...))(
|
item(tt(quote) var(args...))(
|
||||||
Send the raw FTP command sequence to the server. You should be
|
Send the raw FTP command sequence to the server. You should be
|
||||||
familiar with the FTP command set as defined in RFC959 before doing
|
familiar with the FTP command set as defined in RFC959 before doing
|
||||||
this. Useful comands may include tt(STAT) and tt(HELP). Note also
|
this. Useful commands may include tt(STAT) and tt(HELP). Note also
|
||||||
the mechanism for returning messages as described for the variable
|
the mechanism for returning messages as described for the variable
|
||||||
tt(ZFTP_VERBOSE) below, in particular that all messages from the
|
tt(ZFTP_VERBOSE) below, in particular that all messages from the
|
||||||
control connection are sent to standard error.
|
control connection are sent to standard error.
|
||||||
|
@ -335,7 +335,7 @@ digit reply code is defined by RFC959 to correspond to:
|
||||||
|
|
||||||
startitem()
|
startitem()
|
||||||
item(1.)(
|
item(1.)(
|
||||||
A positive prelimnary reply.
|
A positive preliminary reply.
|
||||||
)
|
)
|
||||||
item(2.)(
|
item(2.)(
|
||||||
A positive completion reply.
|
A positive completion reply.
|
||||||
|
@ -442,7 +442,7 @@ until the next call to tt(zftp). Other status changes in subshells
|
||||||
will not be reflected by changes to the variables (but should
|
will not be reflected by changes to the variables (but should
|
||||||
be otherwise harmless).
|
be otherwise harmless).
|
||||||
|
|
||||||
On some operatings systems, the control connection is not valid after a
|
On some operating systems, the control connection is not valid after a
|
||||||
fork(), so that operations in subshells or on the left hand side of a
|
fork(), so that operations in subshells or on the left hand side of a
|
||||||
pipeline are not possible.
|
pipeline are not possible.
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ To assign an array value, use `tt(set -A) var(name) var(value) ...'.
|
||||||
findex(set, use of)
|
findex(set, use of)
|
||||||
The value of a parameter may also be assigned by writing:
|
The value of a parameter may also be assigned by writing:
|
||||||
|
|
||||||
nofill(var(name)tt(=)var(value))
|
indent(var(name)tt(=)var(value))
|
||||||
|
|
||||||
If the integer attribute, tt(-i), is set for var(name), the var(value)
|
If the integer attribute, tt(-i), is set for var(name), the var(value)
|
||||||
is subject to arithmetic evaluation. See noderef(Array Parameters)
|
is subject to arithmetic evaluation. See noderef(Array Parameters)
|
||||||
|
@ -38,19 +38,19 @@ texinode(Array Parameters)(Positional Parameters)()(Parameters)
|
||||||
sect(Array Parameters)
|
sect(Array Parameters)
|
||||||
The value of an array parameter may be assigned by writing:
|
The value of an array parameter may be assigned by writing:
|
||||||
|
|
||||||
nofill(var(name)tt(=LPAR())var(value) ...tt(RPAR()))
|
indent(var(name)tt(=LPAR())var(value) ...tt(RPAR()))
|
||||||
|
|
||||||
If no parameter var(name) exists, an ordinary array parameter is created.
|
If no parameter var(name) exists, an ordinary array parameter is created.
|
||||||
Associative arrays must be declared first, by `tt(typeset -A) var(name)'.
|
Associative arrays must be declared first, by `tt(typeset -A) var(name)'.
|
||||||
When var(name) refers to an associative array, the parenthesized list is
|
When var(name) refers to an associative array, the parenthesized list is
|
||||||
interpreted as alternating keys and values:
|
interpreted as alternating keys and values:
|
||||||
|
|
||||||
nofill(var(name)tt(=LPAR())var(key) var(value) ...tt(RPAR()))
|
indent(var(name)tt(=LPAR())var(key) var(value) ...tt(RPAR()))
|
||||||
|
|
||||||
Every var(key) must have a var(value) in this case. To create an empty
|
Every var(key) must have a var(value) in this case. To create an empty
|
||||||
array or associative array, use:
|
array or associative array, use:
|
||||||
|
|
||||||
nofill(var(name)tt(=LPAR()RPAR()))
|
indent(var(name)tt(=LPAR()RPAR()))
|
||||||
|
|
||||||
Individual elements of an array may be selected using a
|
Individual elements of an array may be selected using a
|
||||||
subscript. A subscript of the form `tt([)var(exp)tt(])'
|
subscript. A subscript of the form `tt([)var(exp)tt(])'
|
||||||
|
@ -59,6 +59,7 @@ an arithmetic expression which will be subject to arithmetic
|
||||||
expansion as if it were surrounded by `tt($LPAR()LPAR())...tt(RPAR()RPAR())'.
|
expansion as if it were surrounded by `tt($LPAR()LPAR())...tt(RPAR()RPAR())'.
|
||||||
The elements are numbered beginning with 1 unless the
|
The elements are numbered beginning with 1 unless the
|
||||||
tt(KSH_ARRAYS) option is set when they are numbered from zero.
|
tt(KSH_ARRAYS) option is set when they are numbered from zero.
|
||||||
|
cindex(subscripts)
|
||||||
pindex(KSH_ARRAYS, use of)
|
pindex(KSH_ARRAYS, use of)
|
||||||
|
|
||||||
The same subscripting syntax is used for associative arrays,
|
The same subscripting syntax is used for associative arrays,
|
||||||
|
@ -72,9 +73,8 @@ except when they appear within double quotes.
|
||||||
|
|
||||||
A subscript of the form `tt([)var(exp1)tt(,)var(exp2)tt(])'
|
A subscript of the form `tt([)var(exp1)tt(,)var(exp2)tt(])'
|
||||||
selects all elements in the range var(exp1) to var(exp2),
|
selects all elements in the range var(exp1) to var(exp2),
|
||||||
inclusive.
|
inclusive. (Associative arrays are unordered, and so do not support
|
||||||
(Associative arrays are unordered, and so do not support ranges.)
|
ranges.) If one of the subscripts evaluates to a negative number,
|
||||||
If one of the subscripts evaluates to a negative number,
|
|
||||||
say tt(-)var(n), then the var(n)th element from the end
|
say tt(-)var(n), then the var(n)th element from the end
|
||||||
of the array is used. Thus `tt($foo[-3])' is the third element
|
of the array is used. Thus `tt($foo[-3])' is the third element
|
||||||
from the end of the array tt(foo), and
|
from the end of the array tt(foo), and
|
||||||
|
@ -95,7 +95,7 @@ element or range is replaced by the expression on the right side. An
|
||||||
array (but not an associative array) may be created by assignment to a
|
array (but not an associative array) may be created by assignment to a
|
||||||
range or element. Arrays do not nest, so assigning a parenthesized list
|
range or element. Arrays do not nest, so assigning a parenthesized list
|
||||||
of values to an element or range changes the number of elements in the
|
of values to an element or range changes the number of elements in the
|
||||||
array, shifting the other elements to accomodate the new values. (This
|
array, shifting the other elements to accommodate the new values. (This
|
||||||
is not supported for associative arrays.)
|
is not supported for associative arrays.)
|
||||||
|
|
||||||
To delete an element of an ordinary array, assign `tt(LPAR()RPAR())' to
|
To delete an element of an ordinary array, assign `tt(LPAR()RPAR())' to
|
||||||
|
@ -180,7 +180,7 @@ values) any of the positions from 1 to var(n) that do not already have
|
||||||
values. Note that, because the positional parameters form an array, an
|
values. Note that, because the positional parameters form an array, an
|
||||||
array assignment of the form `var(n)tt(=LPAR())var(value) ...tt(RPAR())' is
|
array assignment of the form `var(n)tt(=LPAR())var(value) ...tt(RPAR())' is
|
||||||
allowed, and has the effect of shifting all the values at positions greater
|
allowed, and has the effect of shifting all the values at positions greater
|
||||||
than var(n) by as many positions as necessary to accomodate the new values.
|
than var(n) by as many positions as necessary to accommodate the new values.
|
||||||
|
|
||||||
texinode(Local Parameters)(Parameters Set By The Shell)(Positional Parameters)(Parameters)
|
texinode(Local Parameters)(Parameters Set By The Shell)(Positional Parameters)(Parameters)
|
||||||
sect(Local Parameters)
|
sect(Local Parameters)
|
||||||
|
|
|
@ -107,7 +107,7 @@ The shell evaluates each redirection in terms of the
|
||||||
association at the time of evaluation.
|
association at the time of evaluation.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
nofill(... tt(1>)var(fname) tt(2>&1))
|
indent(... tt(1>)var(fname) tt(2>&1))
|
||||||
|
|
||||||
first associates file descriptor 1 with file var(fname).
|
first associates file descriptor 1 with file var(fname).
|
||||||
It then associates file descriptor 2 with the file associated with file
|
It then associates file descriptor 2 with the file associated with file
|
||||||
|
@ -123,12 +123,12 @@ the shell opens the file descriptor as a pipe to a process that copies
|
||||||
its input to all the specified outputs, similar to bf(tee),
|
its input to all the specified outputs, similar to bf(tee),
|
||||||
provided the tt(MULTIOS) option is set. Thus:
|
provided the tt(MULTIOS) option is set. Thus:
|
||||||
|
|
||||||
nofill(tt(date >foo >bar))
|
example(date >foo >bar)
|
||||||
|
|
||||||
writes the date to two files, named `tt(foo)' and `tt(bar)'.
|
writes the date to two files, named `tt(foo)' and `tt(bar)'.
|
||||||
Note that a pipe is an implicit redirection; thus
|
Note that a pipe is an implicit redirection; thus
|
||||||
|
|
||||||
nofill(tt(date >foo | cat))
|
example(date >foo | cat)
|
||||||
|
|
||||||
writes the date to the file `tt(foo)', and also pipes it to cat.
|
writes the date to the file `tt(foo)', and also pipes it to cat.
|
||||||
|
|
||||||
|
@ -136,14 +136,14 @@ If the tt(MULTIOS)
|
||||||
option is set, the word after a redirection operator is also subjected
|
option is set, the word after a redirection operator is also subjected
|
||||||
to filename generation (globbing). Thus
|
to filename generation (globbing). Thus
|
||||||
|
|
||||||
nofill(tt(: > *))
|
example(: > *)
|
||||||
|
|
||||||
will truncate all files in the current directory,
|
will truncate all files in the current directory,
|
||||||
assuming there's at least one. (Without the tt(MULTIOS)
|
assuming there's at least one. (Without the tt(MULTIOS)
|
||||||
option, it would create an empty file called `tt(*)'.)
|
option, it would create an empty file called `tt(*)'.)
|
||||||
Similarly, you can do
|
Similarly, you can do
|
||||||
|
|
||||||
nofill(tt(echo exit 0 >> *.sh))
|
example(echo exit 0 >> *.sh)
|
||||||
|
|
||||||
If the user tries to open a file descriptor for reading more than once,
|
If the user tries to open a file descriptor for reading more than once,
|
||||||
the shell opens the file descriptor as a pipe to a process that copies
|
the shell opens the file descriptor as a pipe to a process that copies
|
||||||
|
@ -151,17 +151,17 @@ all the specified inputs to its output in the order
|
||||||
specified, similar to bf(cat),
|
specified, similar to bf(cat),
|
||||||
provided the tt(MULTIOS) option is set. Thus
|
provided the tt(MULTIOS) option is set. Thus
|
||||||
|
|
||||||
nofill(tt(sort <foo <fubar))
|
example(sort <foo <fubar)
|
||||||
|
|
||||||
or even
|
or even
|
||||||
|
|
||||||
nofill(tt(sort <f{oo,ubar}))
|
example(sort <f{oo,ubar})
|
||||||
|
|
||||||
is equivalent to `tt(cat foo fubar | sort)'.
|
is equivalent to `tt(cat foo fubar | sort)'.
|
||||||
|
|
||||||
Note that a pipe is an implicit redirection; thus
|
Note that a pipe is an implicit redirection; thus
|
||||||
|
|
||||||
nofill(tt(cat bar | sort <foo))
|
example(cat bar | sort <foo)
|
||||||
|
|
||||||
is equivalent to `tt(cat bar foo | sort)' (note the order of the inputs).
|
is equivalent to `tt(cat bar foo | sort)' (note the order of the inputs).
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ If the tt(MULTIOS) option is em(un)set,
|
||||||
each redirection replaces the previous redirection for that file descriptor.
|
each redirection replaces the previous redirection for that file descriptor.
|
||||||
However, all files redirected to are actually opened, so
|
However, all files redirected to are actually opened, so
|
||||||
|
|
||||||
nofill(tt(echo foo > bar > baz))
|
example(echo foo > bar > baz)
|
||||||
|
|
||||||
when tt(MULTIOS) is unset will truncate bar, and write `tt(foo)' into baz.
|
when tt(MULTIOS) is unset will truncate bar, and write `tt(foo)' into baz.
|
||||||
|
|
||||||
|
@ -178,6 +178,6 @@ and zero or more parameter assignments, but no command name,
|
||||||
the command named in the shell variable tt(READNULLCMD) is assumed.
|
the command named in the shell variable tt(READNULLCMD) is assumed.
|
||||||
(If tt(READNULLCMD) is empty or not set, `tt(cat)' is used.) Thus
|
(If tt(READNULLCMD) is empty or not set, `tt(cat)' is used.) Thus
|
||||||
|
|
||||||
nofill(tt(< file))
|
example(< file)
|
||||||
|
|
||||||
copies the contents of tt(file) to the standard output.
|
copies the contents of tt(file) to the standard output.
|
||||||
|
|
|
@ -8,7 +8,7 @@ distribution as an interface to the tt(zftp) builtin command, allowing you
|
||||||
to perform FTP operations from the shell command line or within functions
|
to perform FTP operations from the shell command line or within functions
|
||||||
or scripts. The interface is similar to a traditional FTP client (e.g. the
|
or scripts. The interface is similar to a traditional FTP client (e.g. the
|
||||||
tt(ftp) command itself, see manref(ftp)(1)), but as it is entirely done
|
tt(ftp) command itself, see manref(ftp)(1)), but as it is entirely done
|
||||||
within the shell all the familar completion, editing and globbing features,
|
within the shell all the familiar completion, editing and globbing features,
|
||||||
and so on, are present, and macros are particularly simple to write as they
|
and so on, are present, and macros are particularly simple to write as they
|
||||||
are just ordinary shell functions.
|
are just ordinary shell functions.
|
||||||
|
|
||||||
|
@ -45,21 +45,22 @@ You should make sure all the functions from the tt(Functions/Zftp)
|
||||||
directory of the source distribution are available; they all begin with the
|
directory of the source distribution are available; they all begin with the
|
||||||
two letters `tt(zf)'. They may already have been installed on your system;
|
two letters `tt(zf)'. They may already have been installed on your system;
|
||||||
otherwise, you will need to find them and copy them. The directory should
|
otherwise, you will need to find them and copy them. The directory should
|
||||||
appear as one of the elements of the tt($fpath) array, and the functions
|
appear as one of the elements of the tt($fpath) array (this should already
|
||||||
should be autoloaded. Finally, to initialise the use of the system you
|
be the case if they were installed), and at least the function tt(zfinit)
|
||||||
need to call the tt(zfinit) function. The following code in your
|
should be autoloaded; it will autoload the rest. Finally, to initialise
|
||||||
tt(.zshrc) will arrange for this; assume the functions are stored in the
|
the use of the system you need to call the tt(zfinit) function. The
|
||||||
directory tt(~/myfns):
|
following code in your tt(.zshrc) will arrange for this; assume the
|
||||||
|
functions are stored in the directory tt(~/myfns):
|
||||||
|
|
||||||
tt(indent(
|
example(fpath=(~/myfns $fpath)
|
||||||
nofill(fpath=(~/myfns $fpath))
|
autoload zfinit
|
||||||
nofill(autoload ~/myfns/zf*(:t))
|
zfinit)
|
||||||
nofill(zfinit)
|
|
||||||
))
|
|
||||||
|
|
||||||
Note that tt(zfinit) assumes you are using the tt(zmodload) method to
|
Note that tt(zfinit) assumes you are using the tt(zmodload) method to
|
||||||
load the tt(zftp) command. If it is already built into the shell, change
|
load the tt(zftp) command. If it is already built into the shell, change
|
||||||
tt(zfinit) to tt(zfinit -n).
|
tt(zfinit) to tt(zfinit -n). It is helpful (though not essential) if the
|
||||||
|
call to tt(zfinit) appears after any code to initialise the new completion
|
||||||
|
system, else unnecessary tt(compctl) commands will be given.
|
||||||
|
|
||||||
texinode(Zftp Functions)(Miscellaneous Features)(Installation)(Zftp Function System)
|
texinode(Zftp Functions)(Miscellaneous Features)(Installation)(Zftp Function System)
|
||||||
sect(Functions)
|
sect(Functions)
|
||||||
|
@ -115,7 +116,7 @@ have many of the features of the shell builtin tt(cd).
|
||||||
|
|
||||||
In the first form with var(dir) present, change to the directory var(dir).
|
In the first form with var(dir) present, change to the directory var(dir).
|
||||||
The command `tt(zfcd ..)' is treated specially, so is guaranteed to work on
|
The command `tt(zfcd ..)' is treated specially, so is guaranteed to work on
|
||||||
non-UNIX servers (note this is handled internall by tt(zftp)). If var(dir)
|
non-UNIX servers (note this is handled internally by tt(zftp)). If var(dir)
|
||||||
is omitted, has the effect of `tt(zfcd ~)'.
|
is omitted, has the effect of `tt(zfcd ~)'.
|
||||||
|
|
||||||
The second form changes to the directory previously current.
|
The second form changes to the directory previously current.
|
||||||
|
@ -274,13 +275,48 @@ then tt(zfpcp) will retry using the second form.
|
||||||
)
|
)
|
||||||
enditem()
|
enditem()
|
||||||
|
|
||||||
subsect(Closing the connectino)
|
subsect(Closing the connection)
|
||||||
startitem()
|
startitem()
|
||||||
item(tt(zfclose))(
|
item(tt(zfclose))(
|
||||||
Close the connection.
|
Close the connection.
|
||||||
)
|
)
|
||||||
enditem()
|
enditem()
|
||||||
|
|
||||||
|
subsect(Bookmarks)
|
||||||
|
The two functions tt(zfmark) and tt(zfgoto) allow you to `bookmark' the
|
||||||
|
present location (host, user and directory) of the current FTP connection
|
||||||
|
for later use. The file to be used for storing and retrieving bookmarks is
|
||||||
|
given by the parameter tt($ZFTP_BMFILE); if not set when one of the two
|
||||||
|
functions is called, it will be set to the file tt(.zfbfmarks) in the
|
||||||
|
directory where your zsh startup files live (usually tt(~)).
|
||||||
|
|
||||||
|
startitem()
|
||||||
|
item(tt(zfmark [ )var(bookmark)tt( ]))(
|
||||||
|
If given an argument, mark the current host, user and directory under the
|
||||||
|
name var(bookmark) for later use by tt(zfgoto). If there is no connection
|
||||||
|
open, use the values for the last connection immediately before it was
|
||||||
|
closed; it is an error if there is none. Any existing bookmark
|
||||||
|
under the same name will be silently replaced.
|
||||||
|
|
||||||
|
If not given an argument, list the existing bookmarks and the points to
|
||||||
|
which they refer in the form var(user)tt(@)var(host)tt(:)var(directory).
|
||||||
|
)
|
||||||
|
item(tt(zfgoto [ -n ] )var(bookmark))(
|
||||||
|
Return to the location given by var(bookmark), as previously set by
|
||||||
|
tt(zfmark). If the location has user `tt(ftp)' or `tt(anonymous)', open
|
||||||
|
the connection with tt(zfanon), so that no password is required. If the
|
||||||
|
user and host parameters match those currently stored, those will be used,
|
||||||
|
and again no password is required. Otherwise a password will be prompted
|
||||||
|
for.
|
||||||
|
|
||||||
|
With the option tt(-n), the bookmark is taken to be a nickname stored by
|
||||||
|
the tt(ncftp) program in its bookmark file, which is assumed to be
|
||||||
|
tt(~/.ncftp/bookmarks). The function works identically in other ways.
|
||||||
|
Note that there is no mechanism for adding or modifying tt(ncftp) bookmarks
|
||||||
|
from the zftp functions.
|
||||||
|
)
|
||||||
|
enditem()
|
||||||
|
|
||||||
subsect(Other functions)
|
subsect(Other functions)
|
||||||
Mostly, these functions will not be called directly (apart from
|
Mostly, these functions will not be called directly (apart from
|
||||||
tt(zfinit)), but are described here for completeness. You may wish to
|
tt(zfinit)), but are described here for completeness. You may wish to
|
||||||
|
@ -288,7 +324,7 @@ alter tt(zftp_chpwd) and tt(zftp_progress), in particular.
|
||||||
|
|
||||||
startitem()
|
startitem()
|
||||||
item(tt(zfinit [ -n ]))(
|
item(tt(zfinit [ -n ]))(
|
||||||
As decribed above, this is used to initialise the zftp function system.
|
As described above, this is used to initialise the zftp function system.
|
||||||
The tt(-n) option should be used if the zftp command is already built into
|
The tt(-n) option should be used if the zftp command is already built into
|
||||||
the shell.
|
the shell.
|
||||||
)
|
)
|
||||||
|
@ -320,7 +356,7 @@ var(prefix) and var(suffix) set appropriately.
|
||||||
item(tt(zfrglob var(varname)))(
|
item(tt(zfrglob var(varname)))(
|
||||||
Perform remote globbing, as describes in more detail below. var(varname)
|
Perform remote globbing, as describes in more detail below. var(varname)
|
||||||
is the name of a variable containing the pattern to be expanded; if there
|
is the name of a variable containing the pattern to be expanded; if there
|
||||||
were any matches, the same variable will be set to the exanded set of
|
were any matches, the same variable will be set to the expanded set of
|
||||||
filenames on return.
|
filenames on return.
|
||||||
)
|
)
|
||||||
item(tt(zfrtime var(lfile) var(rfile) [ var(time) ]))(
|
item(tt(zfrtime var(lfile) var(rfile) [ var(time) ]))(
|
||||||
|
@ -339,15 +375,13 @@ tt(xterm) or tt(sun-cmd) terminal emulator to reflect the local and remote
|
||||||
hostnames and current directories. It works best when combined with the
|
hostnames and current directories. It works best when combined with the
|
||||||
function tt(chpwd). In particular, a function of the form
|
function tt(chpwd). In particular, a function of the form
|
||||||
|
|
||||||
tt(indent(
|
example(chpwd() {
|
||||||
nofill(chpwd() {)
|
if [[ -n $ZFTP_USER ]]; then
|
||||||
nofill( if [[ -n $ZFTP_USER ]]; then)
|
zftp_chpwd
|
||||||
nofill( zftp_chpwd)
|
else
|
||||||
nofill( else)
|
# usual chpwd e.g put host:directory in title bar
|
||||||
nofill( # usual chpwd e.g put host:directory in title bar)
|
fi
|
||||||
nofill( fi)
|
})
|
||||||
nofill(})
|
|
||||||
))
|
|
||||||
|
|
||||||
fits in well.
|
fits in well.
|
||||||
)
|
)
|
||||||
|
@ -378,7 +412,7 @@ remote server does not support the UNIX directory semantics, directory
|
||||||
handling is problematic and it is recommended that globbing only be used
|
handling is problematic and it is recommended that globbing only be used
|
||||||
within the current directory. The list of files in the current directory,
|
within the current directory. The list of files in the current directory,
|
||||||
if retrieved, will be cached, so that subsequent globs in the same
|
if retrieved, will be cached, so that subsequent globs in the same
|
||||||
directory without an interventing tt(zfcd) are fast.
|
directory without an intervening tt(zfcd) are fast.
|
||||||
|
|
||||||
If the variable tt($zfrglob) is set to a non-zero length, globbing is
|
If the variable tt($zfrglob) is set to a non-zero length, globbing is
|
||||||
instead performed on the remote host: the server is asked for a list of
|
instead performed on the remote host: the server is asked for a list of
|
||||||
|
@ -415,10 +449,8 @@ never close the connection automatically.
|
||||||
Information about the previous connection is given by the tt(zfstat)
|
Information about the previous connection is given by the tt(zfstat)
|
||||||
function. So, for example, if that reports:
|
function. So, for example, if that reports:
|
||||||
|
|
||||||
tt(indent(
|
example(Not connected.
|
||||||
nofill(Not connected.)
|
Last session: ftp.bar.com:/pub/textfiles)
|
||||||
nofill(Last session: ftp.bar.com:/pub/textfiles)
|
|
||||||
))
|
|
||||||
|
|
||||||
then the command tt(zfget file.txt) will attempt to reopen a connection to
|
then the command tt(zfget file.txt) will attempt to reopen a connection to
|
||||||
tt(ftp.bar.com), retrieve the file tt(/pub/textfiles/file.txt), and
|
tt(ftp.bar.com), retrieve the file tt(/pub/textfiles/file.txt), and
|
||||||
|
@ -427,9 +459,9 @@ will open the connection in the directory tt(/pub) and leave it open.
|
||||||
|
|
||||||
subsect(Completion)
|
subsect(Completion)
|
||||||
|
|
||||||
Completion of remote files and directories is supported. The older,
|
Completion of remote files, directories and bookmarks is supported. The
|
||||||
tt(compctl)-style completion is defined when tt(zfinit) is called; support
|
older, tt(compctl)-style completion is defined when tt(zfinit) is called;
|
||||||
for the new widget-based completion system is provided in the function
|
support for the new widget-based completion system is provided in the
|
||||||
tt(Completion/Builtins/_zftp), which should be installed with the other
|
function tt(Completion/Builtins/_zftp), which should be installed with the
|
||||||
functions of the completion system and hence should automatically be
|
other functions of the completion system and hence should automatically be
|
||||||
available.
|
available.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
texinode(Zsh Line Editor)(Programmable Completion)(Shell Builtin Commands)(Top)
|
texinode(Zsh Line Editor)(Programmable Completion Using compctl)(Shell Builtin Commands)(Top)
|
||||||
chapter(Zsh Line Editor)
|
chapter(Zsh Line Editor)
|
||||||
cindex(line editor)
|
cindex(line editor)
|
||||||
cindex(editor, line)
|
cindex(editor, line)
|
||||||
|
@ -83,7 +83,7 @@ simply to perform some small action. The ZLE commands that key sequences
|
||||||
in keymaps are bound to are in fact widgets. Widgets can be user-defined
|
in keymaps are bound to are in fact widgets. Widgets can be user-defined
|
||||||
or built in.
|
or built in.
|
||||||
|
|
||||||
There are 162 standard widgets built in to ZLE (see sectref(Standard Widgets)).
|
There are 162 standard widgets built in to ZLE (see Standard Widgets below).
|
||||||
Other built-in widgets can be defined by other modules (see
|
Other built-in widgets can be defined by other modules (see
|
||||||
ifzman(zmanref(zshmodules))\
|
ifzman(zmanref(zshmodules))\
|
||||||
ifnzman(noderef(Zsh Modules))\
|
ifnzman(noderef(Zsh Modules))\
|
||||||
|
@ -157,7 +157,7 @@ vindex(keys)
|
||||||
item(tt(keys) (array))(
|
item(tt(keys) (array))(
|
||||||
The keys typed to invoke this widget, one element per
|
The keys typed to invoke this widget, one element per
|
||||||
key. Control-keys are reported with a leading `tt(^)', as in `tt(^A)',
|
key. Control-keys are reported with a leading `tt(^)', as in `tt(^A)',
|
||||||
and meta-keys are repoted with a leading `tt(M-)', as in `tt(M-a)' and
|
and meta-keys are reported with a leading `tt(M-)', as in `tt(M-a)' and
|
||||||
`tt(M-^A)'.
|
`tt(M-^A)'.
|
||||||
)
|
)
|
||||||
vindex(NUMERIC)
|
vindex(NUMERIC)
|
||||||
|
|
10
Doc/zman.yo
10
Doc/zman.yo
|
@ -162,6 +162,12 @@ def(itemiz)(1)(\
|
||||||
|
|
||||||
COMMENT(--- special effects ---)
|
COMMENT(--- special effects ---)
|
||||||
|
|
||||||
|
def(example)(1)(\
|
||||||
|
NOTRANS(.RS)NL()NOTRANS(.nf)NL()\
|
||||||
|
NOTRANS(\fB)ARG1NOTRANS(\fP)\
|
||||||
|
NL()NOTRANS(.fi)NL()NOTRANS(.RE)\
|
||||||
|
)
|
||||||
|
|
||||||
def(nofill)(1)(\
|
def(nofill)(1)(\
|
||||||
NOTRANS(.nf)NL()\
|
NOTRANS(.nf)NL()\
|
||||||
ARG1\
|
ARG1\
|
||||||
|
@ -169,9 +175,9 @@ def(nofill)(1)(\
|
||||||
)
|
)
|
||||||
|
|
||||||
def(indent)(1)(\
|
def(indent)(1)(\
|
||||||
NOTRANS(.RS)\
|
NOTRANS(.RS)NL()NOTRANS(.nf)NL()\
|
||||||
ARG1\
|
ARG1\
|
||||||
NOTRANS(.RE)\
|
NL()NOTRANS(.fi)NL()NOTRANS(.RE)\
|
||||||
)
|
)
|
||||||
|
|
||||||
COMMENT(--- hyperlink menus ---)
|
COMMENT(--- hyperlink menus ---)
|
||||||
|
|
|
@ -17,7 +17,7 @@ def(ifzshall)(1)()\
|
||||||
)\
|
)\
|
||||||
ifztexi(\
|
ifztexi(\
|
||||||
texinfo(zsh.info)(zsh)
|
texinfo(zsh.info)(zsh)
|
||||||
NOTRANS(@setchapternewpage odd
|
NOTRANS(@setchapternewpage off
|
||||||
@iftex
|
@iftex
|
||||||
@finalout
|
@finalout
|
||||||
@afourpaper
|
@afourpaper
|
||||||
|
|
12
Doc/ztexi.yo
12
Doc/ztexi.yo
|
@ -11,7 +11,7 @@ def(CMT)(0)(NOTRANS(@c))
|
||||||
|
|
||||||
ATEXIT(\
|
ATEXIT(\
|
||||||
NL()\
|
NL()\
|
||||||
NOTRANS(@setchapternewpage odd)NL()\
|
NOTRANS(@setchapternewpage off)NL()\
|
||||||
NOTRANS(@contents)NL()\
|
NOTRANS(@contents)NL()\
|
||||||
NOTRANS(@bye)NL()\
|
NOTRANS(@bye)NL()\
|
||||||
)
|
)
|
||||||
|
@ -207,8 +207,16 @@ def(nofill)(1)(\
|
||||||
USECHARTABLE(standard)\
|
USECHARTABLE(standard)\
|
||||||
)
|
)
|
||||||
|
|
||||||
def(indent)(1)(\
|
def(example)(1)(\
|
||||||
|
NOTRANS(@example)NL()\
|
||||||
ARG1\
|
ARG1\
|
||||||
|
NL()NOTRANS(@end example)\
|
||||||
|
)
|
||||||
|
|
||||||
|
def(indent)(1)(\
|
||||||
|
NOTRANS(@display)NL()\
|
||||||
|
ARG1\
|
||||||
|
NL()NOTRANS(@end display)\
|
||||||
)
|
)
|
||||||
|
|
||||||
COMMENT(--- hyperlink menus ---)
|
COMMENT(--- hyperlink menus ---)
|
||||||
|
|
10
Etc/MACHINES
10
Etc/MACHINES
|
@ -38,6 +38,10 @@ DEC: OSF/1 1.2, 1.3, 2.0, 3.*, DEC Unix 4.* (Alpha)
|
||||||
This problem is not related to zsh. If you have such problems,
|
This problem is not related to zsh. If you have such problems,
|
||||||
remove the bogus strip and use /bin/strip instead.
|
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:
|
||||||
|
DLLD=gcc LDFLAGS='-g -rpath <path-to-.so-files>' ./configure ...
|
||||||
|
|
||||||
FreeBSD: FreeBSD 2.2.7 [3.1.4]
|
FreeBSD: FreeBSD 2.2.7 [3.1.4]
|
||||||
Should build `out-of-the-box'.
|
Should build `out-of-the-box'.
|
||||||
|
|
||||||
|
@ -102,5 +106,7 @@ Sun: Solaris 2.*
|
||||||
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
|
Under Solaris 2.7, problems have been reported with dynamically
|
||||||
--enable-dynamic currently does not work.
|
loaded library support using --enable-dynamic. However, other
|
||||||
|
users have been successful with the standard Sun compiler.
|
||||||
|
More details of any problems would be appreciated.
|
||||||
|
|
|
@ -55,7 +55,14 @@ install.fns:
|
||||||
$(sdir_top)/mkinstalldirs $(fndir) || exit 1; \
|
$(sdir_top)/mkinstalldirs $(fndir) || exit 1; \
|
||||||
for file in $(FUNCTIONS_INSTALL); do \
|
for file in $(FUNCTIONS_INSTALL); do \
|
||||||
if test -f $$file; then \
|
if test -f $$file; then \
|
||||||
$(INSTALL_DATA) $$file $(fndir) || exit 1; \
|
if test x$(FUNCTIONS_SUBDIRS) != x -a \
|
||||||
|
x$(FUNCTIONS_SUBDIRS) != xno; then \
|
||||||
|
subdir="`echo $$file | sed -e 's%/.*%%'`"; \
|
||||||
|
$(sdir_top)/mkinstalldirs $(fndir)/$$subdir || exit 1; \
|
||||||
|
$(INSTALL_DATA) $$file $(fndir)/$$subdir || exit 1; \
|
||||||
|
else \
|
||||||
|
$(INSTALL_DATA) $$file $(fndir) || exit 1; \
|
||||||
|
fi; \
|
||||||
fi; \
|
fi; \
|
||||||
done; \
|
done; \
|
||||||
fi; \
|
fi; \
|
||||||
|
@ -65,7 +72,12 @@ uninstall.fns:
|
||||||
if test x$(fndir) != x && test x$(fndir) != xno; then \
|
if test x$(fndir) != x && test x$(fndir) != xno; then \
|
||||||
for file in $(FUNCTIONS_INSTALL); do \
|
for file in $(FUNCTIONS_INSTALL); do \
|
||||||
if test -f $$file; then \
|
if test -f $$file; then \
|
||||||
rm -f "$(fndir)/`echo $$file | sed -e 's%^.*/%%'`"; \
|
if test x$(FUNCTIONS_SUBDIRS) != x -a \
|
||||||
|
x$(FUNCTIONS_SUBDIRS) != xno; then \
|
||||||
|
rm -f $(fndir)/$$file; \
|
||||||
|
else \
|
||||||
|
rm -f "$(fndir)/`echo $$file | sed -e 's%^.*/%%'`"; \
|
||||||
|
fi; \
|
||||||
fi; \
|
fi; \
|
||||||
done; \
|
done; \
|
||||||
fi; \
|
fi; \
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
DISTFILES_SRC='
|
DISTFILES_SRC='
|
||||||
.distfiles
|
.distfiles
|
||||||
zfanon zfautocheck zfcd zfcd_match zfcget zfclose zfcput zfdir
|
zfanon zfautocheck zfcd zfcd_match zfcget zfclose zfcput zfdir
|
||||||
zfgcp zfget zfget_match zfhere zfinit zfls zfopen zfparams
|
zfgcp zfget zfget_match zfgoto zfhere zfinit zfls zfmark zfopen zfparams
|
||||||
zfpcp zfput zfrglob zfrtime zfstat zftp_chpwd zftp_progress
|
zfpcp zfput zfrglob zfrtime zfstat zftp_chpwd zftp_progress
|
||||||
zftype zfuget zfuput
|
zftype zfuget zfuput
|
||||||
'
|
'
|
||||||
|
|
0
Functions/Zftp/zfgoto
Normal file
0
Functions/Zftp/zfgoto
Normal file
|
@ -1,3 +1,5 @@
|
||||||
|
emulate -L zsh
|
||||||
|
|
||||||
[[ $1 = -n ]] || zmodload -ia zftp
|
[[ $1 = -n ]] || zmodload -ia zftp
|
||||||
|
|
||||||
alias zfcd='noglob zfcd'
|
alias zfcd='noglob zfcd'
|
||||||
|
@ -6,6 +8,11 @@ alias zfls='noglob zfls'
|
||||||
alias zfdir='noglob zfdir'
|
alias zfdir='noglob zfdir'
|
||||||
alias zfuget='noglob zfuget'
|
alias zfuget='noglob zfuget'
|
||||||
|
|
||||||
|
autoload -U zfanon zfautocheck zfcd zfcd_match zfcget zfclose zfcput
|
||||||
|
autoload -U zfdir zfgcp zfget zfget_match zfgoto zfhere zfinit zfls
|
||||||
|
autoload -U zfmark zfopen zfparams zfpcp zfput zfrglob zfrtime zfstat
|
||||||
|
autoload -U zftp_chpwd zftp_progress zftype zfuget zfuput
|
||||||
|
|
||||||
# only way of getting that noglob out of the way: this is unnecessary with
|
# only way of getting that noglob out of the way: this is unnecessary with
|
||||||
# widget-based completion and can be commented out.
|
# widget-based completion and can be commented out.
|
||||||
setopt completealiases
|
setopt completealiases
|
||||||
|
@ -14,7 +21,7 @@ setopt completealiases
|
||||||
# zftp completions: only use these if new-style completion is not
|
# zftp completions: only use these if new-style completion is not
|
||||||
# active.
|
# active.
|
||||||
#
|
#
|
||||||
if [[ ${#patcomps} -eq 0 || ${patcomps[(i)zf*]} -gt ${#patcomps} ]]; then
|
if [[ ${#_patcomps} -eq 0 || ${_patcomps[(i)zf*]} -gt ${#_patcomps} ]]; then
|
||||||
compctl -f -x 'p[1]' \
|
compctl -f -x 'p[1]' \
|
||||||
-k '(open params user login type ascii binary mode put putat
|
-k '(open params user login type ascii binary mode put putat
|
||||||
get getat append appendat ls dir local remote mkdir rmdir delete
|
get getat append appendat ls dir local remote mkdir rmdir delete
|
||||||
|
@ -25,4 +32,9 @@ if [[ ${#patcomps} -eq 0 || ${patcomps[(i)zf*]} -gt ${#patcomps} ]]; then
|
||||||
compctl -K zfcd_match -S/ -q zfcd zfdir zfls
|
compctl -K zfcd_match -S/ -q zfcd zfdir zfls
|
||||||
compctl -K zfget_match zfget zfgcp zfuget zfcget
|
compctl -K zfget_match zfget zfgcp zfuget zfcget
|
||||||
compctl -k hosts zfanon zfopen zfparams
|
compctl -k hosts zfanon zfopen zfparams
|
||||||
|
compctl -s \
|
||||||
|
'$(awk '\''{print $1}'\'' ${ZFTP_BMFILE:-${ZDOTDIR:-$HOME}/.zfbkmarks})' \
|
||||||
|
-x 'W[1,-*n*]' \
|
||||||
|
-s '$(awk -F, '\''NR > 2 { print $1 }'\'' ~/.ncftp/bookmarks)' -- \
|
||||||
|
zfgoto zfmark
|
||||||
fi
|
fi
|
||||||
|
|
0
Functions/Zftp/zfmark
Normal file
0
Functions/Zftp/zfmark
Normal file
|
@ -24,6 +24,7 @@ if [[ -z $ZFTP_USER ]]; then
|
||||||
else
|
else
|
||||||
[[ -n $ZFTP_PWD ]] && zflastdir=$ZFTP_PWD
|
[[ -n $ZFTP_PWD ]] && zflastdir=$ZFTP_PWD
|
||||||
zflastsession="$ZFTP_HOST:$ZFTP_PWD"
|
zflastsession="$ZFTP_HOST:$ZFTP_PWD"
|
||||||
|
zflastuser="$ZFTP_USER"
|
||||||
local args
|
local args
|
||||||
if [[ -t 1 && -t 2 ]]; then
|
if [[ -t 1 && -t 2 ]]; then
|
||||||
local str=$zflastsession
|
local str=$zflastsession
|
||||||
|
|
24
INSTALL
24
INSTALL
|
@ -220,11 +220,12 @@ turn off both installation of functions and the setting of a default value
|
||||||
for $fpath/$FPATH.
|
for $fpath/$FPATH.
|
||||||
|
|
||||||
You can control the functions which get installed by setting
|
You can control the functions which get installed by setting
|
||||||
FUNCTIONS_INSTALL, either when running configure or when running `make
|
FUNCTIONS_INSTALL, either when running configure (e.g.
|
||||||
install' or `make install.fns'. It includes a list of files relative to
|
`FUNCTIONS_INSTALL="..." configure ...') or when running `make install' or
|
||||||
either the Completion or Functions subdirectories. By default, all the
|
`make install.fns'. It includes a list of files relative to either the
|
||||||
functions for the Completion system will be installed (see the zshcompsys
|
Completion or Functions subdirectories. By default, all the functions for
|
||||||
manual page), i.e.
|
the Completion system will be installed (see the zshcompsys manual page),
|
||||||
|
i.e.
|
||||||
FUNCTIONS_INSTALL='Core/* Base/* Builtins/* User/* Commands/*'
|
FUNCTIONS_INSTALL='Core/* Base/* Builtins/* User/* Commands/*'
|
||||||
and if the --enable-dynamic option was given, the functions in
|
and if the --enable-dynamic option was given, the functions in
|
||||||
Functions/Zftp, which require the zftp module to be available (see the
|
Functions/Zftp, which require the zftp module to be available (see the
|
||||||
|
@ -233,6 +234,11 @@ miscellaneous functions with documentation in comments; the complete set
|
||||||
of functions can be installed with
|
of functions can be installed with
|
||||||
FUNCTIONS_INSTALL='Core/* Base/* Builtins/* User/* Commands/* Misc/* Zftp/*'
|
FUNCTIONS_INSTALL='Core/* Base/* Builtins/* User/* Commands/* Misc/* Zftp/*'
|
||||||
|
|
||||||
|
You can also set --enable-function-subdirs to allow shell
|
||||||
|
functions to be installed into subdirectories of the function directory,
|
||||||
|
i.e. `Core/*' files will be installed into `FNDIR/Core', and so on.
|
||||||
|
This also initialises $fpath/$FPATH appropriately.
|
||||||
|
|
||||||
Support for large files and integers
|
Support for large files and integers
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
|
@ -257,6 +263,11 @@ type; it does not require that support for large files is actually
|
||||||
enabled. Hence you might consider using --enable-lfs on any 32-bit system
|
enabled. Hence you might consider using --enable-lfs on any 32-bit system
|
||||||
with a suitable compiler such as gcc.
|
with a suitable compiler such as gcc.
|
||||||
|
|
||||||
|
Also note that if `configure' finds out that either of the types off_t or
|
||||||
|
ino_t are 64-bit quantities, but that long integers are only 32 bits, all
|
||||||
|
the above will be enabled automatically. This is necessary to ensure
|
||||||
|
correct handling of these types.
|
||||||
|
|
||||||
None of this is relevant for 64-bit systems; zsh should compile and run
|
None of this is relevant for 64-bit systems; zsh should compile and run
|
||||||
without problems if (sizeof(long) == 8).
|
without problems if (sizeof(long) == 8).
|
||||||
|
|
||||||
|
@ -300,6 +311,7 @@ Features:
|
||||||
zlogin=pathname # the full pathname of the global zlogin script
|
zlogin=pathname # the full pathname of the global zlogin script
|
||||||
zprofile=pathname # the full pathname of the global zprofile script
|
zprofile=pathname # the full pathname of the global zprofile script
|
||||||
zlogout=pathname # the full pathname of the global zlogout script
|
zlogout=pathname # the full pathname of the global zlogout script
|
||||||
fns=directory # the directory where shell functions will go
|
fndir=directory # the directory where shell functions will go
|
||||||
|
function-subdirs # if functions will be installed into subdirectories
|
||||||
dynamic # allow dynamically loaded binary modules
|
dynamic # allow dynamically loaded binary modules
|
||||||
lfs # allow configure check for large files
|
lfs # allow configure check for large files
|
||||||
|
|
|
@ -222,8 +222,21 @@ printulimit(int lim, int hard, int head)
|
||||||
/* display the limit */
|
/* display the limit */
|
||||||
if (limit == RLIM_INFINITY)
|
if (limit == RLIM_INFINITY)
|
||||||
printf("unlimited\n");
|
printf("unlimited\n");
|
||||||
else
|
else {
|
||||||
printf("%ld\n", (long)limit);
|
# ifdef RLIM_T_IS_QUAD_T
|
||||||
|
printf("%qd\n", limit);
|
||||||
|
# else
|
||||||
|
# ifdef RLIM_T_IS_LONG_LONG
|
||||||
|
printf("%lld\n", limit);
|
||||||
|
# else
|
||||||
|
# ifdef RLIM_T_IS_UNSIGNED
|
||||||
|
printf("%lu\n", limit);
|
||||||
|
# else
|
||||||
|
printf("%ld\n", limit);
|
||||||
|
# endif /* RLIM_T_IS_UNSIGNED */
|
||||||
|
# endif /* RLIM_T_IS_LONG_LONG */
|
||||||
|
# endif /* RLIM_T_IS_QUAD_T */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* limit: set or show resource limits. The variable hard indicates *
|
/* limit: set or show resource limits. The variable hard indicates *
|
||||||
|
|
|
@ -205,8 +205,12 @@ clean: clean-modules
|
||||||
distclean: distclean-modules
|
distclean: distclean-modules
|
||||||
realclean: realclean-modules
|
realclean: realclean-modules
|
||||||
|
|
||||||
mostlyclean-modules clean-modules distclean-modules realclean-modules: Makemod
|
# Don't remake Makemod just to delete things, even if it doesn't exist.
|
||||||
@$(MAKE) -f Makemod $(MAKEDEFS) `echo $@ | sed 's/-modules//'`
|
mostlyclean-modules clean-modules distclean-modules realclean-modules:
|
||||||
|
if test -f Makemod; then \
|
||||||
|
@$(MAKE) -f Makemod $(MAKEDEFS) `echo $@ | sed 's/-modules//'`; \
|
||||||
|
fi; \
|
||||||
|
exit 0
|
||||||
|
|
||||||
@CLEAN_MK@
|
@CLEAN_MK@
|
||||||
|
|
||||||
|
|
|
@ -230,7 +230,7 @@ static char *lastmsg, lastcodestr[4];
|
||||||
static int lastcode;
|
static int lastcode;
|
||||||
|
|
||||||
/* flag for remote system is UNIX --- useful to know as things are simpler */
|
/* flag for remote system is UNIX --- useful to know as things are simpler */
|
||||||
static int zfis_unix, zfpassive_conn;
|
static int zfpassive_conn;
|
||||||
|
|
||||||
/* remote system has size, mdtm commands */
|
/* remote system has size, mdtm commands */
|
||||||
enum {
|
enum {
|
||||||
|
@ -1786,7 +1786,6 @@ zftp_open(char *name, char **args, int flags)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
zfis_unix = 0;
|
|
||||||
zfhas_size = zfhas_mdtm = ZFCP_UNKN;
|
zfhas_size = zfhas_mdtm = ZFCP_UNKN;
|
||||||
zdfd = -1;
|
zdfd = -1;
|
||||||
/* initial status: open, ASCII data, stream mode 'n' stuff */
|
/* initial status: open, ASCII data, stream mode 'n' stuff */
|
||||||
|
@ -2039,14 +2038,12 @@ zftp_login(char *name, char **args, int flags)
|
||||||
/*
|
/*
|
||||||
* Use binary for transfers. This simple test saves much
|
* Use binary for transfers. This simple test saves much
|
||||||
* hassle for all concerned, particularly me.
|
* hassle for all concerned, particularly me.
|
||||||
|
*
|
||||||
|
* We could set this based just on the UNIX part,
|
||||||
|
* but I don't really know the consequences of that.
|
||||||
*/
|
*/
|
||||||
zfstatus |= ZFST_IMAG;
|
zfstatus |= ZFST_IMAG;
|
||||||
zfis_unix = 1;
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* we could set zfis_unix based just on the UNIX part,
|
|
||||||
* but I don't really know the consequences of that.
|
|
||||||
*/
|
|
||||||
zfsetparam("ZFTP_SYSTEM", systype, ZFPM_READONLY);
|
zfsetparam("ZFTP_SYSTEM", systype, ZFPM_READONLY);
|
||||||
}
|
}
|
||||||
zfstatus |= ZFST_SYST;
|
zfstatus |= ZFST_SYST;
|
||||||
|
|
|
@ -788,9 +788,8 @@ static char *suffixfunc;
|
||||||
void
|
void
|
||||||
makesuffix(int n)
|
makesuffix(int n)
|
||||||
{
|
{
|
||||||
suffixlen[256] = suffixlen[' '] = suffixlen['\t'] = suffixlen['\n'] =
|
suffixlen[256] = suffixlen[' '] = suffixlen['\t'] = suffixlen['\n'] =
|
||||||
suffixlen[';'] = suffixlen['|'] = suffixlen['&'] =
|
suffixlen[';'] = suffixlen['&'] = suffixlen['|'] = n;
|
||||||
suffixlen['<'] = suffixlen['>'] = n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up suffix for parameter names: the last n characters are a suffix *
|
/* Set up suffix for parameter names: the last n characters are a suffix *
|
||||||
|
|
|
@ -681,12 +681,11 @@ cmphaswilds(char *str)
|
||||||
/* Check if we have to complete a parameter name. */
|
/* Check if we have to complete a parameter name. */
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
check_param(char *s, int set, char **ep)
|
check_param(char *s, int set, int test)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int bq = 0, eq = 0, i;
|
|
||||||
|
|
||||||
if (!ep)
|
if (!test)
|
||||||
ispar = parq = eparq = 0;
|
ispar = parq = eparq = 0;
|
||||||
/* Try to find a `$'. */
|
/* Try to find a `$'. */
|
||||||
for (p = s + offs; p > s && *p != String && *p != Qstring; p--);
|
for (p = s + offs; p > s && *p != String && *p != Qstring; p--);
|
||||||
|
@ -726,9 +725,9 @@ check_param(char *s, int set, char **ep)
|
||||||
|
|
||||||
e = b;
|
e = b;
|
||||||
if (br) {
|
if (br) {
|
||||||
while (*e == (ep ? Dnull : '"'))
|
while (*e == (test ? Dnull : '"'))
|
||||||
e++, parq++, bq++;
|
e++, parq++;
|
||||||
if (!ep)
|
if (!test)
|
||||||
b = e;
|
b = e;
|
||||||
}
|
}
|
||||||
/* Find the end of the name. */
|
/* Find the end of the name. */
|
||||||
|
@ -749,14 +748,12 @@ check_param(char *s, int set, char **ep)
|
||||||
if (offs <= e - s && offs >= b - s && n <= 0) {
|
if (offs <= e - s && offs >= b - s && n <= 0) {
|
||||||
if (br) {
|
if (br) {
|
||||||
p = e;
|
p = e;
|
||||||
while (*p == (ep ? Dnull : '"'))
|
while (*p == (test ? Dnull : '"'))
|
||||||
p++, parq--, eparq++, eq++;
|
p++, parq--, eparq++;
|
||||||
}
|
}
|
||||||
/* It is. */
|
/* It is. */
|
||||||
if (ep) {
|
if (test)
|
||||||
*ep = e;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
|
||||||
/* If we were called from makecomplistflags(), we have to set the
|
/* If we were called from makecomplistflags(), we have to set the
|
||||||
* global variables. */
|
* global variables. */
|
||||||
|
|
||||||
|
@ -765,21 +762,12 @@ check_param(char *s, int set, char **ep)
|
||||||
mflags |= CMF_PARBR;
|
mflags |= CMF_PARBR;
|
||||||
|
|
||||||
/* Get the prefix (anything up to the character before the name). */
|
/* Get the prefix (anything up to the character before the name). */
|
||||||
for (i = eq, p = e; i; i--, p++)
|
isuf = dupstring(e);
|
||||||
*p = '.';
|
untokenize(isuf);
|
||||||
isuf = quotename(e, NULL);
|
|
||||||
for (i = eq, p = isuf; i; i--, p++)
|
|
||||||
*p = '"';
|
|
||||||
*e = '\0';
|
*e = '\0';
|
||||||
ripre = dupstring(s);
|
ripre = dupstring(s);
|
||||||
ripre[b - s] = '\0';
|
ripre[b - s] = '\0';
|
||||||
for (i = bq, p = ripre + (b - s) - 1; i; i--, p--)
|
ipre = dupstring(ripre);
|
||||||
*p = '.';
|
|
||||||
ipre = quotename(ripre, NULL);
|
|
||||||
for (i = bq, p = ripre + strlen(ripre) - 1; i; i--, p--)
|
|
||||||
*p = '"';
|
|
||||||
for (i = bq, p = ipre + strlen(ipre) - 1; i; i--, p--)
|
|
||||||
*p = '"';
|
|
||||||
untokenize(ipre);
|
untokenize(ipre);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1231,8 +1219,7 @@ get_comp_string(void)
|
||||||
clwpos = -1;
|
clwpos = -1;
|
||||||
lexsave();
|
lexsave();
|
||||||
inpush(dupstrspace((char *) linptr), 0, NULL);
|
inpush(dupstrspace((char *) linptr), 0, NULL);
|
||||||
strinbeg();
|
strinbeg(0);
|
||||||
stophist = 2;
|
|
||||||
i = tt0 = cp = rd = ins = oins = linarr = parct = ia = 0;
|
i = tt0 = cp = rd = ins = oins = linarr = parct = ia = 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 *
|
||||||
|
@ -1535,11 +1522,12 @@ get_comp_string(void)
|
||||||
/* This variable will hold the current word in quoted form. */
|
/* This variable will hold the current word in quoted form. */
|
||||||
qword = ztrdup(s);
|
qword = ztrdup(s);
|
||||||
offs = cs - wb;
|
offs = cs - wb;
|
||||||
if ((p = check_param(s, 0, &tt))) {
|
if ((p = check_param(s, 0, 1))) {
|
||||||
for (; *p == Dnull; p++)
|
for (p = s; *p; p++)
|
||||||
*p = '"';
|
if (*p == Dnull)
|
||||||
for (; *tt == Dnull; tt++)
|
*p = '"';
|
||||||
*tt = '"';
|
else if (*p == Snull)
|
||||||
|
*p = '\'';
|
||||||
}
|
}
|
||||||
if (*s == Snull || *s == Dnull) {
|
if (*s == Snull || *s == Dnull) {
|
||||||
char *q = (*s == Snull ? "'" : "\""), *n = tricat(qipre, q, "");
|
char *q = (*s == Snull ? "'" : "\""), *n = tricat(qipre, q, "");
|
||||||
|
@ -3427,7 +3415,7 @@ add_match_data(int alt, char *str, Cline line,
|
||||||
Aminfo ai = (alt ? fainfo : ainfo);
|
Aminfo ai = (alt ? fainfo : ainfo);
|
||||||
int palen, salen, qipl, ipl, pl, ppl, qisl, isl, psl;
|
int palen, salen, qipl, ipl, pl, ppl, qisl, isl, psl;
|
||||||
|
|
||||||
palen = salen = qipl = ipl = pl = ppl = isl = psl = 0;
|
palen = salen = qipl = ipl = pl = ppl = qisl = isl = psl = 0;
|
||||||
|
|
||||||
DPUTS(!line, "BUG: add_match_data() without cline");
|
DPUTS(!line, "BUG: add_match_data() without cline");
|
||||||
|
|
||||||
|
@ -4369,10 +4357,10 @@ docompletion(char *s, int lst, int incmd)
|
||||||
invalidatelist();
|
invalidatelist();
|
||||||
|
|
||||||
/* Print the explanation strings if needed. */
|
/* Print the explanation strings if needed. */
|
||||||
if (!showinglist && validlist && nmatches != 1) {
|
if (!showinglist && validlist && usemenu != 2 && nmatches != 1) {
|
||||||
Cmgroup g = amatches;
|
Cmgroup g = amatches;
|
||||||
Cexpl *e;
|
Cexpl *e;
|
||||||
int up = 0, tr = 1;
|
int up = 0, tr = 1, nn = 0;
|
||||||
|
|
||||||
if (!nmatches)
|
if (!nmatches)
|
||||||
feep();
|
feep();
|
||||||
|
@ -4385,7 +4373,12 @@ docompletion(char *s, int lst, int incmd)
|
||||||
trashzle();
|
trashzle();
|
||||||
tr = 0;
|
tr = 0;
|
||||||
}
|
}
|
||||||
|
if (nn) {
|
||||||
|
up++;
|
||||||
|
putc('\n', shout);
|
||||||
|
}
|
||||||
up += printfmt((*e)->str, (*e)->count, 1);
|
up += printfmt((*e)->str, (*e)->count, 1);
|
||||||
|
nn = 1;
|
||||||
}
|
}
|
||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
|
@ -4915,6 +4908,9 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
|
||||||
int ois = instring, oib = inbackt;
|
int ois = instring, oib = inbackt;
|
||||||
char *tmp, *p, *ns, *ol = (char *) line, sav, oaq = autoq, *qp, *qs;
|
char *tmp, *p, *ns, *ol = (char *) line, sav, oaq = autoq, *qp, *qs;
|
||||||
|
|
||||||
|
swb = swe = soffs = 0;
|
||||||
|
ns = NULL;
|
||||||
|
|
||||||
/* Put the string in the lexer buffer and call the lexer to *
|
/* Put the string in the lexer buffer and call the lexer to *
|
||||||
* get the words we have to expand. */
|
* get the words we have to expand. */
|
||||||
zleparse = 1;
|
zleparse = 1;
|
||||||
|
@ -4930,8 +4926,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
|
||||||
inpush(dupstrspace(tmp), 0, NULL);
|
inpush(dupstrspace(tmp), 0, NULL);
|
||||||
line = (unsigned char *) tmp;
|
line = (unsigned char *) tmp;
|
||||||
ll = tl - 1;
|
ll = tl - 1;
|
||||||
strinbeg();
|
strinbeg(0);
|
||||||
stophist = 2;
|
|
||||||
noaliases = 1;
|
noaliases = 1;
|
||||||
do {
|
do {
|
||||||
ctxtlex();
|
ctxtlex();
|
||||||
|
@ -4979,11 +4974,21 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
|
||||||
ll = oll;
|
ll = oll;
|
||||||
if (cur < 0 || i < 1)
|
if (cur < 0 || i < 1)
|
||||||
return 1;
|
return 1;
|
||||||
|
owb = offs;
|
||||||
|
offs = soffs;
|
||||||
|
if ((p = check_param(ns, 0, 1))) {
|
||||||
|
for (p = ns; *p; p++)
|
||||||
|
if (*p == Dnull)
|
||||||
|
*p = '"';
|
||||||
|
else if (*p == Snull)
|
||||||
|
*p = '\'';
|
||||||
|
}
|
||||||
|
offs = owb;
|
||||||
if (*ns == Snull || *ns == Dnull) {
|
if (*ns == Snull || *ns == Dnull) {
|
||||||
instring = (*ns == Snull ? 1 : 2);
|
instring = (*ns == Snull ? 1 : 2);
|
||||||
inbackt = 0;
|
inbackt = 0;
|
||||||
swb++;
|
swb++;
|
||||||
if (ns[strlen(ns) - 1] == *ns)
|
if (ns[strlen(ns) - 1] == *ns && ns[1])
|
||||||
swe--;
|
swe--;
|
||||||
autoq = (*ns == Snull ? '\'' : '"');
|
autoq = (*ns == Snull ? '\'' : '"');
|
||||||
} else {
|
} else {
|
||||||
|
@ -5028,7 +5033,8 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
|
||||||
char **ow = clwords, *os = cmdstr, *oqp = qipre, *oqs = qisuf;
|
char **ow = clwords, *os = cmdstr, *oqp = qipre, *oqs = qisuf;
|
||||||
int olws = clwsize, olwn = clwnum, olwp = clwpos;
|
int olws = clwsize, olwn = clwnum, olwp = clwpos;
|
||||||
int obr = brange, oer = erange, oof = offs;
|
int obr = brange, oer = erange, oof = offs;
|
||||||
|
unsigned long occ = ccont;
|
||||||
|
|
||||||
clwsize = clwnum = countlinknodes(foo);
|
clwsize = clwnum = countlinknodes(foo);
|
||||||
clwords = (char **) zalloc((clwnum + 1) * sizeof(char *));
|
clwords = (char **) zalloc((clwnum + 1) * sizeof(char *));
|
||||||
for (n = firstnode(foo), i = 0; n; incnode(n), i++) {
|
for (n = firstnode(foo), i = 0; n; incnode(n), i++) {
|
||||||
|
@ -5043,7 +5049,9 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
|
||||||
qipre = qp;
|
qipre = qp;
|
||||||
qisuf = qs;
|
qisuf = qs;
|
||||||
offs = soffs;
|
offs = soffs;
|
||||||
|
ccont = CC_CCCONT;
|
||||||
makecomplistcmd(ns, !clwpos, CFN_FIRST);
|
makecomplistcmd(ns, !clwpos, CFN_FIRST);
|
||||||
|
ccont = occ;
|
||||||
offs = oof;
|
offs = oof;
|
||||||
zsfree(cmdstr);
|
zsfree(cmdstr);
|
||||||
cmdstr = os;
|
cmdstr = os;
|
||||||
|
@ -6341,7 +6349,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
||||||
tmpbuf = (char *)zhalloc(strlen(cc->str) + 5);
|
tmpbuf = (char *)zhalloc(strlen(cc->str) + 5);
|
||||||
sprintf(tmpbuf, "foo %s", cc->str); /* KLUDGE! */
|
sprintf(tmpbuf, "foo %s", cc->str); /* KLUDGE! */
|
||||||
inpush(tmpbuf, 0, NULL);
|
inpush(tmpbuf, 0, NULL);
|
||||||
strinbeg();
|
strinbeg(0);
|
||||||
noaliases = 1;
|
noaliases = 1;
|
||||||
do {
|
do {
|
||||||
ctxtlex();
|
ctxtlex();
|
||||||
|
@ -6502,7 +6510,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
||||||
int oldn = clwnum, oldp = clwpos;
|
int oldn = clwnum, oldp = clwpos;
|
||||||
unsigned long occ = ccont;
|
unsigned long occ = ccont;
|
||||||
|
|
||||||
ccont = 0;
|
ccont = CC_CCCONT;
|
||||||
|
|
||||||
/* So we restrict the words-array. */
|
/* So we restrict the words-array. */
|
||||||
if (brange >= clwnum)
|
if (brange >= clwnum)
|
||||||
|
@ -8099,14 +8107,13 @@ doexpandhist(void)
|
||||||
lexsave();
|
lexsave();
|
||||||
/* We push ol as it will remain unchanged */
|
/* We push ol as it will remain unchanged */
|
||||||
inpush((char *) ol, 0, NULL);
|
inpush((char *) ol, 0, NULL);
|
||||||
strinbeg();
|
strinbeg(1);
|
||||||
noaliases = 1;
|
noaliases = 1;
|
||||||
noerrs = 1;
|
noerrs = 1;
|
||||||
exlast = inbufct;
|
exlast = inbufct;
|
||||||
do {
|
do {
|
||||||
ctxtlex();
|
ctxtlex();
|
||||||
} while (tok != ENDINPUT && tok != LEXERR);
|
} while (tok != ENDINPUT && tok != LEXERR);
|
||||||
stophist = 2;
|
|
||||||
while (!lexstop)
|
while (!lexstop)
|
||||||
hgetc();
|
hgetc();
|
||||||
/* We have to save errflags because it's reset in lexrestore. Since *
|
/* We have to save errflags because it's reset in lexrestore. Since *
|
||||||
|
@ -8178,7 +8185,7 @@ getcurcmd(void)
|
||||||
metafy_line();
|
metafy_line();
|
||||||
inpush(dupstrspace((char *) line), 0, NULL);
|
inpush(dupstrspace((char *) line), 0, NULL);
|
||||||
unmetafy_line();
|
unmetafy_line();
|
||||||
strinbeg();
|
strinbeg(1);
|
||||||
pushheap();
|
pushheap();
|
||||||
do {
|
do {
|
||||||
curlincmd = incmdpos;
|
curlincmd = incmdpos;
|
||||||
|
|
|
@ -43,7 +43,7 @@ static struct builtin builtins[] =
|
||||||
BUILTIN(".", BINF_PSPECIAL, bin_dot, 1, -1, 0, NULL, NULL),
|
BUILTIN(".", BINF_PSPECIAL, bin_dot, 1, -1, 0, NULL, NULL),
|
||||||
BUILTIN(":", BINF_PSPECIAL, bin_true, 0, -1, 0, NULL, NULL),
|
BUILTIN(":", BINF_PSPECIAL, bin_true, 0, -1, 0, NULL, NULL),
|
||||||
BUILTIN("alias", BINF_MAGICEQUALS, bin_alias, 0, -1, 0, "Lgmr", NULL),
|
BUILTIN("alias", BINF_MAGICEQUALS, bin_alias, 0, -1, 0, "Lgmr", NULL),
|
||||||
BUILTIN("autoload", BINF_TYPEOPTS, bin_functions, 0, -1, 0, "t", "u"),
|
BUILTIN("autoload", BINF_TYPEOPTS, bin_functions, 0, -1, 0, "tU", "u"),
|
||||||
BUILTIN("bg", 0, bin_fg, 0, -1, BIN_BG, NULL, NULL),
|
BUILTIN("bg", 0, bin_fg, 0, -1, BIN_BG, NULL, NULL),
|
||||||
BUILTIN("break", BINF_PSPECIAL, bin_break, 0, 1, BIN_BREAK, NULL, NULL),
|
BUILTIN("break", BINF_PSPECIAL, bin_break, 0, 1, BIN_BREAK, NULL, NULL),
|
||||||
BUILTIN("bye", 0, bin_break, 0, 1, BIN_EXIT, NULL, NULL),
|
BUILTIN("bye", 0, bin_break, 0, 1, BIN_EXIT, NULL, NULL),
|
||||||
|
@ -64,7 +64,7 @@ static struct builtin builtins[] =
|
||||||
BUILTIN("false", 0, bin_false, 0, -1, 0, NULL, NULL),
|
BUILTIN("false", 0, bin_false, 0, -1, 0, NULL, NULL),
|
||||||
BUILTIN("fc", BINF_FCOPTS, bin_fc, 0, -1, BIN_FC, "nlreIRWAdDfEim", NULL),
|
BUILTIN("fc", BINF_FCOPTS, bin_fc, 0, -1, BIN_FC, "nlreIRWAdDfEim", NULL),
|
||||||
BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
|
BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
|
||||||
BUILTIN("functions", BINF_TYPEOPTS, bin_functions, 0, -1, 0, "mtu", NULL),
|
BUILTIN("functions", BINF_TYPEOPTS, bin_functions, 0, -1, 0, "mtuU", NULL),
|
||||||
BUILTIN("getln", 0, bin_read, 0, -1, 0, "ecnAlE", "zr"),
|
BUILTIN("getln", 0, bin_read, 0, -1, 0, "ecnAlE", "zr"),
|
||||||
BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL),
|
BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL),
|
||||||
BUILTIN("hash", BINF_MAGICEQUALS, bin_hash, 0, -1, 0, "dfmrv", NULL),
|
BUILTIN("hash", BINF_MAGICEQUALS, bin_hash, 0, -1, 0, "dfmrv", NULL),
|
||||||
|
@ -209,7 +209,7 @@ execbuiltin(LinkList args, Builtin bn)
|
||||||
LinkNode n;
|
LinkNode n;
|
||||||
char ops[MAX_OPS], *arg, *pp, *name, **argv, **oargv, *optstr;
|
char ops[MAX_OPS], *arg, *pp, *name, **argv, **oargv, *optstr;
|
||||||
char *oxarg, *xarg = NULL;
|
char *oxarg, *xarg = NULL;
|
||||||
int flags, sense, argc = 0, execop;
|
int flags, sense, argc = 0, execop, xtr = isset(XTRACE), lxarg = 0;
|
||||||
|
|
||||||
/* initialise some static variables */
|
/* initialise some static variables */
|
||||||
auxdata = NULL;
|
auxdata = NULL;
|
||||||
|
@ -250,12 +250,21 @@ execbuiltin(LinkList args, Builtin bn)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* save the options in xarg, for execution tracing */
|
/* save the options in xarg, for execution tracing */
|
||||||
if (xarg) {
|
if (xtr) {
|
||||||
oxarg = tricat(xarg, " ", arg);
|
if (xarg) {
|
||||||
zsfree(xarg);
|
int l = strlen(arg) + lxarg + 1;
|
||||||
xarg = oxarg;
|
|
||||||
} else
|
oxarg = zhalloc(l + 1);
|
||||||
xarg = ztrdup(arg);
|
strcpy(oxarg, xarg);
|
||||||
|
oxarg[lxarg] = ' ';
|
||||||
|
strcpy(oxarg + lxarg + 1, arg);
|
||||||
|
xarg = oxarg;
|
||||||
|
lxarg = l + 1;
|
||||||
|
} else {
|
||||||
|
xarg = dupstring(arg);
|
||||||
|
lxarg = strlen(xarg);
|
||||||
|
}
|
||||||
|
}
|
||||||
/* handle -- or - (ops['-']), and + (ops['-'] and ops['+']) */
|
/* handle -- or - (ops['-']), and + (ops['-'] and ops['+']) */
|
||||||
if (arg[1] == '-')
|
if (arg[1] == '-')
|
||||||
arg++;
|
arg++;
|
||||||
|
@ -283,7 +292,6 @@ execbuiltin(LinkList args, Builtin bn)
|
||||||
if(*arg == Meta)
|
if(*arg == Meta)
|
||||||
*++arg ^= 32;
|
*++arg ^= 32;
|
||||||
zerr("bad option: -%c", NULL, *arg);
|
zerr("bad option: -%c", NULL, *arg);
|
||||||
zsfree(xarg);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
arg = (char *) ugetnode(args);
|
arg = (char *) ugetnode(args);
|
||||||
|
@ -330,7 +338,6 @@ execbuiltin(LinkList args, Builtin bn)
|
||||||
while ((*argv++ = (char *)ugetnode(args)));
|
while ((*argv++ = (char *)ugetnode(args)));
|
||||||
argv = oargv;
|
argv = oargv;
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
zsfree(xarg);
|
|
||||||
errflag = 0;
|
errflag = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -339,12 +346,11 @@ execbuiltin(LinkList args, Builtin bn)
|
||||||
if (argc < bn->minargs || (argc > bn->maxargs && bn->maxargs != -1)) {
|
if (argc < bn->minargs || (argc > bn->maxargs && bn->maxargs != -1)) {
|
||||||
zwarnnam(name, (argc < bn->minargs)
|
zwarnnam(name, (argc < bn->minargs)
|
||||||
? "not enough arguments" : "too many arguments", NULL, 0);
|
? "not enough arguments" : "too many arguments", NULL, 0);
|
||||||
zsfree(xarg);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* display execution trace information, if required */
|
/* display execution trace information, if required */
|
||||||
if (isset(XTRACE)) {
|
if (xtr) {
|
||||||
fprintf(stderr, "%s%s", (prompt4) ? prompt4 : "", name);
|
fprintf(stderr, "%s%s", (prompt4) ? prompt4 : "", name);
|
||||||
if (xarg)
|
if (xarg)
|
||||||
fprintf(stderr, " %s", xarg);
|
fprintf(stderr, " %s", xarg);
|
||||||
|
@ -353,7 +359,6 @@ execbuiltin(LinkList args, Builtin bn)
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
zsfree(xarg);
|
|
||||||
/* call the handler function, and return its return value */
|
/* call the handler function, and return its return value */
|
||||||
return (*(bn->handlerfunc)) (name, argv, ops, bn->funcid);
|
return (*(bn->handlerfunc)) (name, argv, ops, bn->funcid);
|
||||||
}
|
}
|
||||||
|
@ -1824,17 +1829,18 @@ bin_functions(char *name, char **argv, char *ops, int func)
|
||||||
int on = 0, off = 0;
|
int on = 0, off = 0;
|
||||||
|
|
||||||
/* Do we have any flags defined? */
|
/* Do we have any flags defined? */
|
||||||
if (ops['u'] || ops['t']) {
|
if (ops['u'] == 1)
|
||||||
if (ops['u'] == 1)
|
on |= PM_UNDEFINED;
|
||||||
on |= PM_UNDEFINED;
|
else if (ops['u'] == 2)
|
||||||
else if (ops['u'] == 2)
|
off |= PM_UNDEFINED;
|
||||||
off |= PM_UNDEFINED;
|
if (ops['U'] == 1)
|
||||||
|
on |= PM_UNALIASED|PM_UNDEFINED;
|
||||||
if (ops['t'] == 1)
|
else if (ops['U'] == 2)
|
||||||
on |= PM_TAGGED;
|
off |= PM_UNALIASED;
|
||||||
else if (ops['t'] == 2)
|
if (ops['t'] == 1)
|
||||||
off |= PM_TAGGED;
|
on |= PM_TAGGED;
|
||||||
}
|
else if (ops['t'] == 2)
|
||||||
|
off |= PM_TAGGED;
|
||||||
|
|
||||||
if (off & PM_UNDEFINED) {
|
if (off & PM_UNDEFINED) {
|
||||||
zwarnnam(name, "invalid option(s)", NULL, 0);
|
zwarnnam(name, "invalid option(s)", NULL, 0);
|
||||||
|
@ -1845,6 +1851,8 @@ bin_functions(char *name, char **argv, char *ops, int func)
|
||||||
* are given, we will print only functions containing these *
|
* are given, we will print only functions containing these *
|
||||||
* flags, else we'll print them all. */
|
* flags, else we'll print them all. */
|
||||||
if (!*argv) {
|
if (!*argv) {
|
||||||
|
if (ops['U'] && !ops['u'])
|
||||||
|
on &= ~PM_UNDEFINED;
|
||||||
scanhashtable(shfunctab, 1, on|off, DISABLED, shfunctab->printnode, 0);
|
scanhashtable(shfunctab, 1, on|off, DISABLED, shfunctab->printnode, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3078,8 +3086,7 @@ bin_eval(char *nam, char **argv, char *ops, int func)
|
||||||
List list;
|
List list;
|
||||||
|
|
||||||
inpush(zjoin(argv, ' '), 0, NULL);
|
inpush(zjoin(argv, ' '), 0, NULL);
|
||||||
strinbeg();
|
strinbeg(0);
|
||||||
stophist = 2;
|
|
||||||
list = parse_list();
|
list = parse_list();
|
||||||
strinend();
|
strinend();
|
||||||
inpop();
|
inpop();
|
||||||
|
@ -3584,7 +3591,7 @@ bin_trap(char *name, char **argv, char *ops, int func)
|
||||||
if (!sigfuncs[sig])
|
if (!sigfuncs[sig])
|
||||||
printf("trap -- '' %s\n", sigs[sig]);
|
printf("trap -- '' %s\n", sigs[sig]);
|
||||||
else {
|
else {
|
||||||
s = getpermtext((void *) dupstruct((void *) sigfuncs[sig]));
|
s = getpermtext((void *) sigfuncs[sig]);
|
||||||
printf("trap -- ");
|
printf("trap -- ");
|
||||||
quotedzputs(s, stdout);
|
quotedzputs(s, stdout);
|
||||||
printf(" %s\n", sigs[sig]);
|
printf(" %s\n", sigs[sig]);
|
||||||
|
|
91
Src/cond.c
91
Src/cond.c
|
@ -42,6 +42,7 @@ int
|
||||||
evalcond(Cond c)
|
evalcond(Cond c)
|
||||||
{
|
{
|
||||||
struct stat *st;
|
struct stat *st;
|
||||||
|
char *left, *right = NULL;
|
||||||
|
|
||||||
switch (c->type) {
|
switch (c->type) {
|
||||||
case COND_NOT:
|
case COND_NOT:
|
||||||
|
@ -103,107 +104,109 @@ evalcond(Cond c)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
singsub((char **)&c->left);
|
left = dupstring((char *) c->left);
|
||||||
untokenize(c->left);
|
singsub(&left);
|
||||||
|
untokenize(left);
|
||||||
if (c->right) {
|
if (c->right) {
|
||||||
singsub((char **)&c->right);
|
right = dupstring((char *) c->right);
|
||||||
|
singsub(&right);
|
||||||
if (c->type != COND_STREQ && c->type != COND_STRNEQ)
|
if (c->type != COND_STREQ && c->type != COND_STRNEQ)
|
||||||
untokenize(c->right);
|
untokenize(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tracingcond) {
|
if (tracingcond) {
|
||||||
if (c->type < COND_MOD) {
|
if (c->type < COND_MOD) {
|
||||||
char *rt = (char *)c->right;
|
char *rt = (char *)right;
|
||||||
if (c->type == COND_STREQ || c->type == COND_STRNEQ) {
|
if (c->type == COND_STREQ || c->type == COND_STRNEQ) {
|
||||||
rt = dupstring(rt);
|
rt = dupstring(rt);
|
||||||
untokenize(rt);
|
untokenize(rt);
|
||||||
}
|
}
|
||||||
fprintf(stderr, " %s %s %s", (char *)c->left, condstr[c->type],
|
fprintf(stderr, " %s %s %s", (char *)left, condstr[c->type],
|
||||||
rt);
|
rt);
|
||||||
} else
|
} else
|
||||||
fprintf(stderr, " -%c %s", c->type, (char *)c->left);
|
fprintf(stderr, " -%c %s", c->type, (char *)left);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (c->type) {
|
switch (c->type) {
|
||||||
case COND_STREQ:
|
case COND_STREQ:
|
||||||
return matchpat(c->left, c->right);
|
return matchpat(left, right);
|
||||||
case COND_STRNEQ:
|
case COND_STRNEQ:
|
||||||
return !matchpat(c->left, c->right);
|
return !matchpat(left, right);
|
||||||
case COND_STRLT:
|
case COND_STRLT:
|
||||||
return strcmp(c->left, c->right) < 0;
|
return strcmp(left, right) < 0;
|
||||||
case COND_STRGTR:
|
case COND_STRGTR:
|
||||||
return strcmp(c->left, c->right) > 0;
|
return strcmp(left, right) > 0;
|
||||||
case 'e':
|
case 'e':
|
||||||
case 'a':
|
case 'a':
|
||||||
return (doaccess(c->left, F_OK));
|
return (doaccess(left, F_OK));
|
||||||
case 'b':
|
case 'b':
|
||||||
return (S_ISBLK(dostat(c->left)));
|
return (S_ISBLK(dostat(left)));
|
||||||
case 'c':
|
case 'c':
|
||||||
return (S_ISCHR(dostat(c->left)));
|
return (S_ISCHR(dostat(left)));
|
||||||
case 'd':
|
case 'd':
|
||||||
return (S_ISDIR(dostat(c->left)));
|
return (S_ISDIR(dostat(left)));
|
||||||
case 'f':
|
case 'f':
|
||||||
return (S_ISREG(dostat(c->left)));
|
return (S_ISREG(dostat(left)));
|
||||||
case 'g':
|
case 'g':
|
||||||
return (!!(dostat(c->left) & S_ISGID));
|
return (!!(dostat(left) & S_ISGID));
|
||||||
case 'k':
|
case 'k':
|
||||||
return (!!(dostat(c->left) & S_ISVTX));
|
return (!!(dostat(left) & S_ISVTX));
|
||||||
case 'n':
|
case 'n':
|
||||||
return (!!strlen(c->left));
|
return (!!strlen(left));
|
||||||
case 'o':
|
case 'o':
|
||||||
return (optison(c->left));
|
return (optison(left));
|
||||||
case 'p':
|
case 'p':
|
||||||
return (S_ISFIFO(dostat(c->left)));
|
return (S_ISFIFO(dostat(left)));
|
||||||
case 'r':
|
case 'r':
|
||||||
return (doaccess(c->left, R_OK));
|
return (doaccess(left, R_OK));
|
||||||
case 's':
|
case 's':
|
||||||
return ((st = getstat(c->left)) && !!(st->st_size));
|
return ((st = getstat(left)) && !!(st->st_size));
|
||||||
case 'S':
|
case 'S':
|
||||||
return (S_ISSOCK(dostat(c->left)));
|
return (S_ISSOCK(dostat(left)));
|
||||||
case 'u':
|
case 'u':
|
||||||
return (!!(dostat(c->left) & S_ISUID));
|
return (!!(dostat(left) & S_ISUID));
|
||||||
case 'w':
|
case 'w':
|
||||||
return (doaccess(c->left, W_OK));
|
return (doaccess(left, W_OK));
|
||||||
case 'x':
|
case 'x':
|
||||||
if (privasserted()) {
|
if (privasserted()) {
|
||||||
mode_t mode = dostat(c->left);
|
mode_t mode = dostat(left);
|
||||||
return (mode & S_IXUGO) || S_ISDIR(mode);
|
return (mode & S_IXUGO) || S_ISDIR(mode);
|
||||||
}
|
}
|
||||||
return doaccess(c->left, X_OK);
|
return doaccess(left, X_OK);
|
||||||
case 'z':
|
case 'z':
|
||||||
return (!strlen(c->left));
|
return (!strlen(left));
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'L':
|
case 'L':
|
||||||
return (S_ISLNK(dolstat(c->left)));
|
return (S_ISLNK(dolstat(left)));
|
||||||
case 'O':
|
case 'O':
|
||||||
return ((st = getstat(c->left)) && st->st_uid == geteuid());
|
return ((st = getstat(left)) && st->st_uid == geteuid());
|
||||||
case 'G':
|
case 'G':
|
||||||
return ((st = getstat(c->left)) && st->st_gid == getegid());
|
return ((st = getstat(left)) && st->st_gid == getegid());
|
||||||
case 'N':
|
case 'N':
|
||||||
return ((st = getstat(c->left)) && st->st_atime <= st->st_mtime);
|
return ((st = getstat(left)) && st->st_atime <= st->st_mtime);
|
||||||
case 't':
|
case 't':
|
||||||
return isatty(matheval(c->left));
|
return isatty(matheval(left));
|
||||||
case COND_EQ:
|
case COND_EQ:
|
||||||
return matheval(c->left) == matheval(c->right);
|
return matheval(left) == matheval(right);
|
||||||
case COND_NE:
|
case COND_NE:
|
||||||
return matheval(c->left) != matheval(c->right);
|
return matheval(left) != matheval(right);
|
||||||
case COND_LT:
|
case COND_LT:
|
||||||
return matheval(c->left) < matheval(c->right);
|
return matheval(left) < matheval(right);
|
||||||
case COND_GT:
|
case COND_GT:
|
||||||
return matheval(c->left) > matheval(c->right);
|
return matheval(left) > matheval(right);
|
||||||
case COND_LE:
|
case COND_LE:
|
||||||
return matheval(c->left) <= matheval(c->right);
|
return matheval(left) <= matheval(right);
|
||||||
case COND_GE:
|
case COND_GE:
|
||||||
return matheval(c->left) >= matheval(c->right);
|
return matheval(left) >= matheval(right);
|
||||||
case COND_NT:
|
case COND_NT:
|
||||||
case COND_OT:
|
case COND_OT:
|
||||||
{
|
{
|
||||||
time_t a;
|
time_t a;
|
||||||
|
|
||||||
if (!(st = getstat(c->left)))
|
if (!(st = getstat(left)))
|
||||||
return 0;
|
return 0;
|
||||||
a = st->st_mtime;
|
a = st->st_mtime;
|
||||||
if (!(st = getstat(c->right)))
|
if (!(st = getstat(right)))
|
||||||
return 0;
|
return 0;
|
||||||
return (c->type == COND_NT) ? a > st->st_mtime : a < st->st_mtime;
|
return (c->type == COND_NT) ? a > st->st_mtime : a < st->st_mtime;
|
||||||
}
|
}
|
||||||
|
@ -212,11 +215,11 @@ evalcond(Cond c)
|
||||||
dev_t d;
|
dev_t d;
|
||||||
ino_t i;
|
ino_t i;
|
||||||
|
|
||||||
if (!(st = getstat(c->left)))
|
if (!(st = getstat(left)))
|
||||||
return 0;
|
return 0;
|
||||||
d = st->st_dev;
|
d = st->st_dev;
|
||||||
i = st->st_ino;
|
i = st->st_ino;
|
||||||
if (!(st = getstat(c->right)))
|
if (!(st = getstat(right)))
|
||||||
return 0;
|
return 0;
|
||||||
return d == st->st_dev && i == st->st_ino;
|
return d == st->st_dev && i == st->st_ino;
|
||||||
}
|
}
|
||||||
|
|
394
Src/exec.c
394
Src/exec.c
|
@ -139,8 +139,7 @@ parse_string(char *s)
|
||||||
|
|
||||||
lexsave();
|
lexsave();
|
||||||
inpush(s, 0, NULL);
|
inpush(s, 0, NULL);
|
||||||
strinbeg();
|
strinbeg(0);
|
||||||
stophist = 2;
|
|
||||||
l = parse_list();
|
l = parse_list();
|
||||||
strinend();
|
strinend();
|
||||||
inpop();
|
inpop();
|
||||||
|
@ -298,12 +297,12 @@ static char list_pipe_text[JOBTEXTSIZE];
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
execcursh(Cmd cmd)
|
execcursh(Cmd cmd, LinkList args, int flags)
|
||||||
{
|
{
|
||||||
if (!list_pipe)
|
if (!list_pipe)
|
||||||
deletejob(jobtab + thisjob);
|
deletejob(jobtab + thisjob);
|
||||||
execlist(cmd->u.list, 1, cmd->flags & CFLAG_EXEC);
|
execlist(cmd->u.list, 1, flags & CFLAG_EXEC);
|
||||||
cmd->u.list = NULL;
|
|
||||||
return lastval;
|
return lastval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -718,7 +717,6 @@ execlist(List list, int dont_change_job, int exiting)
|
||||||
/* Reset donetrap: this ensures that a trap is only *
|
/* Reset donetrap: this ensures that a trap is only *
|
||||||
* called once for each sublist that fails. */
|
* called once for each sublist that fails. */
|
||||||
donetrap = 0;
|
donetrap = 0;
|
||||||
simplifyright(list);
|
|
||||||
slist = list->left;
|
slist = list->left;
|
||||||
|
|
||||||
/* Loop through code followed by &&, ||, or end of sublist. */
|
/* Loop through code followed by &&, ||, or end of sublist. */
|
||||||
|
@ -1009,11 +1007,13 @@ execpline2(Pline pline, int how, int input, int output, int last1)
|
||||||
lineno = pline->left->lineno;
|
lineno = pline->left->lineno;
|
||||||
|
|
||||||
if (pline_level == 1)
|
if (pline_level == 1)
|
||||||
strcpy(list_pipe_text, getjobtext((void *) pline->left));
|
if (!sfcontext)
|
||||||
if (pline->type == END) {
|
strcpy(list_pipe_text, getjobtext((void *) pline->left));
|
||||||
|
else
|
||||||
|
list_pipe_text[0] = '\0';
|
||||||
|
if (pline->type == END)
|
||||||
execcmd(pline->left, input, output, how, last1 ? 1 : 2);
|
execcmd(pline->left, input, output, how, last1 ? 1 : 2);
|
||||||
pline->left = NULL;
|
else {
|
||||||
} else {
|
|
||||||
int old_list_pipe = list_pipe;
|
int old_list_pipe = list_pipe;
|
||||||
|
|
||||||
mpipe(pipes);
|
mpipe(pipes);
|
||||||
|
@ -1046,11 +1046,10 @@ execpline2(Pline pline, int how, int input, int output, int last1)
|
||||||
_exit(lastval);
|
_exit(lastval);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* otherwise just do the pipeline normally. */
|
/* otherwise just do the pipeline normally. */
|
||||||
subsh_close = pipes[0];
|
subsh_close = pipes[0];
|
||||||
execcmd(pline->left, input, pipes[1], how, 0);
|
execcmd(pline->left, input, pipes[1], how, 0);
|
||||||
}
|
}
|
||||||
pline->left = NULL;
|
|
||||||
zclose(pipes[1]);
|
zclose(pipes[1]);
|
||||||
if (pline->right) {
|
if (pline->right) {
|
||||||
/* if another execpline() is invoked because the command is *
|
/* if another execpline() is invoked because the command is *
|
||||||
|
@ -1102,13 +1101,17 @@ makecline(LinkList list)
|
||||||
void
|
void
|
||||||
untokenize(char *s)
|
untokenize(char *s)
|
||||||
{
|
{
|
||||||
for (; *s; s++)
|
if (*s) {
|
||||||
if (itok(*s)) {
|
char *p = s, c;
|
||||||
if (*s == Nularg)
|
|
||||||
chuck(s--);
|
while ((c = *s++))
|
||||||
else
|
if (itok(c)) {
|
||||||
*s = ztokens[*s - Pound];
|
if (c != Nularg)
|
||||||
}
|
*p++ = ztokens[c - Pound];
|
||||||
|
} else
|
||||||
|
*p++ = c;
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open a file for writing redicection */
|
/* Open a file for writing redicection */
|
||||||
|
@ -1152,34 +1155,34 @@ clobber_open(struct redir *f)
|
||||||
static void
|
static void
|
||||||
closemn(struct multio **mfds, int fd)
|
closemn(struct multio **mfds, int fd)
|
||||||
{
|
{
|
||||||
struct multio *mn = mfds[fd];
|
if (fd >= 0 && mfds[fd] && mfds[fd]->ct >= 2) {
|
||||||
char buf[TCBUFSIZE];
|
struct multio *mn = mfds[fd];
|
||||||
int len, i;
|
char buf[TCBUFSIZE];
|
||||||
|
int len, i;
|
||||||
|
|
||||||
if (fd < 0 || !mfds[fd] || mfds[fd]->ct < 2)
|
if (zfork()) {
|
||||||
return;
|
|
||||||
if (zfork()) {
|
|
||||||
for (i = 0; i < mn->ct; i++)
|
|
||||||
zclose(mn->fds[i]);
|
|
||||||
zclose(mn->pipe);
|
|
||||||
mn->ct = 1;
|
|
||||||
mn->fds[0] = fd;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* pid == 0 */
|
|
||||||
closeallelse(mn);
|
|
||||||
if (mn->rflag) {
|
|
||||||
/* tee process */
|
|
||||||
while ((len = read(mn->pipe, buf, TCBUFSIZE)) > 0)
|
|
||||||
for (i = 0; i < mn->ct; i++)
|
for (i = 0; i < mn->ct; i++)
|
||||||
write(mn->fds[i], buf, len);
|
zclose(mn->fds[i]);
|
||||||
} else {
|
zclose(mn->pipe);
|
||||||
/* cat process */
|
mn->ct = 1;
|
||||||
for (i = 0; i < mn->ct; i++)
|
mn->fds[0] = fd;
|
||||||
while ((len = read(mn->fds[i], buf, TCBUFSIZE)) > 0)
|
return;
|
||||||
write(mn->pipe, buf, len);
|
}
|
||||||
|
/* pid == 0 */
|
||||||
|
closeallelse(mn);
|
||||||
|
if (mn->rflag) {
|
||||||
|
/* tee process */
|
||||||
|
while ((len = read(mn->pipe, buf, TCBUFSIZE)) > 0)
|
||||||
|
for (i = 0; i < mn->ct; i++)
|
||||||
|
write(mn->fds[i], buf, len);
|
||||||
|
} else {
|
||||||
|
/* cat process */
|
||||||
|
for (i = 0; i < mn->ct; i++)
|
||||||
|
while ((len = read(mn->fds[i], buf, TCBUFSIZE)) > 0)
|
||||||
|
write(mn->pipe, buf, len);
|
||||||
|
}
|
||||||
|
_exit(0);
|
||||||
}
|
}
|
||||||
_exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* close all the mnodes (failure) */
|
/* close all the mnodes (failure) */
|
||||||
|
@ -1273,9 +1276,10 @@ static void
|
||||||
addvars(LinkList l, int export)
|
addvars(LinkList l, int export)
|
||||||
{
|
{
|
||||||
Varasg v;
|
Varasg v;
|
||||||
|
LinkNode n;
|
||||||
LinkList vl;
|
LinkList vl;
|
||||||
int xtr;
|
int xtr;
|
||||||
char **arr, **ptr;
|
char **arr, **ptr, *name;
|
||||||
|
|
||||||
xtr = isset(XTRACE);
|
xtr = isset(XTRACE);
|
||||||
if (xtr && nonempty(l)) {
|
if (xtr && nonempty(l)) {
|
||||||
|
@ -1283,26 +1287,30 @@ addvars(LinkList l, int export)
|
||||||
doneps4 = 1;
|
doneps4 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (nonempty(l)) {
|
for (n = firstnode(l); n; incnode(n)) {
|
||||||
v = (Varasg) ugetnode(l);
|
v = (Varasg) getdata(n);
|
||||||
singsub(&v->name);
|
name = dupstring(v->name);
|
||||||
|
singsub(&name);
|
||||||
if (errflag)
|
if (errflag)
|
||||||
return;
|
return;
|
||||||
untokenize(v->name);
|
untokenize(name);
|
||||||
if (xtr)
|
if (xtr)
|
||||||
fprintf(stderr, "%s=", v->name);
|
fprintf(stderr, "%s=", name);
|
||||||
if (v->type == PM_SCALAR) {
|
if (v->type == PM_SCALAR) {
|
||||||
vl = newlinklist();
|
vl = newlinklist();
|
||||||
addlinknode(vl, v->str);
|
addlinknode(vl, dupstring(v->str));
|
||||||
} else
|
} else
|
||||||
vl = v->arr;
|
vl = listdup(v->arr);
|
||||||
prefork(vl, v->type == PM_SCALAR ? (PF_SINGLE|PF_ASSIGN) : PF_ASSIGN);
|
if (vl) {
|
||||||
if (errflag)
|
prefork(vl, v->type == PM_SCALAR ? (PF_SINGLE|PF_ASSIGN) :
|
||||||
return;
|
PF_ASSIGN);
|
||||||
if (isset(GLOBASSIGN) || v->type != PM_SCALAR)
|
if (errflag)
|
||||||
globlist(vl);
|
return;
|
||||||
if (errflag)
|
if (isset(GLOBASSIGN) || v->type != PM_SCALAR)
|
||||||
return;
|
globlist(vl);
|
||||||
|
if (errflag)
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (v->type == PM_SCALAR && (empty(vl) || !nextnode(firstnode(vl)))) {
|
if (v->type == PM_SCALAR && (empty(vl) || !nextnode(firstnode(vl)))) {
|
||||||
Param pm;
|
Param pm;
|
||||||
char *val;
|
char *val;
|
||||||
|
@ -1319,7 +1327,7 @@ addvars(LinkList l, int export)
|
||||||
if (export) {
|
if (export) {
|
||||||
if (export < 0) {
|
if (export < 0) {
|
||||||
/* We are going to fork so do not bother freeing this */
|
/* We are going to fork so do not bother freeing this */
|
||||||
pm = (Param) paramtab->removenode(paramtab, v->name);
|
pm = (Param) paramtab->removenode(paramtab, name);
|
||||||
if (isset(RESTRICTED) && (pm->flags & PM_RESTRICTED)) {
|
if (isset(RESTRICTED) && (pm->flags & PM_RESTRICTED)) {
|
||||||
zerr("%s: restricted", pm->nam, 0);
|
zerr("%s: restricted", pm->nam, 0);
|
||||||
zsfree(val);
|
zsfree(val);
|
||||||
|
@ -1328,18 +1336,22 @@ addvars(LinkList l, int export)
|
||||||
}
|
}
|
||||||
allexp = opts[ALLEXPORT];
|
allexp = opts[ALLEXPORT];
|
||||||
opts[ALLEXPORT] = 1;
|
opts[ALLEXPORT] = 1;
|
||||||
pm = setsparam(v->name, val);
|
pm = setsparam(name, val);
|
||||||
opts[ALLEXPORT] = allexp;
|
opts[ALLEXPORT] = allexp;
|
||||||
} else
|
} else
|
||||||
pm = setsparam(v->name, val);
|
pm = setsparam(name, val);
|
||||||
if (errflag)
|
if (errflag)
|
||||||
return;
|
return;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ptr = arr = (char **) zalloc(sizeof(char **) * (countlinknodes(vl) + 1));
|
if (vl) {
|
||||||
|
ptr = arr = (char **) zalloc(sizeof(char **) *
|
||||||
|
(countlinknodes(vl) + 1));
|
||||||
|
|
||||||
while (nonempty(vl))
|
while (nonempty(vl))
|
||||||
*ptr++ = ztrdup((char *) ugetnode(vl));
|
*ptr++ = ztrdup((char *) ugetnode(vl));
|
||||||
|
} else
|
||||||
|
ptr = arr = (char **) zalloc(sizeof(char **));
|
||||||
|
|
||||||
*ptr = NULL;
|
*ptr = NULL;
|
||||||
if (xtr) {
|
if (xtr) {
|
||||||
|
@ -1348,7 +1360,7 @@ addvars(LinkList l, int export)
|
||||||
fprintf(stderr, "%s ", *ptr);
|
fprintf(stderr, "%s ", *ptr);
|
||||||
fprintf(stderr, ") ");
|
fprintf(stderr, ") ");
|
||||||
}
|
}
|
||||||
setaparam(v->name, arr);
|
setaparam(name, arr);
|
||||||
if (errflag)
|
if (errflag)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1364,15 +1376,19 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
struct multio *mfds[10];
|
struct multio *mfds[10];
|
||||||
char *text;
|
char *text;
|
||||||
int save[10];
|
int save[10];
|
||||||
int fil, dfil, is_cursh, type, i;
|
int fil, dfil, is_cursh, type, flags, i;
|
||||||
int nullexec = 0, assign = 0, forked = 0;
|
int nullexec = 0, assign = 0, forked = 0;
|
||||||
int is_shfunc = 0, is_builtin = 0, is_exec = 0;
|
int is_shfunc = 0, is_builtin = 0, is_exec = 0;
|
||||||
/* Various flags to the command. */
|
/* Various flags to the command. */
|
||||||
int cflags = 0, checked = 0;
|
int cflags = 0, checked = 0;
|
||||||
|
LinkList vars, redir;
|
||||||
|
|
||||||
doneps4 = 0;
|
doneps4 = 0;
|
||||||
args = cmd->args;
|
args = listdup(cmd->args);
|
||||||
type = cmd->type;
|
type = cmd->type;
|
||||||
|
flags = cmd->flags;
|
||||||
|
redir = dupheaplist(cmd->redir);
|
||||||
|
vars = cmd->vars;
|
||||||
|
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
save[i] = -2;
|
save[i] = -2;
|
||||||
|
@ -1381,7 +1397,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
|
|
||||||
/* If the command begins with `%', then assume it is a *
|
/* If the command begins with `%', then assume it is a *
|
||||||
* reference to a job in the job table. */
|
* reference to a job in the job table. */
|
||||||
if (type == SIMPLE && nonempty(args) &&
|
if (type == SIMPLE && args && nonempty(args) &&
|
||||||
*(char *)peekfirst(args) == '%') {
|
*(char *)peekfirst(args) == '%') {
|
||||||
pushnode(args, dupstring((how & Z_DISOWN)
|
pushnode(args, dupstring((how & Z_DISOWN)
|
||||||
? "disown" : (how & Z_ASYNC) ? "bg" : "fg"));
|
? "disown" : (how & Z_ASYNC) ? "bg" : "fg"));
|
||||||
|
@ -1393,7 +1409,8 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
* job currently in the job table. If it does, then we treat it *
|
* job currently in the job table. If it does, then we treat it *
|
||||||
* as a command to resume this job. */
|
* as a command to resume this job. */
|
||||||
if (isset(AUTORESUME) && type == SIMPLE && (how & Z_SYNC) &&
|
if (isset(AUTORESUME) && type == SIMPLE && (how & Z_SYNC) &&
|
||||||
nonempty(args) && empty(cmd->redir) && !input &&
|
args && nonempty(args) &&
|
||||||
|
(!cmd->redir || empty(cmd->redir)) && !input &&
|
||||||
!nextnode(firstnode(args))) {
|
!nextnode(firstnode(args))) {
|
||||||
if (unset(NOTIFY))
|
if (unset(NOTIFY))
|
||||||
scanjobs();
|
scanjobs();
|
||||||
|
@ -1407,7 +1424,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
* only works in simple cases. has_token() is called to make sure *
|
* only works in simple cases. has_token() is called to make sure *
|
||||||
* this really is a simple case. */
|
* this really is a simple case. */
|
||||||
if (type == SIMPLE) {
|
if (type == SIMPLE) {
|
||||||
while (nonempty(args)) {
|
while (args && nonempty(args)) {
|
||||||
char *cmdarg = (char *) peekfirst(args);
|
char *cmdarg = (char *) peekfirst(args);
|
||||||
checked = !has_token(cmdarg);
|
checked = !has_token(cmdarg);
|
||||||
if (!checked)
|
if (!checked)
|
||||||
|
@ -1444,7 +1461,8 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do prefork substitutions */
|
/* Do prefork substitutions */
|
||||||
prefork(args, (assign || isset(MAGICEQUALSUBST)) ? PF_TYPESET : 0);
|
if (args)
|
||||||
|
prefork(args, (assign || isset(MAGICEQUALSUBST)) ? PF_TYPESET : 0);
|
||||||
|
|
||||||
if (type == SIMPLE) {
|
if (type == SIMPLE) {
|
||||||
int unglobbed = 0;
|
int unglobbed = 0;
|
||||||
|
@ -1453,7 +1471,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
char *cmdarg;
|
char *cmdarg;
|
||||||
|
|
||||||
if (!(cflags & BINF_NOGLOB))
|
if (!(cflags & BINF_NOGLOB))
|
||||||
while (!checked && !errflag && nonempty(args) &&
|
while (!checked && !errflag && args && nonempty(args) &&
|
||||||
has_token((char *) peekfirst(args)))
|
has_token((char *) peekfirst(args)))
|
||||||
glob(args, firstnode(args));
|
glob(args, firstnode(args));
|
||||||
else if (!unglobbed) {
|
else if (!unglobbed) {
|
||||||
|
@ -1465,12 +1483,12 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
/* Current shell should not fork unless the *
|
/* Current shell should not fork unless the *
|
||||||
* exec occurs at the end of a pipeline. */
|
* exec occurs at the end of a pipeline. */
|
||||||
if ((cflags & BINF_EXEC) && last1 == 2)
|
if ((cflags & BINF_EXEC) && last1 == 2)
|
||||||
cmd->flags |= CFLAG_EXEC;
|
flags |= CFLAG_EXEC;
|
||||||
|
|
||||||
/* Empty command */
|
/* Empty command */
|
||||||
if (empty(args)) {
|
if (!args || empty(args)) {
|
||||||
if (nonempty(cmd->redir)) {
|
if (redir && nonempty(redir)) {
|
||||||
if (cmd->flags & CFLAG_EXEC) {
|
if (flags & CFLAG_EXEC) {
|
||||||
/* Was this "exec < foobar"? */
|
/* Was this "exec < foobar"? */
|
||||||
nullexec = 1;
|
nullexec = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -1480,17 +1498,23 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
errflag = lastval = 1;
|
errflag = lastval = 1;
|
||||||
return;
|
return;
|
||||||
} else if (readnullcmd && *readnullcmd &&
|
} else if (readnullcmd && *readnullcmd &&
|
||||||
((Redir) peekfirst(cmd->redir))->type == READ &&
|
((Redir) peekfirst(redir))->type == READ &&
|
||||||
!nextnode(firstnode(cmd->redir))) {
|
!nextnode(firstnode(redir))) {
|
||||||
|
if (!args)
|
||||||
|
args = newlinklist();
|
||||||
addlinknode(args, dupstring(readnullcmd));
|
addlinknode(args, dupstring(readnullcmd));
|
||||||
} else
|
} else {
|
||||||
|
if (!args)
|
||||||
|
args = newlinklist();
|
||||||
addlinknode(args, dupstring(nullcmd));
|
addlinknode(args, dupstring(nullcmd));
|
||||||
|
}
|
||||||
} else if ((cflags & BINF_PREFIX) && (cflags & BINF_COMMAND)) {
|
} else if ((cflags & BINF_PREFIX) && (cflags & BINF_COMMAND)) {
|
||||||
lastval = 0;
|
lastval = 0;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
cmdoutval = 0;
|
cmdoutval = 0;
|
||||||
addvars(cmd->vars, 0);
|
if (vars)
|
||||||
|
addvars(vars, 0);
|
||||||
if (errflag)
|
if (errflag)
|
||||||
lastval = errflag;
|
lastval = errflag;
|
||||||
else
|
else
|
||||||
|
@ -1502,7 +1526,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (isset(RESTRICTED) && (cflags & BINF_EXEC) &&
|
} else if (isset(RESTRICTED) && (cflags & BINF_EXEC) &&
|
||||||
(cmd->flags & CFLAG_EXEC)) {
|
(flags & CFLAG_EXEC)) {
|
||||||
zerrnam("exec", "%s: restricted", (char *) getdata(firstnode(args)), 0);
|
zerrnam("exec", "%s: restricted", (char *) getdata(firstnode(args)), 0);
|
||||||
lastval = 1;
|
lastval = 1;
|
||||||
return;
|
return;
|
||||||
|
@ -1548,22 +1572,32 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the text associated with this command. */
|
/* Get the text associated with this command. */
|
||||||
if (jobbing || (how & Z_TIMED))
|
if (!sfcontext && (jobbing || (how & Z_TIMED)))
|
||||||
text = getjobtext((void *) cmd);
|
text = getjobtext((void *) cmd);
|
||||||
else
|
else
|
||||||
text = NULL;
|
text = NULL;
|
||||||
|
|
||||||
/* Set up special parameter $_ */
|
/* Set up special parameter $_ */
|
||||||
zsfree(underscore);
|
if (args && nonempty(args)) {
|
||||||
if (nonempty(args)
|
char *u = (char *) getdata(lastnode(args));
|
||||||
&& (underscore = ztrdup((char *) getdata(lastnode(args)))))
|
|
||||||
untokenize(underscore);
|
if (u) {
|
||||||
else
|
int ul = strlen(u);
|
||||||
underscore = ztrdup("");
|
|
||||||
|
if (ul >= underscorelen) {
|
||||||
|
zfree(underscore, underscorelen);
|
||||||
|
underscore = (char *) zalloc(underscorelen = ul + 32);
|
||||||
|
}
|
||||||
|
strcpy(underscore, u);
|
||||||
|
} else
|
||||||
|
*underscore = '\0';
|
||||||
|
} else
|
||||||
|
*underscore = '\0';
|
||||||
|
|
||||||
/* Warn about "rm *" */
|
/* Warn about "rm *" */
|
||||||
if (type == SIMPLE && interact && unset(RMSTARSILENT)
|
if (type == SIMPLE && interact && unset(RMSTARSILENT)
|
||||||
&& isset(SHINSTDIN) && nonempty(args) && nextnode(firstnode(args))
|
&& isset(SHINSTDIN) && args && nonempty(args)
|
||||||
|
&& nextnode(firstnode(args))
|
||||||
&& !strcmp(peekfirst(args), "rm")) {
|
&& !strcmp(peekfirst(args), "rm")) {
|
||||||
LinkNode node, next;
|
LinkNode node, next;
|
||||||
|
|
||||||
|
@ -1596,11 +1630,11 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
if (type == SIMPLE && !nullexec) {
|
if (type == SIMPLE && !nullexec) {
|
||||||
char *s;
|
char *s;
|
||||||
char trycd = (isset(AUTOCD) && isset(SHINSTDIN)
|
char trycd = (isset(AUTOCD) && isset(SHINSTDIN)
|
||||||
&& empty(cmd->redir) && !empty(args)
|
&& (!redir || empty(redir)) && args && !empty(args)
|
||||||
&& !nextnode(firstnode(args))
|
&& !nextnode(firstnode(args))
|
||||||
&& *(char *)peekfirst(args));
|
&& *(char *)peekfirst(args));
|
||||||
|
|
||||||
DPUTS(empty(args), "BUG: empty(args) in exec.c");
|
DPUTS((!args || empty(args)), "BUG: empty(args) in exec.c");
|
||||||
if (!hn) {
|
if (!hn) {
|
||||||
/* Resolve external commands */
|
/* Resolve external commands */
|
||||||
char *cmdarg = (char *) peekfirst(args);
|
char *cmdarg = (char *) peekfirst(args);
|
||||||
|
@ -1652,7 +1686,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
* current shell. *
|
* current shell. *
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
if ((how & Z_ASYNC) || (!(cmd->flags & CFLAG_EXEC) &&
|
if ((how & Z_ASYNC) || (!(flags & CFLAG_EXEC) &&
|
||||||
(((is_builtin || is_shfunc) && output) ||
|
(((is_builtin || is_shfunc) && output) ||
|
||||||
(!is_cursh && (last1 != 1 || sigtrapped[SIGZERR] ||
|
(!is_cursh && (last1 != 1 || sigtrapped[SIGZERR] ||
|
||||||
sigtrapped[SIGEXIT] || havefiles()))))) {
|
sigtrapped[SIGEXIT] || havefiles()))))) {
|
||||||
|
@ -1677,10 +1711,13 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
#endif
|
#endif
|
||||||
if (how & Z_ASYNC) {
|
if (how & Z_ASYNC) {
|
||||||
lastpid = (zlong) pid;
|
lastpid = (zlong) pid;
|
||||||
} else if (!jobtab[thisjob].stty_in_env && nonempty(cmd->vars)) {
|
} else if (!jobtab[thisjob].stty_in_env &&
|
||||||
|
vars && nonempty(vars)) {
|
||||||
/* search for STTY=... */
|
/* search for STTY=... */
|
||||||
while (nonempty(cmd->vars))
|
LinkNode n;
|
||||||
if (!strcmp(((Varasg) ugetnode(cmd->vars))->name, "STTY")) {
|
|
||||||
|
for (n = firstnode(vars); n; incnode(n))
|
||||||
|
if (!strcmp(((Varasg) getdata(n))->name, "STTY")) {
|
||||||
jobtab[thisjob].stty_in_env = 1;
|
jobtab[thisjob].stty_in_env = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1713,7 +1750,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
is_exec = 1;
|
is_exec = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cflags & BINF_NOGLOB))
|
if (args && !(cflags & BINF_NOGLOB))
|
||||||
globlist(args);
|
globlist(args);
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
lastval = 1;
|
lastval = 1;
|
||||||
|
@ -1727,11 +1764,12 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
addfd(forked, save, mfds, 1, output, 1);
|
addfd(forked, save, mfds, 1, output, 1);
|
||||||
|
|
||||||
/* Do process substitutions */
|
/* Do process substitutions */
|
||||||
spawnpipes(cmd->redir);
|
if (redir)
|
||||||
|
spawnpipes(redir);
|
||||||
|
|
||||||
/* Do io redirections */
|
/* Do io redirections */
|
||||||
while (nonempty(cmd->redir)) {
|
while (redir && nonempty(redir)) {
|
||||||
fn = (Redir) ugetnode(cmd->redir);
|
fn = (Redir) ugetnode(redir);
|
||||||
DPUTS(fn->type == HEREDOC || fn->type == HEREDOCDASH,
|
DPUTS(fn->type == HEREDOC || fn->type == HEREDOCDASH,
|
||||||
"BUG: unexpanded here document");
|
"BUG: unexpanded here document");
|
||||||
if (fn->type == INPIPE) {
|
if (fn->type == INPIPE) {
|
||||||
|
@ -1749,7 +1787,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
}
|
}
|
||||||
addfd(forked, save, mfds, fn->fd1, fn->fd2, 1);
|
addfd(forked, save, mfds, fn->fd1, fn->fd2, 1);
|
||||||
} else {
|
} else {
|
||||||
if (fn->type != HERESTR && xpandredir(fn, cmd->redir))
|
if (fn->type != HERESTR && xpandredir(fn, redir))
|
||||||
continue;
|
continue;
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
closemnodes(mfds);
|
closemnodes(mfds);
|
||||||
|
@ -1870,15 +1908,15 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
if (is_exec)
|
if (is_exec)
|
||||||
entersubsh(how, type != SUBSH ? 2 : 1, 1);
|
entersubsh(how, type != SUBSH ? 2 : 1, 1);
|
||||||
if (type >= CURSH) {
|
if (type >= CURSH) {
|
||||||
static int (*func[]) _((Cmd)) = {
|
static int (*func[]) _((Cmd, LinkList, int)) = {
|
||||||
execcursh, exectime, execfuncdef, execfor, execwhile,
|
execcursh, exectime, execfuncdef, execfor, execwhile,
|
||||||
execrepeat, execif, execcase, execselect, execcond,
|
execrepeat, execif, execcase, execselect, execcond,
|
||||||
execarith, execautofn
|
execarith, execautofn
|
||||||
};
|
};
|
||||||
|
|
||||||
if (last1 == 1)
|
if (last1 == 1)
|
||||||
cmd->flags |= CFLAG_EXEC;
|
flags |= CFLAG_EXEC;
|
||||||
lastval = (func[type - CURSH]) (cmd);
|
lastval = (func[type - CURSH]) (cmd, args, flags);
|
||||||
} else if (is_builtin || is_shfunc) {
|
} else if (is_builtin || is_shfunc) {
|
||||||
LinkList restorelist = 0, removelist = 0;
|
LinkList restorelist = 0, removelist = 0;
|
||||||
/* builtin or shell function */
|
/* builtin or shell function */
|
||||||
|
@ -1889,11 +1927,11 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
!(hn->flags & BINF_PSPECIAL))))
|
!(hn->flags & BINF_PSPECIAL))))
|
||||||
save_params(cmd, &restorelist, &removelist);
|
save_params(cmd, &restorelist, &removelist);
|
||||||
|
|
||||||
if (cmd->vars) {
|
if (vars) {
|
||||||
/* Export this if the command is a shell function,
|
/* Export this if the command is a shell function,
|
||||||
* but not if it's a builtin.
|
* but not if it's a builtin.
|
||||||
*/
|
*/
|
||||||
addvars(cmd->vars, is_shfunc);
|
addvars(vars, is_shfunc);
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
restore_params(restorelist, removelist);
|
restore_params(restorelist, removelist);
|
||||||
lastval = 1;
|
lastval = 1;
|
||||||
|
@ -1904,6 +1942,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
|
|
||||||
if (is_shfunc) {
|
if (is_shfunc) {
|
||||||
/* It's a shell function */
|
/* It's a shell function */
|
||||||
|
|
||||||
#ifdef PATH_DEV_FD
|
#ifdef PATH_DEV_FD
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -1914,7 +1953,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
if (subsh_close >= 0)
|
if (subsh_close >= 0)
|
||||||
zclose(subsh_close);
|
zclose(subsh_close);
|
||||||
subsh_close = -1;
|
subsh_close = -1;
|
||||||
execshfunc(cmd, (Shfunc) hn);
|
execshfunc(cmd, (Shfunc) hn, args);
|
||||||
#ifdef PATH_DEV_FD
|
#ifdef PATH_DEV_FD
|
||||||
for (i = 10; i <= max_zsh_fd; i++)
|
for (i = 10; i <= max_zsh_fd; i++)
|
||||||
if (fdtable[i] > 1)
|
if (fdtable[i] > 1)
|
||||||
|
@ -1943,7 +1982,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
clearerr(stdout);
|
clearerr(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd->flags & CFLAG_EXEC) {
|
if (flags & CFLAG_EXEC) {
|
||||||
if (subsh)
|
if (subsh)
|
||||||
_exit(lastval);
|
_exit(lastval);
|
||||||
|
|
||||||
|
@ -1957,7 +1996,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
restore_params(restorelist, removelist);
|
restore_params(restorelist, removelist);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (cmd->flags & CFLAG_EXEC) {
|
if (flags & CFLAG_EXEC) {
|
||||||
setiparam("SHLVL", --shlvl);
|
setiparam("SHLVL", --shlvl);
|
||||||
/* If we are exec'ing a command, and we are not *
|
/* If we are exec'ing a command, and we are not *
|
||||||
* in a subshell, then save the history file. */
|
* in a subshell, then save the history file. */
|
||||||
|
@ -1965,8 +2004,8 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
savehistfile(NULL, 1, HFILE_USE_OPTIONS);
|
savehistfile(NULL, 1, HFILE_USE_OPTIONS);
|
||||||
}
|
}
|
||||||
if (type == SIMPLE) {
|
if (type == SIMPLE) {
|
||||||
if (cmd->vars) {
|
if (vars) {
|
||||||
addvars(cmd->vars, -1);
|
addvars(vars, -1);
|
||||||
if (errflag)
|
if (errflag)
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
@ -1981,7 +2020,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
|
||||||
#endif
|
#endif
|
||||||
execute((Cmdnam) hn, cflags & BINF_DASH);
|
execute((Cmdnam) hn, cflags & BINF_DASH);
|
||||||
} else { /* ( ... ) */
|
} else { /* ( ... ) */
|
||||||
DPUTS(cmd->vars && nonempty(cmd->vars),
|
DPUTS(vars && nonempty(vars),
|
||||||
"BUG: assigment before complex command");
|
"BUG: assigment before complex command");
|
||||||
list_pipe = 0;
|
list_pipe = 0;
|
||||||
if (subsh_close >= 0)
|
if (subsh_close >= 0)
|
||||||
|
@ -2011,7 +2050,11 @@ save_params(Cmd cmd, LinkList *restore_p, LinkList *remove_p)
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
MUSTUSEHEAP("save_params()");
|
MUSTUSEHEAP("save_params()");
|
||||||
|
|
||||||
|
if (!cmd->vars) {
|
||||||
|
*restore_p = *remove_p = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
*restore_p = newlinklist();
|
*restore_p = newlinklist();
|
||||||
*remove_p = newlinklist();
|
*remove_p = newlinklist();
|
||||||
|
|
||||||
|
@ -2283,8 +2326,9 @@ getoutput(char *cmd, int qt)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (list != &dummy_list && !list->right && !list->left->flags &&
|
if (list != &dummy_list && !list->right && !list->left->flags &&
|
||||||
list->left->type == END && list->left->left->type == END &&
|
list->left->type == END && list->left->left->type == END &&
|
||||||
(c = list->left->left->left)->type == SIMPLE && empty(c->args) &&
|
(c = list->left->left->left)->type == SIMPLE &&
|
||||||
empty(c->vars) && nonempty(c->redir) &&
|
(!c->args || empty(c->args)) &&
|
||||||
|
(!c->vars || empty(c->vars)) && c->redir && nonempty(c->redir) &&
|
||||||
!nextnode(firstnode(c->redir)) &&
|
!nextnode(firstnode(c->redir)) &&
|
||||||
(r = (Redir) getdata(firstnode(c->redir)))->fd1 == 0 &&
|
(r = (Redir) getdata(firstnode(c->redir)))->fd1 == 0 &&
|
||||||
r->type == READ) {
|
r->type == READ) {
|
||||||
|
@ -2613,7 +2657,7 @@ extern int tracingcond;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
execcond(Cmd cmd)
|
execcond(Cmd cmd, LinkList args, int flags)
|
||||||
{
|
{
|
||||||
int stat;
|
int stat;
|
||||||
if (isset(XTRACE)) {
|
if (isset(XTRACE)) {
|
||||||
|
@ -2633,18 +2677,19 @@ execcond(Cmd cmd)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
execarith(Cmd cmd)
|
execarith(Cmd cmd, LinkList args, int flags)
|
||||||
{
|
{
|
||||||
char *e;
|
char *e;
|
||||||
zlong val = 0;
|
zlong val = 0;
|
||||||
|
|
||||||
if (isset(XTRACE))
|
if (isset(XTRACE))
|
||||||
fprintf(stderr, "%s((", prompt4 ? prompt4 : "");
|
fprintf(stderr, "%s((", prompt4 ? prompt4 : "");
|
||||||
while ((e = (char *) ugetnode(cmd->args))) {
|
if (args)
|
||||||
if (isset(XTRACE))
|
while ((e = (char *) ugetnode(args))) {
|
||||||
fprintf(stderr, " %s", e);
|
if (isset(XTRACE))
|
||||||
val = matheval(e);
|
fprintf(stderr, " %s", e);
|
||||||
}
|
val = matheval(e);
|
||||||
|
}
|
||||||
if (isset(XTRACE)) {
|
if (isset(XTRACE)) {
|
||||||
fprintf(stderr, " ))\n");
|
fprintf(stderr, " ))\n");
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
@ -2657,7 +2702,7 @@ execarith(Cmd cmd)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
exectime(Cmd cmd)
|
exectime(Cmd cmd, LinkList args, int flags)
|
||||||
{
|
{
|
||||||
int jb;
|
int jb;
|
||||||
|
|
||||||
|
@ -2675,30 +2720,33 @@ exectime(Cmd cmd)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
execfuncdef(Cmd cmd)
|
execfuncdef(Cmd cmd, LinkList args, int flags)
|
||||||
{
|
{
|
||||||
Shfunc shf;
|
Shfunc shf;
|
||||||
char *s;
|
char *s;
|
||||||
int signum;
|
int signum;
|
||||||
|
|
||||||
PERMALLOC {
|
if (args) {
|
||||||
while ((s = (char *) ugetnode(cmd->args))) {
|
PERMALLOC {
|
||||||
shf = (Shfunc) zalloc(sizeof *shf);
|
while ((s = (char *) ugetnode(args))) {
|
||||||
shf->funcdef = (List) dupstruct(cmd->u.list);
|
shf = (Shfunc) zalloc(sizeof *shf);
|
||||||
shf->flags = 0;
|
shf->funcdef = (List) dupstruct(cmd->u.list);
|
||||||
|
shf->flags = 0;
|
||||||
|
|
||||||
/* is this shell function a signal trap? */
|
/* is this shell function a signal trap? */
|
||||||
if (!strncmp(s, "TRAP", 4) && (signum = getsignum(s + 4)) != -1) {
|
if (!strncmp(s, "TRAP", 4) &&
|
||||||
if (settrap(signum, shf->funcdef)) {
|
(signum = getsignum(s + 4)) != -1) {
|
||||||
freestruct(shf->funcdef);
|
if (settrap(signum, shf->funcdef)) {
|
||||||
zfree(shf, sizeof *shf);
|
freestruct(shf->funcdef);
|
||||||
LASTALLOC_RETURN 1;
|
zfree(shf, sizeof *shf);
|
||||||
}
|
LASTALLOC_RETURN 1;
|
||||||
sigtrapped[signum] |= ZSIG_FUNC;
|
}
|
||||||
}
|
sigtrapped[signum] |= ZSIG_FUNC;
|
||||||
shfunctab->addnode(shfunctab, ztrdup(s), shf);
|
}
|
||||||
}
|
shfunctab->addnode(shfunctab, ztrdup(s), shf);
|
||||||
} LASTALLOC;
|
}
|
||||||
|
} LASTALLOC;
|
||||||
|
}
|
||||||
if(isset(HISTNOFUNCTIONS))
|
if(isset(HISTNOFUNCTIONS))
|
||||||
remhist();
|
remhist();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2708,7 +2756,7 @@ execfuncdef(Cmd cmd)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static void
|
static void
|
||||||
execshfunc(Cmd cmd, Shfunc shf)
|
execshfunc(Cmd cmd, Shfunc shf, LinkList args)
|
||||||
{
|
{
|
||||||
LinkList last_file_list = NULL;
|
LinkList last_file_list = NULL;
|
||||||
|
|
||||||
|
@ -2726,16 +2774,17 @@ execshfunc(Cmd cmd, Shfunc shf)
|
||||||
if (isset(XTRACE)) {
|
if (isset(XTRACE)) {
|
||||||
LinkNode lptr;
|
LinkNode lptr;
|
||||||
fprintf(stderr, "%s", prompt4 ? prompt4 : prompt4);
|
fprintf(stderr, "%s", prompt4 ? prompt4 : prompt4);
|
||||||
for (lptr = firstnode(cmd->args); lptr; incnode(lptr)) {
|
if (args)
|
||||||
if (lptr != firstnode(cmd->args))
|
for (lptr = firstnode(args); lptr; incnode(lptr)) {
|
||||||
fputc(' ', stderr);
|
if (lptr != firstnode(args))
|
||||||
fprintf(stderr, "%s", (char *)getdata(lptr));
|
fputc(' ', stderr);
|
||||||
}
|
fprintf(stderr, "%s", (char *)getdata(lptr));
|
||||||
|
}
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
doshfunc(shf->nam, shf->funcdef, cmd->args, shf->flags, 0);
|
doshfunc(shf->nam, shf->funcdef, args, shf->flags, 0);
|
||||||
|
|
||||||
if (!list_pipe)
|
if (!list_pipe)
|
||||||
deletefilelist(last_file_list);
|
deletefilelist(last_file_list);
|
||||||
|
@ -2749,10 +2798,16 @@ execshfunc(Cmd cmd, Shfunc shf)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
execautofn(Cmd cmd)
|
execautofn(Cmd cmd, LinkList args, int flags)
|
||||||
{
|
{
|
||||||
Shfunc shf = cmd->u.autofn->shf;
|
Shfunc shf = cmd->u.autofn->shf;
|
||||||
List l = getfpfunc(shf->nam);
|
int noalias = noaliases;
|
||||||
|
List l;
|
||||||
|
|
||||||
|
noaliases = (shf->flags & PM_UNALIASED);
|
||||||
|
l = getfpfunc(shf->nam);
|
||||||
|
noaliases = noalias;
|
||||||
|
|
||||||
if(l == &dummy_list) {
|
if(l == &dummy_list) {
|
||||||
zerr("%s: function definition file not found", shf->nam, 0);
|
zerr("%s: function definition file not found", shf->nam, 0);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -2773,9 +2828,7 @@ execautofn(Cmd cmd)
|
||||||
} LASTALLOC;
|
} LASTALLOC;
|
||||||
shf->flags &= ~PM_UNDEFINED;
|
shf->flags &= ~PM_UNDEFINED;
|
||||||
}
|
}
|
||||||
HEAPALLOC {
|
execlist(shf->funcdef, 1, 0);
|
||||||
execlist(dupstruct(shf->funcdef), 1, 0);
|
|
||||||
} LASTALLOC;
|
|
||||||
return lastval;
|
return lastval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2822,7 +2875,8 @@ doshfunc(char *name, List list, LinkList doshargs, int flags, int noreturnval)
|
||||||
LinkNode node;
|
LinkNode node;
|
||||||
|
|
||||||
node = doshargs->first;
|
node = doshargs->first;
|
||||||
pparams = x = (char **) zcalloc(((sizeof *x) * (1 + countlinknodes(doshargs))));
|
pparams = x = (char **) zcalloc(((sizeof *x) *
|
||||||
|
(1 + countlinknodes(doshargs))));
|
||||||
if (isset(FUNCTIONARGZERO)) {
|
if (isset(FUNCTIONARGZERO)) {
|
||||||
oargv0 = argzero;
|
oargv0 = argzero;
|
||||||
argzero = ztrdup((char *) node->dat);
|
argzero = ztrdup((char *) node->dat);
|
||||||
|
@ -2901,7 +2955,7 @@ void
|
||||||
runshfunc(List list, FuncWrap wrap, char *name)
|
runshfunc(List list, FuncWrap wrap, char *name)
|
||||||
{
|
{
|
||||||
int cont;
|
int cont;
|
||||||
char *ou;
|
VARARR(char, ou, underscorelen);
|
||||||
|
|
||||||
while (wrap) {
|
while (wrap) {
|
||||||
wrap->module->wrapper++;
|
wrap->module->wrapper++;
|
||||||
|
@ -2917,11 +2971,9 @@ runshfunc(List list, FuncWrap wrap, char *name)
|
||||||
wrap = wrap->next;
|
wrap = wrap->next;
|
||||||
}
|
}
|
||||||
startparamscope();
|
startparamscope();
|
||||||
ou = underscore;
|
strcpy(ou, underscore);
|
||||||
underscore = ztrdup(underscore);
|
execlist(list, 1, 0);
|
||||||
execlist(dupstruct(list), 1, 0);
|
strcpy(underscore, ou);
|
||||||
zsfree(underscore);
|
|
||||||
underscore = ou;
|
|
||||||
endparamscope();
|
endparamscope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2949,20 +3001,18 @@ getfpfunc(char *s)
|
||||||
unmetafy(buf, NULL);
|
unmetafy(buf, NULL);
|
||||||
if (!access(buf, R_OK) && (fd = open(buf, O_RDONLY | O_NOCTTY)) != -1) {
|
if (!access(buf, R_OK) && (fd = open(buf, O_RDONLY | O_NOCTTY)) != -1) {
|
||||||
if ((len = lseek(fd, 0, 2)) != -1) {
|
if ((len = lseek(fd, 0, 2)) != -1) {
|
||||||
|
d = (char *) zalloc(len + 1);
|
||||||
lseek(fd, 0, 0);
|
lseek(fd, 0, 0);
|
||||||
d = (char *) zcalloc(len + 1);
|
|
||||||
if (read(fd, d, len) == len) {
|
if (read(fd, d, len) == len) {
|
||||||
close(fd);
|
close(fd);
|
||||||
|
d[len] = '\0';
|
||||||
d = metafy(d, len, META_REALLOC);
|
d = metafy(d, len, META_REALLOC);
|
||||||
HEAPALLOC {
|
HEAPALLOC {
|
||||||
r = parse_string(d);
|
r = parse_string(d);
|
||||||
} LASTALLOC;
|
} LASTALLOC;
|
||||||
zfree(d, len + 1);
|
|
||||||
return r;
|
return r;
|
||||||
} else {
|
} else
|
||||||
zfree(d, len + 1);
|
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
@ -2995,9 +3045,10 @@ stripkshdef(List l, char *name)
|
||||||
if(p->right)
|
if(p->right)
|
||||||
return l;
|
return l;
|
||||||
c = p->left;
|
c = p->left;
|
||||||
if(c->type != FUNCDEF || c->flags ||
|
if (c->type != FUNCDEF || c->flags ||
|
||||||
nonempty(c->redir) || nonempty(c->vars) ||
|
(c->redir && nonempty(c->redir)) || (c->vars && nonempty(c->vars)) ||
|
||||||
empty(c->args) || lastnode(c->args) != firstnode(c->args) ||
|
!c->args || empty(c->args) ||
|
||||||
|
lastnode(c->args) != firstnode(c->args) ||
|
||||||
strcmp(name, peekfirst(c->args)))
|
strcmp(name, peekfirst(c->args)))
|
||||||
return l;
|
return l;
|
||||||
return c->u.list;
|
return c->u.list;
|
||||||
|
@ -3076,8 +3127,7 @@ execsave(void)
|
||||||
es->trapreturn = trapreturn;
|
es->trapreturn = trapreturn;
|
||||||
es->noerrs = noerrs;
|
es->noerrs = noerrs;
|
||||||
es->subsh_close = subsh_close;
|
es->subsh_close = subsh_close;
|
||||||
es->underscore = underscore;
|
es->underscore = ztrdup(underscore);
|
||||||
underscore = ztrdup(underscore);
|
|
||||||
es->next = exstack;
|
es->next = exstack;
|
||||||
exstack = es;
|
exstack = es;
|
||||||
noerrs = cmdoutpid = 0;
|
noerrs = cmdoutpid = 0;
|
||||||
|
@ -3105,8 +3155,8 @@ execrestore(void)
|
||||||
trapreturn = exstack->trapreturn;
|
trapreturn = exstack->trapreturn;
|
||||||
noerrs = exstack->noerrs;
|
noerrs = exstack->noerrs;
|
||||||
subsh_close = exstack->subsh_close;
|
subsh_close = exstack->subsh_close;
|
||||||
zsfree(underscore);
|
strcpy(underscore, exstack->underscore);
|
||||||
underscore = exstack->underscore;
|
zsfree(exstack->underscore);
|
||||||
en = exstack->next;
|
en = exstack->next;
|
||||||
free(exstack);
|
free(exstack);
|
||||||
exstack = en;
|
exstack = en;
|
||||||
|
|
22
Src/glob.c
22
Src/glob.c
|
@ -744,7 +744,7 @@ parsecomp(int gflag)
|
||||||
pptr++;
|
pptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*pptr == Inpar && pptr[1] == Pound) {
|
if (*pptr == Inpar && pptr[1] == Pound && isset(EXTENDEDGLOB)) {
|
||||||
/* Found some globbing flags */
|
/* Found some globbing flags */
|
||||||
char *eptr = pptr;
|
char *eptr = pptr;
|
||||||
if (kshfunc != KF_NONE)
|
if (kshfunc != KF_NONE)
|
||||||
|
@ -3432,17 +3432,17 @@ tokenize(char *s)
|
||||||
void
|
void
|
||||||
remnulargs(char *s)
|
remnulargs(char *s)
|
||||||
{
|
{
|
||||||
int nl = *s;
|
if (*s) {
|
||||||
char *t = s;
|
char *t = s, *p = s, c;
|
||||||
|
|
||||||
while (*s)
|
while ((c = *s++))
|
||||||
if (INULL(*s))
|
if (!INULL(c))
|
||||||
chuck(s);
|
*p++ = c;
|
||||||
else
|
*p = '\0';
|
||||||
s++;
|
if (!*t) {
|
||||||
if (!*t && nl) {
|
t[0] = Nularg;
|
||||||
t[0] = Nularg;
|
t[1] = '\0';
|
||||||
t[1] = '\0';
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -880,7 +880,7 @@ printshfuncnode(HashNode hn, int printflags)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = getpermtext((void *) dupstruct((void *) f->funcdef));
|
t = getpermtext((void *) f->funcdef);
|
||||||
quotedzputs(f->nam, stdout);
|
quotedzputs(f->nam, stdout);
|
||||||
printf(" () {\n\t");
|
printf(" () {\n\t");
|
||||||
zputs(t, stdout);
|
zputs(t, stdout);
|
||||||
|
@ -1327,7 +1327,7 @@ addhistnode(HashTable ht, char *nam, void *nodeptr)
|
||||||
{
|
{
|
||||||
HashNode oldnode = addhashnode2(ht, nam, nodeptr);
|
HashNode oldnode = addhashnode2(ht, nam, nodeptr);
|
||||||
Histent he = (Histent)nodeptr;
|
Histent he = (Histent)nodeptr;
|
||||||
if (oldnode && oldnode != nodeptr) {
|
if (oldnode && oldnode != (HashNode)nodeptr) {
|
||||||
if (he->flags & HIST_MAKEUNIQUE
|
if (he->flags & HIST_MAKEUNIQUE
|
||||||
|| (he->flags & HIST_FOREIGN && (Histent)oldnode == he->up)) {
|
|| (he->flags & HIST_FOREIGN && (Histent)oldnode == he->up)) {
|
||||||
he->flags |= HIST_DUP;
|
he->flags |= HIST_DUP;
|
||||||
|
|
110
Src/hist.c
110
Src/hist.c
|
@ -30,6 +30,27 @@
|
||||||
#include "zsh.mdh"
|
#include "zsh.mdh"
|
||||||
#include "hist.pro"
|
#include "hist.pro"
|
||||||
|
|
||||||
|
/* Functions to call for getting/ungetting a character and for history
|
||||||
|
* word control. */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
int (*hgetc) _((void));
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void (*hungetc) _((int));
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void (*hwaddc) _((int));
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void (*hwbegin) _((int));
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void (*hwend) _((void));
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void (*addtoline) _((int));
|
||||||
|
|
||||||
/* != 0 means history substitution is turned off */
|
/* != 0 means history substitution is turned off */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
@ -159,12 +180,11 @@ int hlinesz;
|
||||||
/* default event (usually curhist-1, that is, "!!") */
|
/* default event (usually curhist-1, that is, "!!") */
|
||||||
|
|
||||||
static int defev;
|
static int defev;
|
||||||
|
|
||||||
/* add a character to the current history word */
|
/* add a character to the current history word */
|
||||||
|
|
||||||
/**/
|
static void
|
||||||
void
|
ihwaddc(int c)
|
||||||
hwaddc(int c)
|
|
||||||
{
|
{
|
||||||
/* Only if history line exists and lexing has not finished. */
|
/* Only if history line exists and lexing has not finished. */
|
||||||
if (chline && !(errflag || lexstop)) {
|
if (chline && !(errflag || lexstop)) {
|
||||||
|
@ -182,7 +202,7 @@ hwaddc(int c)
|
||||||
if (hptr - chline >= hlinesz) {
|
if (hptr - chline >= hlinesz) {
|
||||||
int oldsiz = hlinesz;
|
int oldsiz = hlinesz;
|
||||||
|
|
||||||
chline = realloc(chline, hlinesz = oldsiz + 16);
|
chline = realloc(chline, hlinesz = oldsiz + 64);
|
||||||
hptr = chline + oldsiz;
|
hptr = chline + oldsiz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,12 +212,12 @@ hwaddc(int c)
|
||||||
* zsh expands history (see doexpandhist() in zle_tricky.c). It also *
|
* zsh expands history (see doexpandhist() in zle_tricky.c). It also *
|
||||||
* calculates the new cursor position after the expansion. It is called *
|
* calculates the new cursor position after the expansion. It is called *
|
||||||
* from hgetc() and from gettok() in lex.c for characters in comments. */
|
* from hgetc() and from gettok() in lex.c for characters in comments. */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
addtoline(int c)
|
iaddtoline(int c)
|
||||||
{
|
{
|
||||||
if (! expanding || lexstop)
|
if (!expanding || lexstop)
|
||||||
return;
|
return;
|
||||||
if (qbang && c == bangchar && stophist < 2) {
|
if (qbang && c == bangchar && stophist < 2) {
|
||||||
exlast--;
|
exlast--;
|
||||||
|
@ -216,9 +236,8 @@ addtoline(int c)
|
||||||
line[cs++] = itok(c) ? ztokens[c - Pound] : c;
|
line[cs++] = itok(c) ? ztokens[c - Pound] : c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
static int
|
||||||
int
|
ihgetc(void)
|
||||||
hgetc(void)
|
|
||||||
{
|
{
|
||||||
int c = ingetc();
|
int c = ingetc();
|
||||||
|
|
||||||
|
@ -234,7 +253,7 @@ hgetc(void)
|
||||||
}
|
}
|
||||||
if ((inbufflags & INP_HIST) && !stophist) {
|
if ((inbufflags & INP_HIST) && !stophist) {
|
||||||
/* the current character c came from a history expansion *
|
/* the current character c came from a history expansion *
|
||||||
* (inbufflags && INP_HIST) and history is not disabled *
|
* (inbufflags & INP_HIST) and history is not disabled *
|
||||||
* (e.g. we are not inside single quotes). In that case, \! *
|
* (e.g. we are not inside single quotes). In that case, \! *
|
||||||
* should be treated as ! (since this \! came from a previous *
|
* should be treated as ! (since this \! came from a previous *
|
||||||
* history line where \ was used to escape the bang). So if *
|
* history line where \ was used to escape the bang). So if *
|
||||||
|
@ -606,9 +625,8 @@ histsubchar(int c)
|
||||||
/* unget a char and remove it from chline. It can only be used *
|
/* unget a char and remove it from chline. It can only be used *
|
||||||
* to unget a character returned by hgetc. */
|
* to unget a character returned by hgetc. */
|
||||||
|
|
||||||
/**/
|
static void
|
||||||
void
|
ihungetc(int c)
|
||||||
hungetc(int c)
|
|
||||||
{
|
{
|
||||||
int doit = 1;
|
int doit = 1;
|
||||||
|
|
||||||
|
@ -641,10 +659,10 @@ hungetc(int c)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
strinbeg(void)
|
strinbeg(int dohist)
|
||||||
{
|
{
|
||||||
strin++;
|
strin++;
|
||||||
hbegin();
|
hbegin(dohist);
|
||||||
lexinit();
|
lexinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,17 +679,49 @@ strinend(void)
|
||||||
histdone = 0;
|
histdone = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* dummy functions to use instead of hwaddc(), hwbegin(), and hwend() when
|
||||||
|
* they aren't needed */
|
||||||
|
|
||||||
|
static void
|
||||||
|
nohw(int c)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nohwe(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/* initialize the history mechanism */
|
/* initialize the history mechanism */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
hbegin(void)
|
hbegin(int dohist)
|
||||||
{
|
{
|
||||||
isfirstln = isfirstch = 1;
|
isfirstln = isfirstch = 1;
|
||||||
errflag = histdone = spaceflag = 0;
|
errflag = histdone = spaceflag = 0;
|
||||||
stophist = (!interact || unset(BANGHIST) || unset(SHINSTDIN)) << 1;
|
stophist = (dohist ? ((!interact || unset(SHINSTDIN)) << 1) : 2);
|
||||||
chline = hptr = zcalloc(hlinesz = 16);
|
if (stophist == 2 || (inbufflags & INP_ALIAS)) {
|
||||||
chwords = zalloc((chwordlen = 16)*sizeof(short));
|
chline = hptr = NULL;
|
||||||
|
hlinesz = 0;
|
||||||
|
chwords = NULL;
|
||||||
|
chwordlen = 0;
|
||||||
|
hgetc = ingetc;
|
||||||
|
hungetc = inungetc;
|
||||||
|
hwaddc = nohw;
|
||||||
|
hwbegin = nohw;
|
||||||
|
hwend = nohwe;
|
||||||
|
addtoline = nohw;
|
||||||
|
} else {
|
||||||
|
chline = hptr = zcalloc(hlinesz = 64);
|
||||||
|
chwords = zalloc((chwordlen = 64) * sizeof(short));
|
||||||
|
hgetc = ihgetc;
|
||||||
|
hungetc = ihungetc;
|
||||||
|
hwaddc = ihwaddc;
|
||||||
|
hwbegin = ihwbegin;
|
||||||
|
hwend = ihwend;
|
||||||
|
addtoline = iaddtoline;
|
||||||
|
}
|
||||||
chwordpos = 0;
|
chwordpos = 0;
|
||||||
|
|
||||||
if (histactive & HA_JUNKED)
|
if (histactive & HA_JUNKED)
|
||||||
|
@ -864,7 +914,8 @@ hend(void)
|
||||||
int flag, save = 1;
|
int flag, save = 1;
|
||||||
char *hf = getsparam("HISTFILE");
|
char *hf = getsparam("HISTFILE");
|
||||||
|
|
||||||
DPUTS(!chline, "BUG: chline is NULL in hend()");
|
DPUTS(stophist != 2 && !(inbufflags & INP_ALIAS) && !chline,
|
||||||
|
"BUG: chline is NULL in hend()");
|
||||||
if (histdone & HISTFLAG_SETTY)
|
if (histdone & HISTFLAG_SETTY)
|
||||||
settyinfo(&shttyinfo);
|
settyinfo(&shttyinfo);
|
||||||
if (!(histactive & HA_NOINC)) {
|
if (!(histactive & HA_NOINC)) {
|
||||||
|
@ -1005,8 +1056,10 @@ int hwgetword = -1;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
hwbegin(int offset)
|
ihwbegin(int offset)
|
||||||
{
|
{
|
||||||
|
if (stophist == 2 || strin)
|
||||||
|
return;
|
||||||
if (chwordpos%2)
|
if (chwordpos%2)
|
||||||
chwordpos--; /* make sure we're on a word start, not end */
|
chwordpos--; /* make sure we're on a word start, not end */
|
||||||
/* If we're expanding an alias, we should overwrite the expansion
|
/* If we're expanding an alias, we should overwrite the expansion
|
||||||
|
@ -1023,15 +1076,18 @@ hwbegin(int offset)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
hwend(void)
|
ihwend(void)
|
||||||
{
|
{
|
||||||
|
if (stophist == 2 || strin)
|
||||||
|
return;
|
||||||
if (chwordpos%2 && chline) {
|
if (chwordpos%2 && chline) {
|
||||||
/* end of word reached and we've already begun a word */
|
/* end of word reached and we've already begun a word */
|
||||||
if (hptr > chline + chwords[chwordpos-1]) {
|
if (hptr > chline + chwords[chwordpos-1]) {
|
||||||
chwords[chwordpos++] = hptr - chline;
|
chwords[chwordpos++] = hptr - chline;
|
||||||
if (chwordpos >= chwordlen) {
|
if (chwordpos >= chwordlen) {
|
||||||
chwords = (short *) realloc(chwords,
|
chwords = (short *) realloc(chwords,
|
||||||
(chwordlen += 16)*sizeof(short));
|
(chwordlen += 32) *
|
||||||
|
sizeof(short));
|
||||||
}
|
}
|
||||||
if (hwgetword > -1) {
|
if (hwgetword > -1) {
|
||||||
/* We want to reuse the current word position */
|
/* We want to reuse the current word position */
|
||||||
|
@ -1606,7 +1662,7 @@ readhistfile(char *fn, int err, int readflags)
|
||||||
else if (!lockhistfile(fn, 1))
|
else if (!lockhistfile(fn, 1))
|
||||||
return;
|
return;
|
||||||
if ((in = fopen(unmeta(fn), "r"))) {
|
if ((in = fopen(unmeta(fn), "r"))) {
|
||||||
nwordlist = 16;
|
nwordlist = 64;
|
||||||
wordlist = (short *)zalloc(nwordlist*sizeof(short));
|
wordlist = (short *)zalloc(nwordlist*sizeof(short));
|
||||||
bufsiz = 1024;
|
bufsiz = 1024;
|
||||||
buf = zalloc(bufsiz);
|
buf = zalloc(bufsiz);
|
||||||
|
@ -1717,7 +1773,7 @@ readhistfile(char *fn, int err, int readflags)
|
||||||
if (*pt) {
|
if (*pt) {
|
||||||
if (nwordpos >= nwordlist)
|
if (nwordpos >= nwordlist)
|
||||||
wordlist = (short *) realloc(wordlist,
|
wordlist = (short *) realloc(wordlist,
|
||||||
(nwordlist += 16)*sizeof(short));
|
(nwordlist += 64)*sizeof(short));
|
||||||
wordlist[nwordpos++] = pt - start;
|
wordlist[nwordpos++] = pt - start;
|
||||||
while (*pt && !inblank(*pt))
|
while (*pt && !inblank(*pt))
|
||||||
pt++;
|
pt++;
|
||||||
|
|
31
Src/init.c
31
Src/init.c
|
@ -37,6 +37,14 @@
|
||||||
/**/
|
/**/
|
||||||
int noexitct = 0;
|
int noexitct = 0;
|
||||||
|
|
||||||
|
/* buffer for $_ and its length */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
char *underscore;
|
||||||
|
|
||||||
|
/**/
|
||||||
|
int underscorelen;
|
||||||
|
|
||||||
/* what level of sourcing we are at */
|
/* what level of sourcing we are at */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
@ -94,7 +102,7 @@ loop(int toplevel, int justonce)
|
||||||
if (interact)
|
if (interact)
|
||||||
preprompt();
|
preprompt();
|
||||||
}
|
}
|
||||||
hbegin(); /* init history mech */
|
hbegin(1); /* init history mech */
|
||||||
intr(); /* interrupts on */
|
intr(); /* interrupts on */
|
||||||
lexinit(); /* initialize lexical state */
|
lexinit(); /* initialize lexical state */
|
||||||
if (!(list = parse_event())) { /* if we couldn't parse a list */
|
if (!(list = parse_event())) { /* if we couldn't parse a list */
|
||||||
|
@ -128,6 +136,8 @@ loop(int toplevel, int justonce)
|
||||||
if (stopmsg) /* unset 'you have stopped jobs' flag */
|
if (stopmsg) /* unset 'you have stopped jobs' flag */
|
||||||
stopmsg--;
|
stopmsg--;
|
||||||
execlist(list, 0, 0);
|
execlist(list, 0, 0);
|
||||||
|
if (toplevel)
|
||||||
|
freestructs();
|
||||||
tok = toksav;
|
tok = toksav;
|
||||||
if (toplevel)
|
if (toplevel)
|
||||||
noexitct = 0;
|
noexitct = 0;
|
||||||
|
@ -550,8 +560,20 @@ setupvals(void)
|
||||||
cdpath = mkarray(NULL);
|
cdpath = mkarray(NULL);
|
||||||
manpath = mkarray(NULL);
|
manpath = mkarray(NULL);
|
||||||
fignore = mkarray(NULL);
|
fignore = mkarray(NULL);
|
||||||
#ifdef FUNCTION_DIR
|
#ifdef FPATH_DIR
|
||||||
fpath = mkarray(ztrdup(FUNCTION_DIR));
|
# ifdef FPATH_SUBDIRS
|
||||||
|
{
|
||||||
|
char *fpath_subdirs[] = FPATH_SUBDIRS;
|
||||||
|
int len = sizeof(fpath_subdirs)/sizeof(char *), j;
|
||||||
|
|
||||||
|
fpath = zalloc((len+1)*sizeof(char *));
|
||||||
|
for (j = 0; j < len; j++)
|
||||||
|
fpath[j] = tricat(FPATH_DIR, "/", fpath_subdirs[j]);
|
||||||
|
fpath[len] = NULL;
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
fpath = mkarray(ztrdup(FPATH_DIR));
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
fpath = mkarray(NULL);
|
fpath = mkarray(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
@ -582,7 +604,8 @@ setupvals(void)
|
||||||
ifs = ztrdup(DEFAULT_IFS);
|
ifs = ztrdup(DEFAULT_IFS);
|
||||||
wordchars = ztrdup(DEFAULT_WORDCHARS);
|
wordchars = ztrdup(DEFAULT_WORDCHARS);
|
||||||
postedit = ztrdup("");
|
postedit = ztrdup("");
|
||||||
underscore = ztrdup("");
|
underscore = (char *) zalloc(underscorelen = 32);
|
||||||
|
*underscore = '\0';
|
||||||
|
|
||||||
zoptarg = ztrdup("");
|
zoptarg = ztrdup("");
|
||||||
zoptind = 1;
|
zoptind = 1;
|
||||||
|
|
35
Src/jobs.c
35
Src/jobs.c
|
@ -65,10 +65,6 @@ struct tms shtms;
|
||||||
/**/
|
/**/
|
||||||
int ttyfrozen;
|
int ttyfrozen;
|
||||||
|
|
||||||
/* empty job structure for quick clearing of jobtab entries */
|
|
||||||
|
|
||||||
static struct job zero; /* static variables are initialized to zero */
|
|
||||||
|
|
||||||
static struct timeval dtimeval, now;
|
static struct timeval dtimeval, now;
|
||||||
|
|
||||||
/* Diff two timevals for elapsed-time computations */
|
/* Diff two timevals for elapsed-time computations */
|
||||||
|
@ -244,8 +240,11 @@ update_job(Job jn)
|
||||||
adjustwinsize(0);
|
adjustwinsize(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (list_pipe && (val & 0200) && inforeground == 1) {
|
||||||
|
breaks = loops;
|
||||||
|
errflag = 1;
|
||||||
|
inerrflush();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (somestopped && jn->stat & STAT_SUPERJOB)
|
if (somestopped && jn->stat & STAT_SUPERJOB)
|
||||||
return;
|
return;
|
||||||
jn->stat |= (somestopped) ? STAT_CHANGED | STAT_STOPPED :
|
jn->stat |= (somestopped) ? STAT_CHANGED | STAT_STOPPED :
|
||||||
|
@ -663,14 +662,16 @@ deletejob(Job jn)
|
||||||
nx = pn->next;
|
nx = pn->next;
|
||||||
zfree(pn, sizeof(struct process));
|
zfree(pn, sizeof(struct process));
|
||||||
}
|
}
|
||||||
zsfree(jn->pwd);
|
|
||||||
|
|
||||||
deletefilelist(jn->filelist);
|
deletefilelist(jn->filelist);
|
||||||
|
|
||||||
if (jn->ty)
|
if (jn->ty)
|
||||||
zfree(jn->ty, sizeof(struct ttyinfo));
|
zfree(jn->ty, sizeof(struct ttyinfo));
|
||||||
|
|
||||||
*jn = zero;
|
jn->gleader = jn->other = 0;
|
||||||
|
jn->stat = jn->stty_in_env = 0;
|
||||||
|
jn->procs = NULL;
|
||||||
|
jn->filelist = NULL;
|
||||||
|
jn->ty = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add a process to the current job */
|
/* add a process to the current job */
|
||||||
|
@ -831,7 +832,12 @@ waitjob(int job, int sig)
|
||||||
void
|
void
|
||||||
waitjobs(void)
|
waitjobs(void)
|
||||||
{
|
{
|
||||||
waitjob(thisjob, 0);
|
Job jn = jobtab + thisjob;
|
||||||
|
|
||||||
|
if (jn->procs)
|
||||||
|
waitjob(thisjob, 0);
|
||||||
|
else
|
||||||
|
deletejob(jn);
|
||||||
thisjob = -1;
|
thisjob = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,12 +849,9 @@ clearjobtab(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 1; i < MAXJOB; i++) {
|
for (i = 1; i < MAXJOB; i++)
|
||||||
if (jobtab[i].pwd)
|
|
||||||
zsfree(jobtab[i].pwd);
|
|
||||||
if (jobtab[i].ty)
|
if (jobtab[i].ty)
|
||||||
zfree(jobtab[i].ty, sizeof(struct ttyinfo));
|
zfree(jobtab[i].ty, sizeof(struct ttyinfo));
|
||||||
}
|
|
||||||
|
|
||||||
memset(jobtab, 0, sizeof(jobtab)); /* zero out table */
|
memset(jobtab, 0, sizeof(jobtab)); /* zero out table */
|
||||||
}
|
}
|
||||||
|
@ -864,7 +867,11 @@ initjob(void)
|
||||||
for (i = 1; i < MAXJOB; i++)
|
for (i = 1; i < MAXJOB; i++)
|
||||||
if (!jobtab[i].stat) {
|
if (!jobtab[i].stat) {
|
||||||
jobtab[i].stat = STAT_INUSE;
|
jobtab[i].stat = STAT_INUSE;
|
||||||
jobtab[i].pwd = ztrdup(pwd);
|
if (strlen(pwd) >= PATH_MAX) {
|
||||||
|
memcpy(jobtab[i].pwd, pwd, PATH_MAX);
|
||||||
|
jobtab[i].pwd[PATH_MAX] = '\0';
|
||||||
|
} else
|
||||||
|
strcpy(jobtab[i].pwd, pwd);
|
||||||
jobtab[i].gleader = 0;
|
jobtab[i].gleader = 0;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
76
Src/lex.c
76
Src/lex.c
|
@ -179,6 +179,12 @@ struct lexstack {
|
||||||
int hwgetword;
|
int hwgetword;
|
||||||
int lexstop;
|
int lexstop;
|
||||||
struct heredocs *hdocs;
|
struct heredocs *hdocs;
|
||||||
|
int (*hgetc) _((void));
|
||||||
|
void (*hungetc) _((int));
|
||||||
|
void (*hwaddc) _((int));
|
||||||
|
void (*hwbegin) _((int));
|
||||||
|
void (*hwend) _((void));
|
||||||
|
void (*addtoline) _((int));
|
||||||
|
|
||||||
unsigned char *cstack;
|
unsigned char *cstack;
|
||||||
int csp;
|
int csp;
|
||||||
|
@ -226,6 +232,12 @@ lexsave(void)
|
||||||
ls->hwgetword = hwgetword;
|
ls->hwgetword = hwgetword;
|
||||||
ls->lexstop = lexstop;
|
ls->lexstop = lexstop;
|
||||||
ls->hdocs = hdocs;
|
ls->hdocs = hdocs;
|
||||||
|
ls->hgetc = hgetc;
|
||||||
|
ls->hungetc = hungetc;
|
||||||
|
ls->hwaddc = hwaddc;
|
||||||
|
ls->hwbegin = hwbegin;
|
||||||
|
ls->hwend = hwend;
|
||||||
|
ls->addtoline = addtoline;
|
||||||
cmdsp = 0;
|
cmdsp = 0;
|
||||||
inredir = 0;
|
inredir = 0;
|
||||||
hdocs = NULL;
|
hdocs = NULL;
|
||||||
|
@ -271,6 +283,12 @@ lexrestore(void)
|
||||||
hwgetword = lstack->hwgetword;
|
hwgetword = lstack->hwgetword;
|
||||||
lexstop = lstack->lexstop;
|
lexstop = lstack->lexstop;
|
||||||
hdocs = lstack->hdocs;
|
hdocs = lstack->hdocs;
|
||||||
|
hgetc = lstack->hgetc;
|
||||||
|
hungetc = lstack->hungetc;
|
||||||
|
hwaddc = lstack->hwaddc;
|
||||||
|
hwbegin = lstack->hwbegin;
|
||||||
|
hwend = lstack->hwend;
|
||||||
|
addtoline = lstack->addtoline;
|
||||||
hlinesz = lstack->hlinesz;
|
hlinesz = lstack->hlinesz;
|
||||||
errflag = 0;
|
errflag = 0;
|
||||||
|
|
||||||
|
@ -783,7 +801,7 @@ gettok(void)
|
||||||
static int
|
static int
|
||||||
gettokstr(int c, int sub)
|
gettokstr(int c, int sub)
|
||||||
{
|
{
|
||||||
int bct = 0, pct = 0, brct = 0;
|
int bct = 0, pct = 0, brct = 0, fdpar = 0;
|
||||||
int intpos = 1, in_brace_param = 0;
|
int intpos = 1, in_brace_param = 0;
|
||||||
int peek, inquote;
|
int peek, inquote;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -798,8 +816,12 @@ gettokstr(int c, int sub)
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int act;
|
int act;
|
||||||
int e;
|
int e;
|
||||||
|
int inbl = inblank(c);
|
||||||
|
|
||||||
|
if (fdpar && !inbl && c != ')')
|
||||||
|
fdpar = 0;
|
||||||
|
|
||||||
if (inblank(c) && !in_brace_param && !pct)
|
if (inbl && !in_brace_param && !pct)
|
||||||
act = LX2_BREAK;
|
act = LX2_BREAK;
|
||||||
else {
|
else {
|
||||||
act = lexact2[STOUC(c)];
|
act = lexact2[STOUC(c)];
|
||||||
|
@ -822,6 +844,12 @@ gettokstr(int c, int sub)
|
||||||
add(Meta);
|
add(Meta);
|
||||||
break;
|
break;
|
||||||
case LX2_OUTPAR:
|
case LX2_OUTPAR:
|
||||||
|
if (fdpar) {
|
||||||
|
/* this is a single word `( )', treat as INOUTPAR */
|
||||||
|
add(c);
|
||||||
|
*bptr = '\0';
|
||||||
|
return INOUTPAR;
|
||||||
|
}
|
||||||
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--) {
|
||||||
|
@ -898,11 +926,40 @@ gettokstr(int c, int sub)
|
||||||
e = hgetc();
|
e = hgetc();
|
||||||
hungetc(e);
|
hungetc(e);
|
||||||
lexstop = 0;
|
lexstop = 0;
|
||||||
if (e == ')' ||
|
/* For command words, parentheses are only
|
||||||
(incmdpos && !brct && peek != ENVSTRING))
|
* special at the start. But now we're tokenising
|
||||||
|
* the remaining string. So I don't see what
|
||||||
|
* the old incmdpos test here is for.
|
||||||
|
* pws 1999/6/8
|
||||||
|
*
|
||||||
|
* Oh, no.
|
||||||
|
* func1( )
|
||||||
|
* is a valid function definition in [k]sh. The best
|
||||||
|
* thing we can do, without really nasty lookahead tricks,
|
||||||
|
* is break if we find a blank after a parenthesis. At
|
||||||
|
* least this can't happen inside braces or brackets. We
|
||||||
|
* only allow this with SHGLOB (set for both sh and ksh).
|
||||||
|
*
|
||||||
|
* Things like `print @( |foo)' should still
|
||||||
|
* work, because [k]sh don't allow multiple words
|
||||||
|
* in a function definition, so we only do this
|
||||||
|
* in command position.
|
||||||
|
* pws 1999/6/14
|
||||||
|
*/
|
||||||
|
if (e == ')' || (isset(SHGLOB) && inblank(e) && !bct &&
|
||||||
|
!brct && !intpos && incmdpos))
|
||||||
goto brk;
|
goto brk;
|
||||||
}
|
}
|
||||||
pct++;
|
/*
|
||||||
|
* This also handles the [k]sh `foo( )' function definition.
|
||||||
|
* Maintain a variable fdpar, set as long as a single set of
|
||||||
|
* parentheses contains only space. Then if we get to the
|
||||||
|
* closing parenthesis and it is still set, we can assume we
|
||||||
|
* have a function definition. Only do this at the start of
|
||||||
|
* the word, since the (...) must be a separate token.
|
||||||
|
*/
|
||||||
|
if (!pct++ && isset(SHGLOB) && intpos && !bct && !brct)
|
||||||
|
fdpar = 1;
|
||||||
}
|
}
|
||||||
c = Inpar;
|
c = Inpar;
|
||||||
break;
|
break;
|
||||||
|
@ -1294,8 +1351,7 @@ parsestr(char *s)
|
||||||
lexsave();
|
lexsave();
|
||||||
untokenize(s);
|
untokenize(s);
|
||||||
inpush(dupstring(s), 0, NULL);
|
inpush(dupstring(s), 0, NULL);
|
||||||
strinbeg();
|
strinbeg(0);
|
||||||
stophist = 2;
|
|
||||||
len = 0;
|
len = 0;
|
||||||
bptr = tokstr = s;
|
bptr = tokstr = s;
|
||||||
bsiz = l + 1;
|
bsiz = l + 1;
|
||||||
|
@ -1331,8 +1387,7 @@ parse_subst_string(char *s)
|
||||||
lexsave();
|
lexsave();
|
||||||
untokenize(s);
|
untokenize(s);
|
||||||
inpush(dupstring(s), 0, NULL);
|
inpush(dupstring(s), 0, NULL);
|
||||||
strinbeg();
|
strinbeg(0);
|
||||||
stophist = 2;
|
|
||||||
len = 0;
|
len = 0;
|
||||||
bptr = tokstr = s;
|
bptr = tokstr = s;
|
||||||
bsiz = l + 1;
|
bsiz = l + 1;
|
||||||
|
@ -1377,8 +1432,7 @@ exalias(void)
|
||||||
|
|
||||||
if (!tokstr) {
|
if (!tokstr) {
|
||||||
yytext = tokstrings[tok];
|
yytext = tokstrings[tok];
|
||||||
if (yytext)
|
|
||||||
yytext = dupstring(yytext);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ newlinklist(void)
|
||||||
{
|
{
|
||||||
LinkList list;
|
LinkList list;
|
||||||
|
|
||||||
list = (LinkList) alloc(sizeof *list);
|
list = (LinkList) ncalloc(sizeof *list);
|
||||||
list->first = NULL;
|
list->first = NULL;
|
||||||
list->last = (LinkNode) list;
|
list->last = (LinkNode) list;
|
||||||
return list;
|
return list;
|
||||||
|
@ -53,7 +53,7 @@ insertlinknode(LinkList list, LinkNode node, void *dat)
|
||||||
LinkNode tmp, new;
|
LinkNode tmp, new;
|
||||||
|
|
||||||
tmp = node->next;
|
tmp = node->next;
|
||||||
node->next = new = (LinkNode) alloc(sizeof *tmp);
|
node->next = new = (LinkNode) ncalloc(sizeof *tmp);
|
||||||
new->last = node;
|
new->last = node;
|
||||||
new->dat = dat;
|
new->dat = dat;
|
||||||
new->next = tmp;
|
new->next = tmp;
|
||||||
|
|
64
Src/loop.c
64
Src/loop.c
|
@ -44,21 +44,18 @@ int contflag;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int breaks;
|
int breaks;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
execfor(Cmd cmd)
|
execfor(Cmd cmd, LinkList args, int flags)
|
||||||
{
|
{
|
||||||
List list;
|
|
||||||
Forcmd node;
|
Forcmd node;
|
||||||
char *str;
|
char *str;
|
||||||
int val = 0;
|
zlong val = 0;
|
||||||
LinkList args;
|
|
||||||
|
|
||||||
node = cmd->u.forcmd;
|
node = cmd->u.forcmd;
|
||||||
args = cmd->args;
|
|
||||||
if (node->condition) {
|
if (node->condition) {
|
||||||
str = node->name;
|
str = dupstring(node->name);
|
||||||
singsub(&str);
|
singsub(&str);
|
||||||
if (!errflag)
|
if (!errflag)
|
||||||
matheval(str);
|
matheval(str);
|
||||||
|
@ -69,7 +66,7 @@ execfor(Cmd cmd)
|
||||||
|
|
||||||
args = newlinklist();
|
args = newlinklist();
|
||||||
for (x = pparams; *x; x++)
|
for (x = pparams; *x; x++)
|
||||||
addlinknode(args, ztrdup(*x));
|
addlinknode(args, dupstring(*x));
|
||||||
}
|
}
|
||||||
lastval = 0;
|
lastval = 0;
|
||||||
loops++;
|
loops++;
|
||||||
|
@ -95,13 +92,12 @@ execfor(Cmd cmd)
|
||||||
if (!val)
|
if (!val)
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
str = (char *) ugetnode(args);
|
if (!args || !(str = (char *) ugetnode(args)))
|
||||||
if (!str)
|
|
||||||
break;
|
break;
|
||||||
setsparam(node->name, ztrdup(str));
|
setsparam(node->name, ztrdup(str));
|
||||||
}
|
}
|
||||||
list = (List) dupstruct(node->list);
|
execlist(node->list, 1,
|
||||||
execlist(list, 1, (cmd->flags & CFLAG_EXEC) && empty(args));
|
(flags & CFLAG_EXEC) && args && empty(args));
|
||||||
if (breaks) {
|
if (breaks) {
|
||||||
breaks--;
|
breaks--;
|
||||||
if (breaks || !contflag)
|
if (breaks || !contflag)
|
||||||
|
@ -129,27 +125,24 @@ execfor(Cmd cmd)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
execselect(Cmd cmd)
|
execselect(Cmd cmd, LinkList args, int flags)
|
||||||
{
|
{
|
||||||
List list;
|
|
||||||
Forcmd node;
|
Forcmd node;
|
||||||
char *str, *s;
|
char *str, *s;
|
||||||
LinkList args;
|
|
||||||
LinkNode n;
|
LinkNode n;
|
||||||
int i;
|
int i;
|
||||||
FILE *inp;
|
FILE *inp;
|
||||||
size_t more;
|
size_t more;
|
||||||
|
|
||||||
node = cmd->u.forcmd;
|
node = cmd->u.forcmd;
|
||||||
args = cmd->args;
|
|
||||||
if (!node->inflag) {
|
if (!node->inflag) {
|
||||||
char **x;
|
char **x;
|
||||||
|
|
||||||
args = newlinklist();
|
args = newlinklist();
|
||||||
for (x = pparams; *x; x++)
|
for (x = pparams; *x; x++)
|
||||||
addlinknode(args, ztrdup(*x));
|
addlinknode(args, dupstring(*x));
|
||||||
}
|
}
|
||||||
if (empty(args))
|
if (!args || empty(args))
|
||||||
return 1;
|
return 1;
|
||||||
loops++;
|
loops++;
|
||||||
lastval = 0;
|
lastval = 0;
|
||||||
|
@ -196,8 +189,7 @@ execselect(Cmd cmd)
|
||||||
str = "";
|
str = "";
|
||||||
}
|
}
|
||||||
setsparam(node->name, ztrdup(str));
|
setsparam(node->name, ztrdup(str));
|
||||||
list = (List) dupstruct(node->list);
|
execlist(node->list, 1, 0);
|
||||||
execlist(list, 1, 0);
|
|
||||||
freeheap();
|
freeheap();
|
||||||
if (breaks) {
|
if (breaks) {
|
||||||
breaks--;
|
breaks--;
|
||||||
|
@ -278,9 +270,8 @@ selectlist(LinkList l, size_t start)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
execwhile(Cmd cmd)
|
execwhile(Cmd cmd, LinkList args, int flags)
|
||||||
{
|
{
|
||||||
List list;
|
|
||||||
struct whilecmd *node;
|
struct whilecmd *node;
|
||||||
int olderrexit, oldval;
|
int olderrexit, oldval;
|
||||||
|
|
||||||
|
@ -290,9 +281,8 @@ execwhile(Cmd cmd)
|
||||||
pushheap();
|
pushheap();
|
||||||
loops++;
|
loops++;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
list = (List) dupstruct(node->cont);
|
|
||||||
noerrexit = 1;
|
noerrexit = 1;
|
||||||
execlist(list, 1, 0);
|
execlist(node->cont, 1, 0);
|
||||||
noerrexit = olderrexit;
|
noerrexit = olderrexit;
|
||||||
if (!((lastval == 0) ^ node->cond)) {
|
if (!((lastval == 0) ^ node->cond)) {
|
||||||
if (breaks)
|
if (breaks)
|
||||||
|
@ -300,8 +290,7 @@ execwhile(Cmd cmd)
|
||||||
lastval = oldval;
|
lastval = oldval;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
list = (List) dupstruct(node->loop);
|
execlist(node->loop, 1, 0);
|
||||||
execlist(list, 1, 0);
|
|
||||||
if (breaks) {
|
if (breaks) {
|
||||||
breaks--;
|
breaks--;
|
||||||
if (breaks || !contflag)
|
if (breaks || !contflag)
|
||||||
|
@ -322,22 +311,20 @@ execwhile(Cmd cmd)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
execrepeat(Cmd cmd)
|
execrepeat(Cmd cmd, LinkList args, int flags)
|
||||||
{
|
{
|
||||||
List list;
|
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
lastval = 0;
|
lastval = 0;
|
||||||
if (empty(cmd->args) || nextnode(firstnode(cmd->args))) {
|
if (!args || empty(args) || nextnode(firstnode(args))) {
|
||||||
zerr("bad argument for repeat", NULL, 0);
|
zerr("bad argument for repeat", NULL, 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
count = atoi(peekfirst(cmd->args));
|
count = atoi(peekfirst(args));
|
||||||
pushheap();
|
pushheap();
|
||||||
loops++;
|
loops++;
|
||||||
while (count--) {
|
while (count--) {
|
||||||
list = (List) dupstruct(cmd->u.list);
|
execlist(cmd->u.list, 1, 0);
|
||||||
execlist(list, 1, 0);
|
|
||||||
freeheap();
|
freeheap();
|
||||||
if (breaks) {
|
if (breaks) {
|
||||||
breaks--;
|
breaks--;
|
||||||
|
@ -357,7 +344,7 @@ execrepeat(Cmd cmd)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
execif(Cmd cmd)
|
execif(Cmd cmd, LinkList args, int flags)
|
||||||
{
|
{
|
||||||
struct ifcmd *node;
|
struct ifcmd *node;
|
||||||
int olderrexit;
|
int olderrexit;
|
||||||
|
@ -380,7 +367,7 @@ execif(Cmd cmd)
|
||||||
noerrexit = olderrexit;
|
noerrexit = olderrexit;
|
||||||
|
|
||||||
if (*t)
|
if (*t)
|
||||||
execlist(*t, 1, cmd->flags & CFLAG_EXEC);
|
execlist(*t, 1, flags & CFLAG_EXEC);
|
||||||
else
|
else
|
||||||
lastval = 0;
|
lastval = 0;
|
||||||
|
|
||||||
|
@ -389,7 +376,7 @@ execif(Cmd cmd)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
execcase(Cmd cmd)
|
execcase(Cmd cmd, LinkList args, int flags)
|
||||||
{
|
{
|
||||||
struct casecmd *node;
|
struct casecmd *node;
|
||||||
char *word;
|
char *word;
|
||||||
|
@ -400,18 +387,18 @@ execcase(Cmd cmd)
|
||||||
l = node->lists;
|
l = node->lists;
|
||||||
p = node->pats;
|
p = node->pats;
|
||||||
|
|
||||||
word = *p++;
|
word = dupstring(*p++);
|
||||||
singsub(&word);
|
singsub(&word);
|
||||||
untokenize(word);
|
untokenize(word);
|
||||||
lastval = 0;
|
lastval = 0;
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
while (*p) {
|
while (*p) {
|
||||||
char *pat = *p + 1;
|
char *pat = dupstring(*p + 1);
|
||||||
singsub(&pat);
|
singsub(&pat);
|
||||||
if (matchpat(word, pat)) {
|
if (matchpat(word, pat)) {
|
||||||
do {
|
do {
|
||||||
execlist(*l++, 1, **p == ';' && (cmd->flags & CFLAG_EXEC));
|
execlist(*l++, 1, **p == ';' && (flags & CFLAG_EXEC));
|
||||||
} while(**p++ == '&' && *p);
|
} while(**p++ == '&' && *p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -421,4 +408,3 @@ execcase(Cmd cmd)
|
||||||
}
|
}
|
||||||
return lastval;
|
return lastval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
Src/math.c
14
Src/math.c
|
@ -733,9 +733,9 @@ mathevall(char *s, int prek, char **ep)
|
||||||
char *xptr;
|
char *xptr;
|
||||||
zlong xyyval;
|
zlong xyyval;
|
||||||
LV xyylval;
|
LV xyylval;
|
||||||
char **xlvals = 0;
|
char **xlvals = 0, *nlvals[LVCOUNT];
|
||||||
int xsp;
|
int xsp;
|
||||||
struct mathvalue *xstack = 0;
|
struct mathvalue *xstack = 0, nstack[STACKSZ];
|
||||||
zlong ret;
|
zlong ret;
|
||||||
|
|
||||||
xlastbase = xnoeval = xunary = xlvc = xyyval = xyylval = xsp = 0;
|
xlastbase = xnoeval = xunary = xlvc = xyyval = xyylval = xsp = 0;
|
||||||
|
@ -753,9 +753,10 @@ mathevall(char *s, int prek, char **ep)
|
||||||
xsp = sp;
|
xsp = sp;
|
||||||
xstack = stack;
|
xstack = stack;
|
||||||
}
|
}
|
||||||
stack = (struct mathvalue *)zalloc(STACKSZ*sizeof(struct mathvalue));
|
stack = nstack;
|
||||||
lastbase = -1;
|
lastbase = -1;
|
||||||
lvals = (char **)zcalloc(LVCOUNT*sizeof(char *));
|
memset(nlvals, 0, LVCOUNT*sizeof(char *));
|
||||||
|
lvals = nlvals;
|
||||||
lvc = 0;
|
lvc = 0;
|
||||||
ptr = s;
|
ptr = s;
|
||||||
sp = -1;
|
sp = -1;
|
||||||
|
@ -769,8 +770,6 @@ mathevall(char *s, int prek, char **ep)
|
||||||
|
|
||||||
ret = stack[0].val;
|
ret = stack[0].val;
|
||||||
|
|
||||||
zfree(lvals, LVCOUNT*sizeof(char *));
|
|
||||||
zfree(stack, STACKSZ*sizeof(struct mathvalue));
|
|
||||||
if (--mlevel) {
|
if (--mlevel) {
|
||||||
lastbase = xlastbase;
|
lastbase = xlastbase;
|
||||||
noeval = xnoeval;
|
noeval = xnoeval;
|
||||||
|
@ -827,7 +826,8 @@ mathevalarg(char *s, char **ss)
|
||||||
static void
|
static void
|
||||||
mathparse(int pc)
|
mathparse(int pc)
|
||||||
{
|
{
|
||||||
int q, otok, onoeval;
|
zlong q;
|
||||||
|
int otok, onoeval;
|
||||||
|
|
||||||
if (errflag)
|
if (errflag)
|
||||||
return;
|
return;
|
||||||
|
|
55
Src/mem.c
55
Src/mem.c
|
@ -97,7 +97,7 @@ static int h_m[1025], h_push, h_pop, h_free;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define H_ISIZE sizeof(zlong)
|
#define H_ISIZE sizeof(zlong)
|
||||||
#define HEAPSIZE (8192 - H_ISIZE)
|
#define HEAPSIZE (16384 - H_ISIZE)
|
||||||
#define HEAP_ARENA_SIZE (HEAPSIZE - sizeof(struct heap))
|
#define HEAP_ARENA_SIZE (HEAPSIZE - sizeof(struct heap))
|
||||||
#define HEAPFREE (16384 - H_ISIZE)
|
#define HEAPFREE (16384 - H_ISIZE)
|
||||||
|
|
||||||
|
@ -133,6 +133,10 @@ global_permalloc(void)
|
||||||
|
|
||||||
static Heap heaps;
|
static Heap heaps;
|
||||||
|
|
||||||
|
/* first heap with free space, not always correct */
|
||||||
|
|
||||||
|
static Heap fheap;
|
||||||
|
|
||||||
/* Use new heaps from now on. This returns the old heap-list. */
|
/* Use new heaps from now on. This returns the old heap-list. */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
@ -141,7 +145,7 @@ new_heaps(void)
|
||||||
{
|
{
|
||||||
Heap h = heaps;
|
Heap h = heaps;
|
||||||
|
|
||||||
heaps = NULL;
|
fheap = heaps = NULL;
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
@ -160,6 +164,7 @@ old_heaps(Heap old)
|
||||||
zfree(h, sizeof(*h));
|
zfree(h, sizeof(*h));
|
||||||
}
|
}
|
||||||
heaps = old;
|
heaps = old;
|
||||||
|
fheap = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Temporarily switch to other heaps (or back again). */
|
/* Temporarily switch to other heaps (or back again). */
|
||||||
|
@ -171,6 +176,7 @@ switch_heaps(Heap new)
|
||||||
Heap h = heaps;
|
Heap h = heaps;
|
||||||
|
|
||||||
heaps = new;
|
heaps = new;
|
||||||
|
fheap = NULL;
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
@ -208,6 +214,8 @@ freeheap(void)
|
||||||
#if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG)
|
#if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG)
|
||||||
h_free++;
|
h_free++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
fheap = NULL;
|
||||||
for (h = heaps; h; h = hn) {
|
for (h = heaps; h; h = hn) {
|
||||||
hn = h->next;
|
hn = h->next;
|
||||||
if (h->sp) {
|
if (h->sp) {
|
||||||
|
@ -215,6 +223,8 @@ freeheap(void)
|
||||||
memset(arena(h) + h->sp->used, 0xff, h->used - h->sp->used);
|
memset(arena(h) + h->sp->used, 0xff, h->used - h->sp->used);
|
||||||
#endif
|
#endif
|
||||||
h->used = h->sp->used;
|
h->used = h->sp->used;
|
||||||
|
if (!fheap && h->used < HEAP_ARENA_SIZE)
|
||||||
|
fheap = h;
|
||||||
hl = h;
|
hl = h;
|
||||||
} else
|
} else
|
||||||
zfree(h, HEAPSIZE);
|
zfree(h, HEAPSIZE);
|
||||||
|
@ -238,6 +248,7 @@ popheap(void)
|
||||||
h_pop++;
|
h_pop++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
fheap = NULL;
|
||||||
for (h = heaps; h; h = hn) {
|
for (h = heaps; h; h = hn) {
|
||||||
hn = h->next;
|
hn = h->next;
|
||||||
if ((hs = h->sp)) {
|
if ((hs = h->sp)) {
|
||||||
|
@ -246,6 +257,8 @@ popheap(void)
|
||||||
memset(arena(h) + hs->used, 0xff, h->used - hs->used);
|
memset(arena(h) + hs->used, 0xff, h->used - hs->used);
|
||||||
#endif
|
#endif
|
||||||
h->used = hs->used;
|
h->used = hs->used;
|
||||||
|
if (!fheap && h->used < HEAP_ARENA_SIZE)
|
||||||
|
fheap = h;
|
||||||
zfree(hs, sizeof(*hs));
|
zfree(hs, sizeof(*hs));
|
||||||
|
|
||||||
hl = h;
|
hl = h;
|
||||||
|
@ -275,13 +288,12 @@ zhalloc(size_t size)
|
||||||
|
|
||||||
/* find a heap with enough free space */
|
/* find a heap with enough free space */
|
||||||
|
|
||||||
for (h = heaps; h; h = h->next) {
|
for (h = (fheap ? fheap : heaps); h; h = h->next) {
|
||||||
if (HEAP_ARENA_SIZE >= (n = size + h->used)) {
|
if (HEAP_ARENA_SIZE >= (n = size + h->used)) {
|
||||||
h->used = n;
|
h->used = n;
|
||||||
return arena(h) + n - size;
|
return arena(h) + n - size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Heap hp;
|
Heap hp;
|
||||||
/* not found, allocate new heap */
|
/* not found, allocate new heap */
|
||||||
|
@ -311,6 +323,7 @@ zhalloc(size_t size)
|
||||||
hp->next = h;
|
hp->next = h;
|
||||||
else
|
else
|
||||||
heaps = h;
|
heaps = h;
|
||||||
|
fheap = NULL;
|
||||||
|
|
||||||
unqueue_signals();
|
unqueue_signals();
|
||||||
return arena(h);
|
return arena(h);
|
||||||
|
@ -361,6 +374,7 @@ hrealloc(char *p, size_t old, size_t new)
|
||||||
ph->next = h->next;
|
ph->next = h->next;
|
||||||
else
|
else
|
||||||
heaps = h->next;
|
heaps = h->next;
|
||||||
|
fheap = NULL;
|
||||||
zfree(h, HEAPSIZE);
|
zfree(h, HEAPSIZE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -593,6 +607,16 @@ struct m_hdr {
|
||||||
#define M_ISIZE (sizeof(zlong))
|
#define M_ISIZE (sizeof(zlong))
|
||||||
#define M_MIN (2 * M_ISIZE)
|
#define M_MIN (2 * M_ISIZE)
|
||||||
|
|
||||||
|
/* M_FREE is the number of bytes that have to be free before memory is
|
||||||
|
* given back to the system
|
||||||
|
* M_KEEP is the number of bytes that will be kept when memory is given
|
||||||
|
* back; note that this has to be less than M_FREE
|
||||||
|
* M_ALLOC is the number of extra bytes to request from the system */
|
||||||
|
|
||||||
|
#define M_FREE 65536
|
||||||
|
#define M_KEEP 32768
|
||||||
|
#define M_ALLOC M_KEEP
|
||||||
|
|
||||||
/* a pointer to the last free block, a pointer to the free list (the blocks
|
/* a pointer to the last free block, a pointer to the free list (the blocks
|
||||||
on this list are kept in order - lowest address first) */
|
on this list are kept in order - lowest address first) */
|
||||||
|
|
||||||
|
@ -623,13 +647,13 @@ static char *m_high, *m_low;
|
||||||
|
|
||||||
|
|
||||||
#define M_SIDX(S) ((S) / M_ISIZE)
|
#define M_SIDX(S) ((S) / M_ISIZE)
|
||||||
#define M_SNUM 50
|
#define M_SNUM 128
|
||||||
#define M_SLEN(M) ((M)->len / M_SNUM)
|
#define M_SLEN(M) ((M)->len / M_SNUM)
|
||||||
#define M_SBLEN(S) ((S) * M_SNUM + sizeof(struct m_shdr *) + \
|
#define M_SBLEN(S) ((S) * M_SNUM + sizeof(struct m_shdr *) + \
|
||||||
sizeof(zlong) + sizeof(struct m_hdr *))
|
sizeof(zlong) + sizeof(struct m_hdr *))
|
||||||
#define M_BSLEN(S) (((S) - sizeof(struct m_shdr *) - \
|
#define M_BSLEN(S) (((S) - sizeof(struct m_shdr *) - \
|
||||||
sizeof(zlong) - sizeof(struct m_hdr *)) / M_SNUM)
|
sizeof(zlong) - sizeof(struct m_hdr *)) / M_SNUM)
|
||||||
#define M_NSMALL 8
|
#define M_NSMALL 13
|
||||||
|
|
||||||
static struct m_hdr *m_small[M_NSMALL];
|
static struct m_hdr *m_small[M_NSMALL];
|
||||||
|
|
||||||
|
@ -691,9 +715,9 @@ malloc(MALLOC_ARG_T size)
|
||||||
m->used++;
|
m->used++;
|
||||||
|
|
||||||
/* if all small blocks in this block are allocated, the block is
|
/* if all small blocks in this block are allocated, the block is
|
||||||
put at the end of the list blocks wth small blocks of this
|
put at the end of the list blocks with small blocks of this
|
||||||
size (i.e., we try to keep blocks with free blocks at the
|
size (i.e., we try to keep blocks with free blocks at the
|
||||||
beginning of the list, to make the search faster */
|
beginning of the list, to make the search faster) */
|
||||||
|
|
||||||
if (m->used == M_SNUM && m->next) {
|
if (m->used == M_SNUM && m->next) {
|
||||||
for (mt = m; mt->next; mt = mt->next);
|
for (mt = m; mt->next; mt = mt->next);
|
||||||
|
@ -753,15 +777,24 @@ malloc(MALLOC_ARG_T size)
|
||||||
for (mp = NULL, m = m_free; m && m->len < size; mp = m, m = m->next);
|
for (mp = NULL, m = m_free; m && m->len < size; mp = m, m = m->next);
|
||||||
}
|
}
|
||||||
if (!m) {
|
if (!m) {
|
||||||
|
long nal;
|
||||||
/* no matching free block was found, we have to request new
|
/* no matching free block was found, we have to request new
|
||||||
memory from the system */
|
memory from the system */
|
||||||
n = (size + M_HSIZE + m_pgsz - 1) & ~(m_pgsz - 1);
|
n = (size + M_HSIZE + M_ALLOC + m_pgsz - 1) & ~(m_pgsz - 1);
|
||||||
|
|
||||||
if (((char *)(m = (struct m_hdr *)sbrk(n))) == ((char *)-1)) {
|
if (((char *)(m = (struct m_hdr *)sbrk(n))) == ((char *)-1)) {
|
||||||
DPUTS(1, "MEM: allocation error at sbrk.");
|
DPUTS(1, "MEM: allocation error at sbrk.");
|
||||||
unqueue_signals();
|
unqueue_signals();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if ((nal = ((long)(char *)m) & (M_ALIGN-1))) {
|
||||||
|
if ((char *)sbrk(M_ALIGN - nal) == (char *)-1) {
|
||||||
|
DPUTS(1, "MEM: allocation error at sbrk.");
|
||||||
|
unqueue_signals();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
m = (struct m_hdr *) ((char *)m + (M_ALIGN - nal));
|
||||||
|
}
|
||||||
/* set m_low, for the check in free() */
|
/* set m_low, for the check in free() */
|
||||||
if (!m_low)
|
if (!m_low)
|
||||||
m_low = (char *)m;
|
m_low = (char *)m;
|
||||||
|
@ -1034,8 +1067,8 @@ zfree(void *p, int sz)
|
||||||
and now there is more than one page size of memory, we can give
|
and now there is more than one page size of memory, we can give
|
||||||
it back to the system (and we do it ;-) */
|
it back to the system (and we do it ;-) */
|
||||||
if ((((char *)m_lfree) + M_ISIZE + m_lfree->len) == m_high &&
|
if ((((char *)m_lfree) + M_ISIZE + m_lfree->len) == m_high &&
|
||||||
m_lfree->len >= m_pgsz + M_MIN) {
|
m_lfree->len >= m_pgsz + M_MIN + M_FREE) {
|
||||||
long n = (m_lfree->len - M_MIN) & ~(m_pgsz - 1);
|
long n = (m_lfree->len - M_MIN - M_KEEP) & ~(m_pgsz - 1);
|
||||||
|
|
||||||
m_lfree->len -= n;
|
m_lfree->len -= n;
|
||||||
if (brk(m_high -= n) == -1) {
|
if (brk(m_high -= n) == -1) {
|
||||||
|
|
21
Src/params.c
21
Src/params.c
|
@ -52,7 +52,6 @@ char **pparams, /* $argv */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
char *argzero, /* $0 */
|
char *argzero, /* $0 */
|
||||||
*underscore, /* $_ */
|
|
||||||
*home, /* $HOME */
|
*home, /* $HOME */
|
||||||
*hostnam, /* $HOST */
|
*hostnam, /* $HOST */
|
||||||
*ifs, /* $IFS */
|
*ifs, /* $IFS */
|
||||||
|
@ -232,11 +231,6 @@ IPDEF9("manpath", &manpath, "MANPATH"),
|
||||||
IPDEF9("psvar", &psvar, "PSVAR"),
|
IPDEF9("psvar", &psvar, "PSVAR"),
|
||||||
IPDEF9("watch", &watch, "WATCH"),
|
IPDEF9("watch", &watch, "WATCH"),
|
||||||
|
|
||||||
/*TEST BEGIN*/
|
|
||||||
#define IPDEF10(A) {NULL,A,PM_HASHED|PM_SPECIAL|PM_DONTIMPORT,BR((void *)0),SFN(hashsetfn),GFN(hashgetfn),stdunsetfn,0,NULL,NULL,NULL,0}
|
|
||||||
IPDEF10("testhash"),
|
|
||||||
/*TEST END*/
|
|
||||||
|
|
||||||
#ifdef DYNAMIC
|
#ifdef DYNAMIC
|
||||||
IPDEF9F("module_path", &module_path, "MODULE_PATH", PM_RESTRICTED),
|
IPDEF9F("module_path", &module_path, "MODULE_PATH", PM_RESTRICTED),
|
||||||
#endif
|
#endif
|
||||||
|
@ -723,16 +717,13 @@ isident(char *s)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **garr;
|
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static zlong
|
static zlong
|
||||||
getarg(char **str, int *inv, Value v, int a2, zlong *w)
|
getarg(char **str, int *inv, Value v, int a2, zlong *w)
|
||||||
{
|
{
|
||||||
int num = 1, word = 0, rev = 0, ind = 0, down = 0, l, i, ishash;
|
int hasbeg = 0, word = 0, rev = 0, ind = 0, down = 0, l, i, ishash;
|
||||||
int beg = 0, hasbeg = 0;
|
|
||||||
char *s = *str, *sep = NULL, *t, sav, *d, **ta, **p, *tt;
|
char *s = *str, *sep = NULL, *t, sav, *d, **ta, **p, *tt;
|
||||||
zlong r = 0;
|
zlong num = 1, beg = 0, r = 0;
|
||||||
Comp c;
|
Comp c;
|
||||||
|
|
||||||
ishash = (v->pm && PM_TYPE(v->pm->flags) == PM_HASHED);
|
ishash = (v->pm && PM_TYPE(v->pm->flags) == PM_HASHED);
|
||||||
|
@ -1147,7 +1138,6 @@ fetchvalue(char **pptr, int bracks, int flags)
|
||||||
int ppar = 0;
|
int ppar = 0;
|
||||||
|
|
||||||
s = t = *pptr;
|
s = t = *pptr;
|
||||||
garr = NULL;
|
|
||||||
|
|
||||||
if (idigit(*s)) {
|
if (idigit(*s)) {
|
||||||
if (bracks >= 0)
|
if (bracks >= 0)
|
||||||
|
@ -1638,7 +1628,7 @@ 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) {
|
if (v && PM_TYPE(v->pm->flags) == PM_HASHED) {
|
||||||
zerr("attempt to set slice of associative array", NULL, 0);
|
zerr("attempt to set slice of associative array", NULL, 0);
|
||||||
freearray(val);
|
freearray(val);
|
||||||
errflag = 1;
|
errflag = 1;
|
||||||
|
@ -2466,7 +2456,10 @@ wordcharssetfn(Param pm, char *x)
|
||||||
char *
|
char *
|
||||||
underscoregetfn(Param pm)
|
underscoregetfn(Param pm)
|
||||||
{
|
{
|
||||||
return underscore;
|
char *u = dupstring(underscore);
|
||||||
|
|
||||||
|
untokenize(u);
|
||||||
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function to get value for special parameter `TERM' */
|
/* Function to get value for special parameter `TERM' */
|
||||||
|
|
56
Src/parse.c
56
Src/parse.c
|
@ -298,6 +298,8 @@ par_pline(void)
|
||||||
rdr->type = MERGEOUT;
|
rdr->type = MERGEOUT;
|
||||||
rdr->fd1 = 2;
|
rdr->fd1 = 2;
|
||||||
rdr->name = dupstring("1");
|
rdr->name = dupstring("1");
|
||||||
|
if (!c->redir)
|
||||||
|
c->redir = newlinklist();
|
||||||
addlinknode(c->redir, rdr);
|
addlinknode(c->redir, rdr);
|
||||||
|
|
||||||
cmdpush(CS_ERRPIPE);
|
cmdpush(CS_ERRPIPE);
|
||||||
|
@ -330,11 +332,14 @@ par_cmd(void)
|
||||||
|
|
||||||
c = (Cmd) make_cmd();
|
c = (Cmd) make_cmd();
|
||||||
c->lineno = lineno;
|
c->lineno = lineno;
|
||||||
c->args = newlinklist();
|
c->args = NULL;
|
||||||
c->redir = newlinklist();
|
c->vars = NULL;
|
||||||
c->vars = newlinklist();
|
if (IS_REDIROP(tok)) {
|
||||||
while (IS_REDIROP(tok))
|
c->redir = newlinklist();
|
||||||
par_redir(c->redir);
|
while (IS_REDIROP(tok))
|
||||||
|
par_redir(c->redir);
|
||||||
|
} else
|
||||||
|
c->redir = NULL;
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case FOR:
|
case FOR:
|
||||||
cmdpush(CS_FOR);
|
cmdpush(CS_FOR);
|
||||||
|
@ -399,6 +404,8 @@ par_cmd(void)
|
||||||
break;
|
break;
|
||||||
case DINPAR:
|
case DINPAR:
|
||||||
c->type = CARITH;
|
c->type = CARITH;
|
||||||
|
if (!c->args)
|
||||||
|
c->args = newlinklist();
|
||||||
addlinknode(c->args, tokstr);
|
addlinknode(c->args, tokstr);
|
||||||
yylex();
|
yylex();
|
||||||
break;
|
break;
|
||||||
|
@ -407,8 +414,12 @@ par_cmd(void)
|
||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while (IS_REDIROP(tok))
|
if (IS_REDIROP(tok)) {
|
||||||
par_redir(c->redir);
|
if (!c->redir)
|
||||||
|
c->redir = newlinklist();
|
||||||
|
while (IS_REDIROP(tok))
|
||||||
|
par_redir(c->redir);
|
||||||
|
}
|
||||||
incmdpos = 1;
|
incmdpos = 1;
|
||||||
incasepat = 0;
|
incasepat = 0;
|
||||||
incond = 0;
|
incond = 0;
|
||||||
|
@ -460,6 +471,8 @@ par_for(Cmd c)
|
||||||
f->inflag = 1;
|
f->inflag = 1;
|
||||||
incmdpos = 0;
|
incmdpos = 0;
|
||||||
yylex();
|
yylex();
|
||||||
|
if (!c->args)
|
||||||
|
c->args = newlinklist();
|
||||||
c->args = par_wordlist();
|
c->args = par_wordlist();
|
||||||
if (tok != SEPER)
|
if (tok != SEPER)
|
||||||
YYERRORV;
|
YYERRORV;
|
||||||
|
@ -467,6 +480,8 @@ par_for(Cmd c)
|
||||||
f->inflag = 1;
|
f->inflag = 1;
|
||||||
incmdpos = 0;
|
incmdpos = 0;
|
||||||
yylex();
|
yylex();
|
||||||
|
if (!c->args)
|
||||||
|
c->args = newlinklist();
|
||||||
c->args = par_nl_wordlist();
|
c->args = par_nl_wordlist();
|
||||||
if (tok != OUTPAR)
|
if (tok != OUTPAR)
|
||||||
YYERRORV;
|
YYERRORV;
|
||||||
|
@ -819,6 +834,8 @@ par_repeat(Cmd c)
|
||||||
yylex();
|
yylex();
|
||||||
if (tok != STRING)
|
if (tok != STRING)
|
||||||
YYERRORV;
|
YYERRORV;
|
||||||
|
if (!c->args)
|
||||||
|
c->args = newlinklist();
|
||||||
addlinknode(c->args, tokstr);
|
addlinknode(c->args, tokstr);
|
||||||
incmdpos = 1;
|
incmdpos = 1;
|
||||||
yylex();
|
yylex();
|
||||||
|
@ -966,6 +983,8 @@ par_simple(Cmd c)
|
||||||
v->str = p + 1;
|
v->str = p + 1;
|
||||||
} else
|
} else
|
||||||
equalsplit(tokstr, &v->str);
|
equalsplit(tokstr, &v->str);
|
||||||
|
if (!c->vars)
|
||||||
|
c->vars = newlinklist();
|
||||||
addlinknode(c->vars, v);
|
addlinknode(c->vars, v);
|
||||||
isnull = 0;
|
isnull = 0;
|
||||||
} else if (tok == ENVARRAY) {
|
} else if (tok == ENVARRAY) {
|
||||||
|
@ -982,6 +1001,8 @@ par_simple(Cmd c)
|
||||||
if (tok != OUTPAR)
|
if (tok != OUTPAR)
|
||||||
YYERROR;
|
YYERROR;
|
||||||
incmdpos = oldcmdpos;
|
incmdpos = oldcmdpos;
|
||||||
|
if (!c->vars)
|
||||||
|
c->vars = newlinklist();
|
||||||
addlinknode(c->vars, v);
|
addlinknode(c->vars, v);
|
||||||
isnull = 0;
|
isnull = 0;
|
||||||
} else
|
} else
|
||||||
|
@ -993,9 +1014,13 @@ par_simple(Cmd c)
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (tok == STRING) {
|
if (tok == STRING) {
|
||||||
incmdpos = 0;
|
incmdpos = 0;
|
||||||
|
if (!c->args)
|
||||||
|
c->args = newlinklist();
|
||||||
addlinknode(c->args, tokstr);
|
addlinknode(c->args, tokstr);
|
||||||
yylex();
|
yylex();
|
||||||
} else if (IS_REDIROP(tok)) {
|
} else if (IS_REDIROP(tok)) {
|
||||||
|
if (!c->redir)
|
||||||
|
c->redir = newlinklist();
|
||||||
par_redir(c->redir);
|
par_redir(c->redir);
|
||||||
} else if (tok == INOUTPAR) {
|
} else if (tok == INOUTPAR) {
|
||||||
incmdpos = 1;
|
incmdpos = 1;
|
||||||
|
@ -1011,15 +1036,26 @@ par_simple(Cmd c)
|
||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
yylex();
|
yylex();
|
||||||
} else
|
} else {
|
||||||
c->u.list = (List) expandstruct((struct node *) par_cmd(), N_LIST);
|
List l;
|
||||||
|
Sublist sl;
|
||||||
|
Pline pl;
|
||||||
|
|
||||||
|
l = (List) allocnode(N_LIST);
|
||||||
|
l->type = Z_SYNC;
|
||||||
|
l->left = sl = (Sublist) allocnode(N_SUBLIST);
|
||||||
|
sl->type = END;
|
||||||
|
sl->left = pl = (Pline) allocnode(N_PLINE);
|
||||||
|
pl->type = END;
|
||||||
|
pl->left = par_cmd();
|
||||||
|
}
|
||||||
cmdpop();
|
cmdpop();
|
||||||
c->type = FUNCDEF;
|
c->type = FUNCDEF;
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
isnull = 0;
|
isnull = 0;
|
||||||
}
|
}
|
||||||
if (isnull && empty(c->redir))
|
if (isnull && (!c->redir || empty(c->redir)))
|
||||||
return NULL;
|
return NULL;
|
||||||
incmdpos = 1;
|
incmdpos = 1;
|
||||||
return c;
|
return c;
|
||||||
|
|
|
@ -719,7 +719,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
|
||||||
freelinklist(args, (FreeFunc) NULL);
|
freelinklist(args, (FreeFunc) NULL);
|
||||||
zsfree(name);
|
zsfree(name);
|
||||||
} else HEAPALLOC {
|
} else HEAPALLOC {
|
||||||
execlist(dupstruct(sigfn), 1, 0);
|
execlist(sigfn, 1, 0);
|
||||||
} LASTALLOC;
|
} LASTALLOC;
|
||||||
if (trapreturn > 0)
|
if (trapreturn > 0)
|
||||||
trapret = trapreturn;
|
trapret = trapreturn;
|
||||||
|
|
|
@ -53,9 +53,9 @@ prefork(LinkList list, int flags)
|
||||||
|
|
||||||
MUSTUSEHEAP("prefork");
|
MUSTUSEHEAP("prefork");
|
||||||
for (node = firstnode(list); node; incnode(node)) {
|
for (node = firstnode(list); node; incnode(node)) {
|
||||||
char *str, *str3;
|
char *str;
|
||||||
|
|
||||||
str = str3 = (char *)getdata(node);
|
str = (char *)getdata(node);
|
||||||
if ((*str == Inang || *str == Outang || *str == Equals) &&
|
if ((*str == Inang || *str == Outang || *str == Equals) &&
|
||||||
str[1] == Inpar) {
|
str[1] == Inpar) {
|
||||||
if (*str == Inang || *str == Outang)
|
if (*str == Inang || *str == Outang)
|
||||||
|
|
34
Src/text.c
34
Src/text.c
|
@ -169,7 +169,6 @@ gettext2(struct node *n)
|
||||||
if (_List(n)->type & Z_DISOWN)
|
if (_List(n)->type & Z_DISOWN)
|
||||||
taddstr("|");
|
taddstr("|");
|
||||||
}
|
}
|
||||||
simplifyright(_List(n));
|
|
||||||
if (_List(n)->right) {
|
if (_List(n)->right) {
|
||||||
if (tnewlins)
|
if (tnewlins)
|
||||||
taddnl();
|
taddnl();
|
||||||
|
@ -460,22 +459,23 @@ getsimptext(Cmd cmd)
|
||||||
{
|
{
|
||||||
LinkNode n;
|
LinkNode n;
|
||||||
|
|
||||||
for (n = firstnode(cmd->vars); n; incnode(n)) {
|
if (cmd->vars)
|
||||||
struct varasg *v = (struct varasg *)getdata(n);
|
for (n = firstnode(cmd->vars); n; incnode(n)) {
|
||||||
|
struct varasg *v = (struct varasg *)getdata(n);
|
||||||
|
|
||||||
taddstr(v->name);
|
taddstr(v->name);
|
||||||
taddchr('=');
|
taddchr('=');
|
||||||
if (PM_TYPE(v->type) == PM_ARRAY) {
|
if (PM_TYPE(v->type) == PM_ARRAY) {
|
||||||
taddchr('(');
|
taddchr('(');
|
||||||
taddlist(v->arr);
|
taddlist(v->arr);
|
||||||
taddstr(") ");
|
taddstr(") ");
|
||||||
} else if (PM_TYPE(v->type) == PM_HASHED) {
|
} else if (PM_TYPE(v->type) == PM_HASHED) {
|
||||||
/* XXX */
|
/* XXX */
|
||||||
} else {
|
} else {
|
||||||
taddstr(v->str);
|
taddstr(v->str);
|
||||||
taddchr(' ');
|
taddchr(' ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
taddlist(cmd->args);
|
taddlist(cmd->args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,6 +490,8 @@ getredirs(Cmd cmd)
|
||||||
"<<", "<<-", "<<<", "<&", ">&", NULL /* >&- */, "<", ">"
|
"<<", "<<-", "<<<", "<&", ">&", NULL /* >&- */, "<", ">"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!cmd->redir)
|
||||||
|
return;
|
||||||
taddchr(' ');
|
taddchr(' ');
|
||||||
for (n = firstnode(cmd->redir); n; incnode(n)) {
|
for (n = firstnode(cmd->redir); n; incnode(n)) {
|
||||||
struct redir *f = (struct redir *)getdata(n);
|
struct redir *f = (struct redir *)getdata(n);
|
||||||
|
@ -537,7 +539,7 @@ taddlist(LinkList l)
|
||||||
{
|
{
|
||||||
LinkNode n;
|
LinkNode n;
|
||||||
|
|
||||||
if (!(n = firstnode(l)))
|
if (!l || !(n = firstnode(l)))
|
||||||
return;
|
return;
|
||||||
for (; n; incnode(n)) {
|
for (; n; incnode(n)) {
|
||||||
taddstr(getdata(n));
|
taddstr(getdata(n));
|
||||||
|
|
645
Src/utils.c
645
Src/utils.c
|
@ -853,61 +853,131 @@ int resetneeded;
|
||||||
int winchanged;
|
int winchanged;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* check the size of the window and adjust if necessary. *
|
static int
|
||||||
* The value of from: *
|
adjustlines(int signalled)
|
||||||
* 0: called from update_job or setupvals *
|
|
||||||
* 1: called from the SIGWINCH handler *
|
|
||||||
* 2: the user have just changed LINES manually *
|
|
||||||
* 3: the user have just changed COLUMNS manually */
|
|
||||||
|
|
||||||
/**/
|
|
||||||
void
|
|
||||||
adjustwinsize(int from)
|
|
||||||
{
|
{
|
||||||
int oldcols = columns, oldrows = lines;
|
int oldlines = lines;
|
||||||
|
|
||||||
#ifdef TIOCGWINSZ
|
#ifdef TIOCGWINSZ
|
||||||
static int userlines, usercols;
|
if (signalled || lines <= 0)
|
||||||
|
lines = shttyinfo.winsize.ws_row;
|
||||||
if (SHTTY == -1)
|
else
|
||||||
return;
|
shttyinfo.winsize.ws_row = lines;
|
||||||
|
#endif /* TIOCGWINSZ */
|
||||||
if (from == 2)
|
if (lines <= 0) {
|
||||||
userlines = lines > 0;
|
DPUTS(signalled, "BUG: Impossible TIOCGWINSZ rows");
|
||||||
if (from == 3)
|
|
||||||
usercols = columns > 0;
|
|
||||||
|
|
||||||
if (!ioctl(SHTTY, TIOCGWINSZ, (char *)&shttyinfo.winsize)) {
|
|
||||||
if (!userlines || from == 1)
|
|
||||||
lines = shttyinfo.winsize.ws_row;
|
|
||||||
if (!usercols || from == 1)
|
|
||||||
columns = shttyinfo.winsize.ws_col;
|
|
||||||
}
|
|
||||||
#endif /* TIOCGWINSZ */
|
|
||||||
|
|
||||||
if (lines <= 0)
|
|
||||||
lines = tclines > 0 ? tclines : 24;
|
lines = tclines > 0 ? tclines : 24;
|
||||||
if (columns <= 0)
|
}
|
||||||
columns = tccolumns > 0 ? tccolumns : 80;
|
|
||||||
if (lines > 2)
|
if (lines > 2)
|
||||||
termflags &= ~TERM_SHORT;
|
termflags &= ~TERM_SHORT;
|
||||||
else
|
else
|
||||||
termflags |= TERM_SHORT;
|
termflags |= TERM_SHORT;
|
||||||
|
|
||||||
|
return (lines != oldlines);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
adjustcolumns(int signalled)
|
||||||
|
{
|
||||||
|
int oldcolumns = columns;
|
||||||
|
|
||||||
|
#ifdef TIOCGWINSZ
|
||||||
|
if (signalled || columns <= 0)
|
||||||
|
columns = shttyinfo.winsize.ws_col;
|
||||||
|
else
|
||||||
|
shttyinfo.winsize.ws_col = columns;
|
||||||
|
#endif /* TIOCGWINSZ */
|
||||||
|
if (columns <= 0) {
|
||||||
|
DPUTS(signalled, "BUG: Impossible TIOCGWINSZ cols");
|
||||||
|
columns = tccolumns > 0 ? tccolumns : 80;
|
||||||
|
}
|
||||||
|
|
||||||
if (columns > 2)
|
if (columns > 2)
|
||||||
termflags &= ~TERM_NARROW;
|
termflags &= ~TERM_NARROW;
|
||||||
else
|
else
|
||||||
termflags |= TERM_NARROW;
|
termflags |= TERM_NARROW;
|
||||||
|
|
||||||
|
return (columns != oldcolumns);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check the size of the window and adjust if necessary. *
|
||||||
|
* The value of from: *
|
||||||
|
* 0: called from update_job or setupvals *
|
||||||
|
* 1: called from the SIGWINCH handler *
|
||||||
|
* 2: called from the LINES parameter callback *
|
||||||
|
* 3: called from the COLUMNS parameter callback */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void
|
||||||
|
adjustwinsize(int from)
|
||||||
|
{
|
||||||
|
static int getwinsz = 1;
|
||||||
|
int ttyrows = shttyinfo.winsize.ws_row;
|
||||||
|
int ttycols = shttyinfo.winsize.ws_col;
|
||||||
|
int resetzle = 0;
|
||||||
|
|
||||||
|
if (getwinsz || from == 1) {
|
||||||
#ifdef TIOCGWINSZ
|
#ifdef TIOCGWINSZ
|
||||||
if (interact && from >= 2) {
|
if (SHTTY == -1)
|
||||||
shttyinfo.winsize.ws_row = lines;
|
return;
|
||||||
shttyinfo.winsize.ws_col = columns;
|
if (ioctl(SHTTY, TIOCGWINSZ, (char *)&shttyinfo.winsize) == 0) {
|
||||||
|
resetzle = (ttyrows != shttyinfo.winsize.ws_row ||
|
||||||
|
ttycols != shttyinfo.winsize.ws_col);
|
||||||
|
if (from == 0 && resetzle && ttyrows && ttycols)
|
||||||
|
from = 1; /* Signal missed while a job owned the tty? */
|
||||||
|
ttyrows = shttyinfo.winsize.ws_row;
|
||||||
|
ttycols = shttyinfo.winsize.ws_col;
|
||||||
|
} else {
|
||||||
|
/* Set to unknown on failure */
|
||||||
|
shttyinfo.winsize.ws_row = 0;
|
||||||
|
shttyinfo.winsize.ws_col = 0;
|
||||||
|
resetzle = 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
resetzle = from == 1;
|
||||||
|
#endif /* TIOCGWINSZ */
|
||||||
|
} /* else
|
||||||
|
return; */
|
||||||
|
|
||||||
|
switch (from) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
getwinsz = 0;
|
||||||
|
/* Calling setiparam() here calls this function recursively, but *
|
||||||
|
* because we've already called adjustlines() and adjustcolumns() *
|
||||||
|
* here, recursive calls are no-ops unless a signal intervenes. *
|
||||||
|
* The commented "else return;" above might be a safe shortcut, *
|
||||||
|
* but I'm concerned about what happens on race conditions; e.g., *
|
||||||
|
* suppose the user resizes his xterm during `eval $(resize)'? */
|
||||||
|
if (adjustlines(from) && zgetenv("LINES"))
|
||||||
|
setiparam("LINES", lines);
|
||||||
|
if (adjustcolumns(from) && zgetenv("COLUMNS"))
|
||||||
|
setiparam("COLUMNS", columns);
|
||||||
|
getwinsz = 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
resetzle = adjustlines(0);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
resetzle = adjustcolumns(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TIOCGWINSZ
|
||||||
|
if (interact && from >= 2 &&
|
||||||
|
(shttyinfo.winsize.ws_row != ttyrows ||
|
||||||
|
shttyinfo.winsize.ws_col != ttycols)) {
|
||||||
|
/* shttyinfo.winsize is already set up correctly */
|
||||||
ioctl(SHTTY, TIOCSWINSZ, (char *)&shttyinfo.winsize);
|
ioctl(SHTTY, TIOCSWINSZ, (char *)&shttyinfo.winsize);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* TIOCGWINSZ */
|
||||||
|
|
||||||
if (zleactive && (from >= 2 || oldcols != columns || oldrows != lines)) {
|
if (zleactive && resetzle) {
|
||||||
resetneeded = winchanged = 1;
|
#ifdef TIOCGWINSZ
|
||||||
|
winchanged =
|
||||||
|
#endif /* TIOCGWINSZ */
|
||||||
|
resetneeded = 1;
|
||||||
zrefresh();
|
zrefresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1733,13 +1803,12 @@ char *
|
||||||
sepjoin(char **s, char *sep)
|
sepjoin(char **s, char *sep)
|
||||||
{
|
{
|
||||||
char *r, *p, **t;
|
char *r, *p, **t;
|
||||||
int l, sl, elide = 0;
|
int l, sl;
|
||||||
char sepbuf[3];
|
char sepbuf[3];
|
||||||
|
|
||||||
if (!*s)
|
if (!*s)
|
||||||
return "";
|
return "";
|
||||||
if (!sep) {
|
if (!sep) {
|
||||||
elide = 1;
|
|
||||||
sep = sepbuf;
|
sep = sepbuf;
|
||||||
sepbuf[0] = *ifs;
|
sepbuf[0] = *ifs;
|
||||||
sepbuf[1] = *ifs == Meta ? ifs[1] ^ 32 : '\0';
|
sepbuf[1] = *ifs == Meta ? ifs[1] ^ 32 : '\0';
|
||||||
|
@ -1853,329 +1922,21 @@ allocnode(int type)
|
||||||
{
|
{
|
||||||
struct node *n;
|
struct node *n;
|
||||||
|
|
||||||
n = (struct node *) alloc(sizetab[type]);
|
n = (struct node *) ncalloc(sizetab[type]);
|
||||||
memset((void *) n, 0, sizetab[type]);
|
memset((void *) n, 0, sizetab[type]);
|
||||||
n->ntype = flagtab[type];
|
n->ntype = flagtab[type];
|
||||||
if (useheap)
|
|
||||||
n->ntype |= NT_HEAP;
|
|
||||||
|
|
||||||
return (void *) n;
|
return (void *) n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* duplicate a syntax tree */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void *
|
void *
|
||||||
dupstruct(void *a)
|
dupstruct(void *a)
|
||||||
{
|
|
||||||
struct node *n, *r;
|
|
||||||
|
|
||||||
n = (struct node *) a;
|
|
||||||
if (!a || ((List) a) == &dummy_list)
|
|
||||||
return (void *) a;
|
|
||||||
|
|
||||||
if ((n->ntype & NT_HEAP) && !useheap) {
|
|
||||||
HEAPALLOC {
|
|
||||||
n = (struct node *) dupstruct2((void *) n);
|
|
||||||
} LASTALLOC;
|
|
||||||
n = simplifystruct(n);
|
|
||||||
}
|
|
||||||
r = (struct node *)dupstruct2((void *) n);
|
|
||||||
|
|
||||||
if (!(n->ntype & NT_HEAP) && useheap)
|
|
||||||
r = expandstruct(r, N_LIST);
|
|
||||||
|
|
||||||
return (void *) r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**/
|
|
||||||
static struct node *
|
|
||||||
simplifystruct(struct node *n)
|
|
||||||
{
|
|
||||||
if (!n || ((List) n) == &dummy_list)
|
|
||||||
return n;
|
|
||||||
|
|
||||||
switch (NT_TYPE(n->ntype)) {
|
|
||||||
case N_LIST:
|
|
||||||
{
|
|
||||||
List l = (List) n;
|
|
||||||
|
|
||||||
l->left = (Sublist) simplifystruct((struct node *)l->left);
|
|
||||||
if ((l->type & Z_SYNC) && !l->right)
|
|
||||||
return (struct node *)l->left;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_SUBLIST:
|
|
||||||
{
|
|
||||||
Sublist sl = (Sublist) n;
|
|
||||||
|
|
||||||
sl->left = (Pline) simplifystruct((struct node *)sl->left);
|
|
||||||
if (sl->type == END && !sl->flags && !sl->right)
|
|
||||||
return (struct node *)sl->left;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_PLINE:
|
|
||||||
{
|
|
||||||
Pline pl = (Pline) n;
|
|
||||||
|
|
||||||
pl->left = (Cmd) simplifystruct((struct node *)pl->left);
|
|
||||||
if (pl->type == END && !pl->right)
|
|
||||||
return (struct node *)pl->left;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_CMD:
|
|
||||||
{
|
|
||||||
Cmd c = (Cmd) n;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
if (empty(c->args))
|
|
||||||
c->args = NULL, i++;
|
|
||||||
if (empty(c->redir))
|
|
||||||
c->redir = NULL, i++;
|
|
||||||
if (empty(c->vars))
|
|
||||||
c->vars = NULL, i++;
|
|
||||||
|
|
||||||
c->u.list = (List) simplifystruct((struct node *)c->u.list);
|
|
||||||
if (i == 3 && !c->flags &&
|
|
||||||
(c->type == CWHILE || c->type == CIF ||
|
|
||||||
c->type == COND))
|
|
||||||
return (struct node *)c->u.list;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_FOR:
|
|
||||||
{
|
|
||||||
Forcmd f = (Forcmd) n;
|
|
||||||
|
|
||||||
f->list = (List) simplifystruct((struct node *)f->list);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_CASE:
|
|
||||||
{
|
|
||||||
struct casecmd *c = (struct casecmd *)n;
|
|
||||||
List *l;
|
|
||||||
|
|
||||||
for (l = c->lists; *l; l++)
|
|
||||||
*l = (List) simplifystruct((struct node *)*l);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_IF:
|
|
||||||
{
|
|
||||||
struct ifcmd *i = (struct ifcmd *)n;
|
|
||||||
List *l;
|
|
||||||
|
|
||||||
for (l = i->ifls; *l; l++)
|
|
||||||
*l = (List) simplifystruct((struct node *)*l);
|
|
||||||
for (l = i->thenls; *l; l++)
|
|
||||||
*l = (List) simplifystruct((struct node *)*l);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_WHILE:
|
|
||||||
{
|
|
||||||
struct whilecmd *w = (struct whilecmd *)n;
|
|
||||||
|
|
||||||
w->cont = (List) simplifystruct((struct node *)w->cont);
|
|
||||||
w->loop = (List) simplifystruct((struct node *)w->loop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**/
|
|
||||||
struct node *
|
|
||||||
expandstruct(struct node *n, int exp)
|
|
||||||
{
|
|
||||||
struct node *m;
|
|
||||||
|
|
||||||
if (!n || ((List) n) == &dummy_list)
|
|
||||||
return n;
|
|
||||||
|
|
||||||
if (exp != N_COUNT && exp != NT_TYPE(n->ntype)) {
|
|
||||||
switch (exp) {
|
|
||||||
case N_LIST:
|
|
||||||
{
|
|
||||||
List l;
|
|
||||||
|
|
||||||
m = (struct node *) allocnode(N_LIST);
|
|
||||||
l = (List) m;
|
|
||||||
l->type = Z_SYNC;
|
|
||||||
l->left = (Sublist) expandstruct(n, N_SUBLIST);
|
|
||||||
|
|
||||||
return (struct node *)l;
|
|
||||||
}
|
|
||||||
case N_SUBLIST:
|
|
||||||
{
|
|
||||||
Sublist sl;
|
|
||||||
|
|
||||||
m = (struct node *) allocnode(N_SUBLIST);
|
|
||||||
sl = (Sublist) m;
|
|
||||||
sl->type = END;
|
|
||||||
sl->left = (Pline) expandstruct(n, N_PLINE);
|
|
||||||
|
|
||||||
return (struct node *)sl;
|
|
||||||
}
|
|
||||||
case N_PLINE:
|
|
||||||
{
|
|
||||||
Pline pl;
|
|
||||||
|
|
||||||
m = (struct node *) allocnode(N_PLINE);
|
|
||||||
pl = (Pline) m;
|
|
||||||
pl->type = END;
|
|
||||||
pl->left = (Cmd) expandstruct(n, N_CMD);
|
|
||||||
|
|
||||||
return (struct node *)pl;
|
|
||||||
}
|
|
||||||
case N_CMD:
|
|
||||||
{
|
|
||||||
Cmd c;
|
|
||||||
|
|
||||||
m = (struct node *) allocnode(N_CMD);
|
|
||||||
c = (Cmd) m;
|
|
||||||
switch (NT_TYPE(n->ntype)) {
|
|
||||||
case N_WHILE:
|
|
||||||
c->type = CWHILE;
|
|
||||||
break;
|
|
||||||
case N_IF:
|
|
||||||
c->type = CIF;
|
|
||||||
break;
|
|
||||||
case N_COND:
|
|
||||||
c->type = COND;
|
|
||||||
}
|
|
||||||
c->u.list = (List) expandstruct(n, NT_TYPE(n->ntype));
|
|
||||||
c->args = newlinklist();
|
|
||||||
c->vars = newlinklist();
|
|
||||||
c->redir = newlinklist();
|
|
||||||
|
|
||||||
return (struct node *)c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
switch (NT_TYPE(n->ntype)) {
|
|
||||||
case N_LIST:
|
|
||||||
{
|
|
||||||
List l = (List) n;
|
|
||||||
|
|
||||||
l->left = (Sublist) expandstruct((struct node *)l->left,
|
|
||||||
N_SUBLIST);
|
|
||||||
l->right = (List) expandstruct((struct node *)l->right,
|
|
||||||
N_LIST);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_SUBLIST:
|
|
||||||
{
|
|
||||||
Sublist sl = (Sublist) n;
|
|
||||||
|
|
||||||
sl->left = (Pline) expandstruct((struct node *)sl->left,
|
|
||||||
N_PLINE);
|
|
||||||
sl->right = (Sublist) expandstruct((struct node *)sl->right,
|
|
||||||
N_SUBLIST);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_PLINE:
|
|
||||||
{
|
|
||||||
Pline pl = (Pline) n;
|
|
||||||
|
|
||||||
pl->left = (Cmd) expandstruct((struct node *)pl->left,
|
|
||||||
N_CMD);
|
|
||||||
pl->right = (Pline) expandstruct((struct node *)pl->right,
|
|
||||||
N_PLINE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_CMD:
|
|
||||||
{
|
|
||||||
Cmd c = (Cmd) n;
|
|
||||||
|
|
||||||
if (!c->args)
|
|
||||||
c->args = newlinklist();
|
|
||||||
if (!c->vars)
|
|
||||||
c->vars = newlinklist();
|
|
||||||
if (!c->redir)
|
|
||||||
c->redir = newlinklist();
|
|
||||||
|
|
||||||
switch (c->type) {
|
|
||||||
case CFOR:
|
|
||||||
case CSELECT:
|
|
||||||
c->u.list = (List) expandstruct((struct node *)c->u.list,
|
|
||||||
N_FOR);
|
|
||||||
break;
|
|
||||||
case CWHILE:
|
|
||||||
c->u.list = (List) expandstruct((struct node *)c->u.list,
|
|
||||||
N_WHILE);
|
|
||||||
break;
|
|
||||||
case CIF:
|
|
||||||
c->u.list = (List) expandstruct((struct node *)c->u.list,
|
|
||||||
N_IF);
|
|
||||||
break;
|
|
||||||
case CCASE:
|
|
||||||
c->u.list = (List) expandstruct((struct node *)c->u.list,
|
|
||||||
N_CASE);
|
|
||||||
break;
|
|
||||||
case COND:
|
|
||||||
c->u.list = (List) expandstruct((struct node *)c->u.list,
|
|
||||||
N_COND);
|
|
||||||
break;
|
|
||||||
case ZCTIME:
|
|
||||||
c->u.list = (List) expandstruct((struct node *)c->u.list,
|
|
||||||
N_SUBLIST);
|
|
||||||
break;
|
|
||||||
case AUTOFN:
|
|
||||||
c->u.list = (List) expandstruct((struct node *)c->u.list,
|
|
||||||
N_AUTOFN);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c->u.list = (List) expandstruct((struct node *)c->u.list,
|
|
||||||
N_LIST);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_FOR:
|
|
||||||
{
|
|
||||||
Forcmd f = (Forcmd) n;
|
|
||||||
|
|
||||||
f->list = (List) expandstruct((struct node *)f->list,
|
|
||||||
N_LIST);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_CASE:
|
|
||||||
{
|
|
||||||
struct casecmd *c = (struct casecmd *)n;
|
|
||||||
List *l;
|
|
||||||
|
|
||||||
for (l = c->lists; *l; l++)
|
|
||||||
*l = (List) expandstruct((struct node *)*l, N_LIST);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_IF:
|
|
||||||
{
|
|
||||||
struct ifcmd *i = (struct ifcmd *)n;
|
|
||||||
List *l;
|
|
||||||
|
|
||||||
for (l = i->ifls; *l; l++)
|
|
||||||
*l = (List) expandstruct((struct node *)*l, N_LIST);
|
|
||||||
for (l = i->thenls; *l; l++)
|
|
||||||
*l = (List) expandstruct((struct node *)*l, N_LIST);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case N_WHILE:
|
|
||||||
{
|
|
||||||
struct whilecmd *w = (struct whilecmd *)n;
|
|
||||||
|
|
||||||
w->cont = (List) expandstruct((struct node *)w->cont,
|
|
||||||
N_LIST);
|
|
||||||
w->loop = (List) expandstruct((struct node *)w->loop,
|
|
||||||
N_LIST);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* duplicate a syntax tree */
|
|
||||||
|
|
||||||
/**/
|
|
||||||
static void *
|
|
||||||
dupstruct2(void *a)
|
|
||||||
{
|
{
|
||||||
void **onodes, **nnodes, *ret, *n, *on;
|
void **onodes, **nnodes, *ret, *n, *on;
|
||||||
int type, heap;
|
int type;
|
||||||
size_t nodeoffs;
|
size_t nodeoffs;
|
||||||
|
|
||||||
if (!a || ((List) a) == &dummy_list)
|
if (!a || ((List) a) == &dummy_list)
|
||||||
|
@ -2183,53 +1944,33 @@ dupstruct2(void *a)
|
||||||
type = *(int *)a;
|
type = *(int *)a;
|
||||||
ret = alloc(sizetab[NT_TYPE(type)]);
|
ret = alloc(sizetab[NT_TYPE(type)]);
|
||||||
memcpy(ret, a, nodeoffs = offstab[NT_TYPE(type)]);
|
memcpy(ret, a, nodeoffs = offstab[NT_TYPE(type)]);
|
||||||
*(int*)ret = (type & ~NT_HEAP) | (useheap ? NT_HEAP : 0);
|
|
||||||
onodes = (void **) ((char *)a + nodeoffs);
|
onodes = (void **) ((char *)a + nodeoffs);
|
||||||
nnodes = (void **) ((char *)ret + nodeoffs);
|
nnodes = (void **) ((char *)ret + nodeoffs);
|
||||||
heap = type & NT_HEAP;
|
|
||||||
for (type = (type & 0xffff00) >> 4; (type >>= 4); *nnodes++ = n) {
|
for (type = (type & 0xffff00) >> 4; (type >>= 4); *nnodes++ = n) {
|
||||||
if (!(on = *onodes++))
|
if (!(on = *onodes++))
|
||||||
n = NULL;
|
n = NULL;
|
||||||
else {
|
else {
|
||||||
switch (type & 0xf) {
|
switch (type & 0xf) {
|
||||||
case NT_NODE:
|
case NT_NODE:
|
||||||
n = dupstruct2(on);
|
n = dupstruct(on);
|
||||||
break;
|
break;
|
||||||
case NT_STR:
|
case NT_STR:
|
||||||
n = dupstring(on);
|
n = dupstring(on);
|
||||||
break;
|
break;
|
||||||
case NT_LIST | NT_NODE:
|
case NT_LIST | NT_NODE:
|
||||||
if (heap) {
|
n = duplist(on, (VFunc) dupstruct);
|
||||||
if (useheap)
|
|
||||||
n = duplist(on, (VFunc) dupstruct2);
|
|
||||||
else
|
|
||||||
n = list2arr(on, (VFunc) dupstruct2);
|
|
||||||
}
|
|
||||||
else if (useheap)
|
|
||||||
n = arr2list(on, (VFunc) dupstruct2);
|
|
||||||
else
|
|
||||||
n = duparray(on, (VFunc) dupstruct2);
|
|
||||||
break;
|
break;
|
||||||
case NT_LIST | NT_STR:
|
case NT_LIST | NT_STR:
|
||||||
if (heap) {
|
n = duplist(on, (VFunc) (useheap ? dupstring : ztrdup));
|
||||||
if (useheap)
|
|
||||||
n = duplist(on, (VFunc) dupstring);
|
|
||||||
else
|
|
||||||
n = list2arr(on, (VFunc) ztrdup);
|
|
||||||
}
|
|
||||||
else if (useheap)
|
|
||||||
n = arr2list(on, (VFunc) dupstring);
|
|
||||||
else
|
|
||||||
n = duparray(on, (VFunc) ztrdup);
|
|
||||||
break;
|
break;
|
||||||
case NT_NODE | NT_ARR:
|
case NT_NODE | NT_ARR:
|
||||||
n = duparray(on, (VFunc) dupstruct2);
|
n = duparray(on, (VFunc) dupstruct);
|
||||||
break;
|
break;
|
||||||
case NT_STR | NT_ARR:
|
case NT_STR | NT_ARR:
|
||||||
n = duparray(on, (VFunc) (useheap ? dupstring : ztrdup));
|
n = duparray(on, (VFunc) (useheap ? dupstring : ztrdup));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DPUTS(1, "BUG: bad node type in dupstruct2()");
|
DPUTS(1, "BUG: bad node type in dupstruct()");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2237,19 +1978,46 @@ dupstruct2(void *a)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free a syntax tree */
|
/* Free a syntax tree. Now, freestruct() only registers everything that
|
||||||
|
* has to be freed. Later, freestructs() will be called to do the real
|
||||||
|
* work. This is to avoid having functions that are currently executed
|
||||||
|
* free themselves by re-defining themselves. */
|
||||||
|
|
||||||
|
static LinkList freeslist = NULL;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
freestruct(void *a)
|
freestruct(void *a)
|
||||||
{
|
{
|
||||||
void **nodes, *n;
|
|
||||||
int type, size;
|
|
||||||
|
|
||||||
if (!a || ((List) a) == &dummy_list)
|
if (!a || ((List) a) == &dummy_list)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
type = * (int *) a;
|
PERMALLOC {
|
||||||
|
if (!freeslist)
|
||||||
|
freeslist = newlinklist();
|
||||||
|
addlinknode(freeslist, a);
|
||||||
|
} LASTALLOC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void
|
||||||
|
freestructs(void)
|
||||||
|
{
|
||||||
|
void *a;
|
||||||
|
|
||||||
|
if (freeslist)
|
||||||
|
while ((a = getlinknode(freeslist)))
|
||||||
|
ifreestruct(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static void
|
||||||
|
ifreestruct(void *a)
|
||||||
|
{
|
||||||
|
void **nodes, *n;
|
||||||
|
int type, size;
|
||||||
|
|
||||||
|
type = *(int *) a;
|
||||||
nodes = (void **) ((char *)a + offstab[NT_TYPE(type)]);
|
nodes = (void **) ((char *)a + offstab[NT_TYPE(type)]);
|
||||||
size = sizetab[NT_TYPE(type)];
|
size = sizetab[NT_TYPE(type)];
|
||||||
for (type = (type & 0xffff00) >> 4; (type >>= 4);) {
|
for (type = (type & 0xffff00) >> 4; (type >>= 4);) {
|
||||||
|
@ -2262,6 +2030,8 @@ freestruct(void *a)
|
||||||
zsfree((char *) n);
|
zsfree((char *) n);
|
||||||
break;
|
break;
|
||||||
case NT_LIST | NT_NODE:
|
case NT_LIST | NT_NODE:
|
||||||
|
freelinklist((LinkList) n, (FreeFunc) freestruct);
|
||||||
|
break;
|
||||||
case NT_NODE | NT_ARR:
|
case NT_NODE | NT_ARR:
|
||||||
{
|
{
|
||||||
void **p = (void **) n;
|
void **p = (void **) n;
|
||||||
|
@ -2272,6 +2042,8 @@ freestruct(void *a)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NT_LIST | NT_STR:
|
case NT_LIST | NT_STR:
|
||||||
|
freelinklist((LinkList) n, (FreeFunc) zsfree);
|
||||||
|
break;
|
||||||
case NT_STR | NT_ARR:
|
case NT_STR | NT_ARR:
|
||||||
freearray((char **) n);
|
freearray((char **) n);
|
||||||
break;
|
break;
|
||||||
|
@ -2286,59 +2058,47 @@ freestruct(void *a)
|
||||||
zfree(a, size);
|
zfree(a, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
LinkList
|
||||||
|
dupheaplist(LinkList l)
|
||||||
|
{
|
||||||
|
if (!l)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return duplist(l, (VFunc) dupstruct);
|
||||||
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static LinkList
|
static LinkList
|
||||||
duplist(LinkList l, VFunc func)
|
duplist(LinkList l, VFunc func)
|
||||||
{
|
{
|
||||||
LinkList ret;
|
if (l && nonempty(l)) {
|
||||||
LinkNode node;
|
LinkList ret;
|
||||||
|
LinkNode node;
|
||||||
|
|
||||||
ret = newlinklist();
|
ret = newlinklist();
|
||||||
for (node = firstnode(l); node; incnode(node))
|
for (node = firstnode(l); node; incnode(node))
|
||||||
addlinknode(ret, func(getdata(node)));
|
addlinknode(ret, func(getdata(node)));
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
char **
|
char **
|
||||||
duparray(char **arr, VFunc func)
|
duparray(char **arr, VFunc func)
|
||||||
{
|
{
|
||||||
char **ret, **rr;
|
if (arr && *arr) {
|
||||||
|
char **ret, **rr, *p;
|
||||||
|
|
||||||
ret = (char **) alloc((arrlen(arr) + 1) * sizeof(char *));
|
ret = (char **) alloc((arrlen(arr) + 1) * sizeof(char *));
|
||||||
for (rr = ret; *arr;)
|
for (rr = ret; (p = *arr++);)
|
||||||
*rr++ = (char *)func(*arr++);
|
*rr++ = (char *)func(p);
|
||||||
*rr = NULL;
|
*rr = NULL;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
/**/
|
|
||||||
static char **
|
|
||||||
list2arr(LinkList l, VFunc func)
|
|
||||||
{
|
|
||||||
char **arr, **r;
|
|
||||||
LinkNode n;
|
|
||||||
|
|
||||||
arr = r = (char **) alloc((countlinknodes(l) + 1) * sizeof(char *));
|
|
||||||
|
|
||||||
for (n = firstnode(l); n; incnode(n))
|
|
||||||
*r++ = (char *)func(getdata(n));
|
|
||||||
*r = NULL;
|
|
||||||
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**/
|
|
||||||
static LinkList
|
|
||||||
arr2list(char **arr, VFunc func)
|
|
||||||
{
|
|
||||||
LinkList l = newlinklist();
|
|
||||||
|
|
||||||
while (*arr)
|
|
||||||
addlinknode(l, func(*arr++));
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
@ -2384,28 +2144,6 @@ equalsplit(char *s, char **t)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* see if the right side of a list is trivial */
|
|
||||||
|
|
||||||
/**/
|
|
||||||
void
|
|
||||||
simplifyright(List l)
|
|
||||||
{
|
|
||||||
Cmd c;
|
|
||||||
|
|
||||||
if (l == &dummy_list || !l->right)
|
|
||||||
return;
|
|
||||||
if (l->right->right || l->right->left->right ||
|
|
||||||
l->right->left->flags || l->right->left->left->right ||
|
|
||||||
l->left->flags)
|
|
||||||
return;
|
|
||||||
c = l->left->left->left;
|
|
||||||
if (c->type != SIMPLE || nonempty(c->args) || nonempty(c->redir)
|
|
||||||
|| nonempty(c->vars))
|
|
||||||
return;
|
|
||||||
l->right = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the ztypes table */
|
/* the ztypes table */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
@ -2470,6 +2208,25 @@ arrdup(char **s)
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Duplicate a list of strings. */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
LinkList
|
||||||
|
listdup(LinkList l)
|
||||||
|
{
|
||||||
|
if (!l)
|
||||||
|
return NULL;
|
||||||
|
else {
|
||||||
|
LinkList r = newlinklist();
|
||||||
|
LinkNode n;
|
||||||
|
|
||||||
|
for (n = firstnode(l); n; incnode(n))
|
||||||
|
addlinknode(r, dupstring((char *) getdata(n)));
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
char **
|
char **
|
||||||
listarr(LinkList l)
|
listarr(LinkList l)
|
||||||
|
|
|
@ -75,6 +75,7 @@ findcmd
|
||||||
firsthist
|
firsthist
|
||||||
freearray
|
freearray
|
||||||
freeheap
|
freeheap
|
||||||
|
freelinklist
|
||||||
freestruct
|
freestruct
|
||||||
getaparam
|
getaparam
|
||||||
gethashnode
|
gethashnode
|
||||||
|
@ -113,6 +114,7 @@ hist_skip_flags
|
||||||
holdintr
|
holdintr
|
||||||
hptr
|
hptr
|
||||||
hrealloc
|
hrealloc
|
||||||
|
ifs
|
||||||
inbufct
|
inbufct
|
||||||
incmdpos
|
incmdpos
|
||||||
incond
|
incond
|
||||||
|
@ -179,7 +181,6 @@ path
|
||||||
pathchecked
|
pathchecked
|
||||||
popheap
|
popheap
|
||||||
postedit
|
postedit
|
||||||
pparams
|
|
||||||
ppid
|
ppid
|
||||||
prefork
|
prefork
|
||||||
prepromptfns
|
prepromptfns
|
||||||
|
|
14
Src/zsh.h
14
Src/zsh.h
|
@ -47,7 +47,11 @@
|
||||||
*/
|
*/
|
||||||
#ifdef ZSH_64_BIT_TYPE
|
#ifdef ZSH_64_BIT_TYPE
|
||||||
typedef ZSH_64_BIT_TYPE zlong;
|
typedef ZSH_64_BIT_TYPE zlong;
|
||||||
typedef unsigned ZSH_64_BIT_TYPE zulong;
|
#ifdef ZSH_64_BIT_UTYPE
|
||||||
|
typedef ZSH_64_BIT_UTYPE zulong;
|
||||||
|
#else
|
||||||
|
typedef unsigned zlong zulong;
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
typedef long zlong;
|
typedef long zlong;
|
||||||
typedef unsigned long zulong;
|
typedef unsigned long zulong;
|
||||||
|
@ -352,7 +356,6 @@ struct node {
|
||||||
#define NT_N(T, N) (((T) >> (8 + (N) * 4)) & 0xf)
|
#define NT_N(T, N) (((T) >> (8 + (N) * 4)) & 0xf)
|
||||||
#define NT_SET(T0, T1, T2, T3, T4) \
|
#define NT_SET(T0, T1, T2, T3, T4) \
|
||||||
((T0) | ((T1) << 8) | ((T2) << 12) | ((T3) << 16) | ((T4) << 20))
|
((T0) | ((T1) << 8) | ((T2) << 12) | ((T3) << 16) | ((T4) << 20))
|
||||||
#define NT_HEAP (1 << 30)
|
|
||||||
|
|
||||||
/* tree element for lists */
|
/* tree element for lists */
|
||||||
|
|
||||||
|
@ -605,7 +608,7 @@ struct job {
|
||||||
pid_t gleader; /* process group leader of this job */
|
pid_t gleader; /* process group leader of this job */
|
||||||
pid_t other; /* subjob id or subshell pid */
|
pid_t other; /* subjob id or subshell pid */
|
||||||
int stat; /* see STATs below */
|
int stat; /* see STATs below */
|
||||||
char *pwd; /* current working dir of shell when *
|
char pwd[PATH_MAX + 1]; /* current working dir of shell when *
|
||||||
* this job was spawned */
|
* this job was spawned */
|
||||||
struct process *procs; /* list of processes */
|
struct process *procs; /* list of processes */
|
||||||
LinkList filelist; /* list of files to delete when done */
|
LinkList filelist; /* list of files to delete when done */
|
||||||
|
@ -948,7 +951,12 @@ struct param {
|
||||||
#define PM_READONLY (1<<8) /* readonly */
|
#define PM_READONLY (1<<8) /* readonly */
|
||||||
#define PM_TAGGED (1<<9) /* tagged */
|
#define PM_TAGGED (1<<9) /* tagged */
|
||||||
#define PM_EXPORTED (1<<10) /* exported */
|
#define PM_EXPORTED (1<<10) /* exported */
|
||||||
|
|
||||||
|
/* The following are the same since they *
|
||||||
|
* both represent -U option to typeset */
|
||||||
#define PM_UNIQUE (1<<11) /* remove duplicates */
|
#define PM_UNIQUE (1<<11) /* remove duplicates */
|
||||||
|
#define PM_UNALIASED (1<<11) /* do not expand aliases when autoloading */
|
||||||
|
|
||||||
#define PM_TIED (1<<12) /* array tied to colon-path or v.v. */
|
#define PM_TIED (1<<12) /* array tied to colon-path or v.v. */
|
||||||
#define PM_SPECIAL (1<<13) /* special builtin parameter */
|
#define PM_SPECIAL (1<<13) /* special builtin parameter */
|
||||||
#define PM_DONTIMPORT (1<<14) /* do not import this variable */
|
#define PM_DONTIMPORT (1<<14) /* do not import this variable */
|
||||||
|
|
11
Src/zsh.mdd
11
Src/zsh.mdd
|
@ -31,7 +31,16 @@ version.h: $(sdir_top)/Config/version.mk
|
||||||
zshpaths.h: FORCE Makemod
|
zshpaths.h: FORCE Makemod
|
||||||
@echo '#define MODULE_DIR "'$(MODDIR)'"' > zshpaths.h.tmp
|
@echo '#define MODULE_DIR "'$(MODDIR)'"' > zshpaths.h.tmp
|
||||||
@if test x$(fndir) != xno; then \
|
@if test x$(fndir) != xno; then \
|
||||||
echo '#define FUNCTION_DIR "'$(fndir)'"' >> zshpaths.h.tmp; \
|
echo '#define FPATH_DIR "'$(fndir)'"' >> zshpaths.h.tmp; \
|
||||||
|
if test x$(FUNCTIONS_SUBDIRS) != x -a \
|
||||||
|
x$(FUNCTIONS_SUBDIRS) != xno; then \
|
||||||
|
fpath_tmp="`for f in $$FUNCTIONS_INSTALL; do \
|
||||||
|
echo $$f | sed s%/.*%%; \
|
||||||
|
done | sort | uniq`"; \
|
||||||
|
fpath_tmp="`echo $$fpath_tmp | sed 's/ /\", \"/g'`"; \
|
||||||
|
echo "#define FPATH_SUBDIRS { \"$$fpath_tmp\" }" \
|
||||||
|
>>zshpaths.h.tmp; \
|
||||||
|
fi; \
|
||||||
fi
|
fi
|
||||||
@if cmp -s zshpaths.h zshpaths.h.tmp; then \
|
@if cmp -s zshpaths.h zshpaths.h.tmp; then \
|
||||||
rm -f zshpaths.h.tmp; \
|
rm -f zshpaths.h.tmp; \
|
||||||
|
|
|
@ -504,3 +504,21 @@ Documentation
|
||||||
ocurring in the main text, "plugh" is a normal word that is being quoted
|
ocurring in the main text, "plugh" is a normal word that is being quoted
|
||||||
(it's the user that says `plugh', not the documentation), and "xyzzy"
|
(it's the user that says `plugh', not the documentation), and "xyzzy"
|
||||||
is some text to be typed literally that is being quoted.
|
is some text to be typed literally that is being quoted.
|
||||||
|
|
||||||
|
* For multiple-line pieces of text that should not be filled, there are
|
||||||
|
various models.
|
||||||
|
- If the text is pure example, i.e. with no metasyntactic variables etc.,
|
||||||
|
it should be included within `example(...)'. The text will be
|
||||||
|
indented, will not be filled and will be put into a fixed width font.
|
||||||
|
- If the text includes mixed fonts, it should be included within
|
||||||
|
`indent(...)'. As with `example()', the text is not filled, but now
|
||||||
|
explicit font-changing commands are required inside.
|
||||||
|
- If the text appears inside some other format, such as for example the
|
||||||
|
`item()' list structure, then the instruction `nofill(...)', which
|
||||||
|
simply turns off filling should be used; as with `indent(...)',
|
||||||
|
explicit font changing commands are required. This is also an
|
||||||
|
alternative to `indent()' when no identation is required, e.g. if the
|
||||||
|
accumulated indentation would otherwise be too long.
|
||||||
|
All the above should appear on their own, separated by newlines from the
|
||||||
|
surrounding text. No extra newlines after the opening or before the
|
||||||
|
closing parenthesis are required.
|
||||||
|
|
|
@ -248,9 +248,12 @@
|
||||||
/* Define to 1 if long is 64 bits */
|
/* Define to 1 if long is 64 bits */
|
||||||
#undef LONG_IS_64_BIT
|
#undef LONG_IS_64_BIT
|
||||||
|
|
||||||
/* Define to a 64 bit type if there is one, but long is shorter */
|
/* Define to a 64 bit integer type if there is one, but long is shorter */
|
||||||
#undef ZSH_64_BIT_TYPE
|
#undef ZSH_64_BIT_TYPE
|
||||||
|
|
||||||
|
/* Define to an unsigned variant of ZSH_64_BIT_TYPE if that is defined */
|
||||||
|
#undef ZSH_64_BIT_UTYPE
|
||||||
|
|
||||||
/* Define to 1 if off_t is 64 bit (for large file support) */
|
/* Define to 1 if off_t is 64 bit (for large file support) */
|
||||||
#undef OFF_T_IS_64_BIT
|
#undef OFF_T_IS_64_BIT
|
||||||
|
|
||||||
|
|
24
aczsh.m4
24
aczsh.m4
|
@ -41,11 +41,13 @@ for ac_shellvar in $ac_shellvars; do
|
||||||
CPPFLAGS) ac_lfsvar=LFS_CFLAGS ;;
|
CPPFLAGS) ac_lfsvar=LFS_CFLAGS ;;
|
||||||
*) ac_lfsvar=LFS_$ac_shellvar ;;
|
*) ac_lfsvar=LFS_$ac_shellvar ;;
|
||||||
esac
|
esac
|
||||||
eval test '"${'$ac_shellvar'+set}"' = set && ac_set=$ac_shellvar
|
|
||||||
(getconf $ac_lfsvar) >/dev/null 2>&1 || { ac_result=no; break; }
|
(getconf $ac_lfsvar) >/dev/null 2>&1 || { ac_result=no; break; }
|
||||||
ac_getconf=`getconf $ac_lfsvar`
|
ac_getconf=`getconf $ac_lfsvar`
|
||||||
ac_getconfs=$ac_getconfs$ac_getconf
|
if test -n "$ac_getconf"; then
|
||||||
eval ac_test_$ac_shellvar="\$ac_getconf"
|
eval test '"${'$ac_shellvar'+set}"' = set && ac_set=$ac_shellvar
|
||||||
|
ac_getconfs=$ac_getconfs$ac_getconf
|
||||||
|
eval ac_test_$ac_shellvar="\$ac_getconf"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
case "$ac_result$ac_getconfs" in
|
case "$ac_result$ac_getconfs" in
|
||||||
yes) ac_result=no ;;
|
yes) ac_result=no ;;
|
||||||
|
@ -74,12 +76,12 @@ esac
|
||||||
dnl
|
dnl
|
||||||
dnl zsh_64_BIT_TYPE
|
dnl zsh_64_BIT_TYPE
|
||||||
dnl Check whether the first argument works as a 64-bit type.
|
dnl Check whether the first argument works as a 64-bit type.
|
||||||
dnl If there is a non-zero second argument, we just assume it works
|
dnl If there is a non-zero third argument, we just assume it works
|
||||||
dnl when we're cross compiling. This is to allow a type to be
|
dnl when we're cross compiling. This is to allow a type to be
|
||||||
dnl specified directly as --enable-lfs="long long".
|
dnl specified directly as --enable-lfs="long long".
|
||||||
dnl Sets zsh_cv_64_bit_type to the first argument if the test worked,
|
dnl Sets the variable given in the second argument to the first argument
|
||||||
dnl `no' otherwise. Be careful testing this, as it may produce
|
dnl if the test worked, `no' otherwise. Be careful testing this, as it
|
||||||
dnl two words `long long' on an unquoted substitution.
|
dnl may produce two words `long long' on an unquoted substitution.
|
||||||
dnl This macro does not produce messages as it may be run several times
|
dnl This macro does not produce messages as it may be run several times
|
||||||
dnl before finding the right type.
|
dnl before finding the right type.
|
||||||
dnl
|
dnl
|
||||||
|
@ -95,11 +97,11 @@ main()
|
||||||
$1 foo = 0;
|
$1 foo = 0;
|
||||||
return sizeof($1) != 8;
|
return sizeof($1) != 8;
|
||||||
}
|
}
|
||||||
], zsh_cv_64_bit_type="$1", zsh_cv_64_bit_type=no,
|
], $2="$1", $2=no,
|
||||||
[if test x$2 != x ; then
|
[if test x$3 != x ; then
|
||||||
zsh_cv_64_bit_type="$1"
|
$2="$1"
|
||||||
else
|
else
|
||||||
zsh_cv_64_bit_type=no
|
$2=no
|
||||||
fi])
|
fi])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
118
configure.in
118
configure.in
|
@ -97,8 +97,7 @@ AC_ARG_ENABLE(zsh-hash-debug,
|
||||||
AC_DEFINE(ZSH_HASH_DEBUG)
|
AC_DEFINE(ZSH_HASH_DEBUG)
|
||||||
fi])
|
fi])
|
||||||
|
|
||||||
dnl Do you want large file support, if available (mostly Solaris)?
|
dnl Do you want large file support, if available?
|
||||||
dnl Currently this is only partially implemented.
|
|
||||||
undefine([lfs])dnl
|
undefine([lfs])dnl
|
||||||
AC_ARG_ENABLE(lfs,
|
AC_ARG_ENABLE(lfs,
|
||||||
[ --enable-lfs turn on support for large files])
|
[ --enable-lfs turn on support for large files])
|
||||||
|
@ -203,18 +202,35 @@ AC_DEFINE(RESTRICTED_R)
|
||||||
|
|
||||||
undefine([fndir])dnl
|
undefine([fndir])dnl
|
||||||
AC_ARG_ENABLE(fndir,
|
AC_ARG_ENABLE(fndir,
|
||||||
[ --enable-fndir=DIR where functions go (default DATADIR/zsh-fns)],
|
[ --enable-fndir=DIR where functions go (default DATADIR/zsh/functions)],
|
||||||
[fndir="$enableval"], [fndir=${datadir}/zsh/functions])
|
[if test $enableval = yes; then
|
||||||
|
fndir=${datadir}/zsh/functions
|
||||||
|
else
|
||||||
|
fndir="$enableval"
|
||||||
|
fi], [fndir=${datadir}/zsh/functions])
|
||||||
|
|
||||||
if test x${FUNCTIONS_INSTALL+set} != xset; then
|
undefine([function_subdirs])
|
||||||
|
AC_ARG_ENABLE(function-subdirs,
|
||||||
|
[ --enable-function-subdirs install functions in subdirectories])
|
||||||
|
|
||||||
|
if test "x${FUNCTIONS_INSTALL+set}" != xset; then
|
||||||
FUNCTIONS_INSTALL="Core/* Base/* Builtins/* User/* Commands/*"
|
FUNCTIONS_INSTALL="Core/* Base/* Builtins/* User/* Commands/*"
|
||||||
if test $dynamic != no; then
|
if test $dynamic != no; then
|
||||||
FUNCTIONS_INSTALL="${FUNCTIONS_INSTALL} Zftp/*"
|
FUNCTIONS_INSTALL="${FUNCTIONS_INSTALL} Zftp/*"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "x${enable_function_subdirs}" != x -a \
|
||||||
|
"x${enable_function_subdirs}" != xno -a \
|
||||||
|
"x$FUNCTIONS_INSTALL" != x; then
|
||||||
|
FUNCTIONS_SUBDIRS=yes
|
||||||
|
else
|
||||||
|
FUNCTIONS_SUBDIRS=no
|
||||||
|
fi
|
||||||
|
|
||||||
AC_SUBST(fndir)dnl
|
AC_SUBST(fndir)dnl
|
||||||
AC_SUBST(FUNCTIONS_INSTALL)dnl
|
AC_SUBST(FUNCTIONS_INSTALL)dnl
|
||||||
|
AC_SUBST(FUNCTIONS_SUBDIRS)dnl
|
||||||
|
|
||||||
dnl ------------------
|
dnl ------------------
|
||||||
dnl CHECK THE COMPILER
|
dnl CHECK THE COMPILER
|
||||||
|
@ -225,7 +241,7 @@ test -z "${LDFLAGS+set}" && LDFLAGS= auto_ldflags=1
|
||||||
|
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
|
|
||||||
dnl Check for large file support (Solaris).
|
dnl Check for large file support.
|
||||||
dnl This needs to be done early to get the stuff into the flags.
|
dnl This needs to be done early to get the stuff into the flags.
|
||||||
if test "x$enable_lfs" != x; then
|
if test "x$enable_lfs" != x; then
|
||||||
zsh_LARGE_FILE_SUPPORT
|
zsh_LARGE_FILE_SUPPORT
|
||||||
|
@ -552,44 +568,69 @@ zsh_cv_long_is_64_bit=no)])
|
||||||
|
|
||||||
if test $zsh_cv_long_is_64_bit = yes; then
|
if test $zsh_cv_long_is_64_bit = yes; then
|
||||||
AC_DEFINE(LONG_IS_64_BIT)
|
AC_DEFINE(LONG_IS_64_BIT)
|
||||||
elif test "x$enable_lfs" != x; then
|
else
|
||||||
AC_CACHE_CHECK(if compiler has a 64 bit type, zsh_cv_64_bit_type,
|
AC_CACHE_CHECK(if off_t is 64 bit, zsh_cv_off_t_is_64_bit,
|
||||||
[if test "x$enable_lfs" != xyes; then
|
[AC_TRY_RUN([
|
||||||
zsh_64_BIT_TYPE(${enable_lfs})
|
|
||||||
else
|
|
||||||
zsh_64_BIT_TYPE(long long)
|
|
||||||
if test "$zsh_cv_64_bit_type" = no; then
|
|
||||||
zsh_64_BIT_TYPE(quad_t)
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
if test "$zsh_cv_64_bit_type" != no; then
|
|
||||||
AC_DEFINE_UNQUOTED(ZSH_64_BIT_TYPE, $zsh_cv_64_bit_type)
|
|
||||||
|
|
||||||
AC_CACHE_CHECK(if off_t is 64 bit, zsh_cv_off_t_is_64_bit,
|
|
||||||
[AC_TRY_RUN([
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
main() { return sizeof(off_t) < 8; }
|
main() { return sizeof(off_t) < 8; }
|
||||||
],
|
],
|
||||||
zsh_cv_off_t_is_64_bit=yes,
|
zsh_cv_off_t_is_64_bit=yes,
|
||||||
zsh_cv_off_t_is_64_bit=no,
|
zsh_cv_off_t_is_64_bit=no,
|
||||||
zsh_cv_off_t_is_64_bit=no)])
|
zsh_cv_off_t_is_64_bit=no)])
|
||||||
if test $zsh_cv_off_t_is_64_bit = yes; then
|
if test $zsh_cv_off_t_is_64_bit = yes; then
|
||||||
AC_DEFINE(OFF_T_IS_64_BIT)
|
AC_DEFINE(OFF_T_IS_64_BIT)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_CACHE_CHECK(if ino_t is 64 bit, zsh_cv_ino_t_is_64_bit,
|
AC_CACHE_CHECK(if ino_t is 64 bit, zsh_cv_ino_t_is_64_bit,
|
||||||
[AC_TRY_RUN([
|
[AC_TRY_RUN([
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
main() { return sizeof(ino_t) < 8; }
|
main() { return sizeof(ino_t) < 8; }
|
||||||
],
|
],
|
||||||
zsh_cv_ino_t_is_64_bit=yes,
|
zsh_cv_ino_t_is_64_bit=yes,
|
||||||
zsh_cv_ino_t_is_64_bit=no,
|
zsh_cv_ino_t_is_64_bit=no,
|
||||||
zsh_cv_ino_t_is_64_bit=no)])
|
zsh_cv_ino_t_is_64_bit=no)])
|
||||||
if test $zsh_cv_ino_t_is_64_bit = yes; then
|
if test $zsh_cv_ino_t_is_64_bit = yes; then
|
||||||
AC_DEFINE(INO_T_IS_64_BIT)
|
AC_DEFINE(INO_T_IS_64_BIT)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$enable_lfs" != xno -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 "x$enable_lfs" != xyes -a "x$enable_lfs" != xno; then
|
||||||
|
zsh_64_BIT_TYPE(${enable_lfs}, zsh_cv_64_bit_type, force)
|
||||||
|
else
|
||||||
|
zsh_64_BIT_TYPE(long long, zsh_cv_64_bit_type)
|
||||||
|
if test "$zsh_cv_64_bit_type" = no; then
|
||||||
|
zsh_64_BIT_TYPE(quad_t, zsh_cv_64_bit_type)
|
||||||
|
fi
|
||||||
|
if test "$zsh_cv_64_bit_type" = no; then
|
||||||
|
zsh_64_BIT_TYPE(__int64_t, zsh_cv_64_bit_type)
|
||||||
|
fi
|
||||||
|
dnl As a last resort, if we know off_t has 64 bits, use that as
|
||||||
|
dnl the 64-bit integer type. I don't dare try ino_t since there's
|
||||||
|
dnl probably nothing to stop that being unsigned.
|
||||||
|
if test "$zsh_cv_64_bit_type" = no -a \
|
||||||
|
"$zsh_cv_off_t_is_64_bit" = yes; then
|
||||||
|
zsh_64_BIT_TYPE(off_t, zsh_cv_64_bit_type)
|
||||||
|
fi
|
||||||
|
fi])
|
||||||
|
if test "$zsh_cv_64_bit_type" != no; then
|
||||||
|
AC_DEFINE_UNQUOTED(ZSH_64_BIT_TYPE, $zsh_cv_64_bit_type)
|
||||||
|
|
||||||
|
dnl Handle cases where unsigned type cannot be simply
|
||||||
|
dnl `unsigned ZSH_64_BIT_TYPE'. More tests may be required.
|
||||||
|
AC_CACHE_CHECK(for a corresponding unsigned 64 bit type,
|
||||||
|
zsh_cv_64_bit_utype,
|
||||||
|
[zsh_64_BIT_TYPE(unsigned $zsh_cv_64_bit_type, zsh_cv_64_bit_utype,
|
||||||
|
force)
|
||||||
|
if test "$zsh_cv_64_bit_utype" = no; then
|
||||||
|
zsh_64_BIT_TYPE(__uint64_t, zsh_cv_64_bit_utype)
|
||||||
|
fi])
|
||||||
|
if test "$zsh_cv_64_bit_utype" != no; then
|
||||||
|
AC_DEFINE_UNQUOTED(ZSH_64_BIT_UTYPE, $zsh_cv_64_bit_utype)
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -1326,6 +1367,7 @@ eval "zshbin1=${bindir}"
|
||||||
eval "zshbin2=${zshbin1}"
|
eval "zshbin2=${zshbin1}"
|
||||||
eval "zshman=${mandir}"
|
eval "zshman=${mandir}"
|
||||||
eval "zshinfo=${infodir}"
|
eval "zshinfo=${infodir}"
|
||||||
|
eval "zshfndir=${fndir}"
|
||||||
|
|
||||||
echo "
|
echo "
|
||||||
zsh configuration
|
zsh configuration
|
||||||
|
@ -1350,5 +1392,9 @@ echo "\
|
||||||
library flags : ${LIBS}
|
library flags : ${LIBS}
|
||||||
binary install path : ${zshbin2}
|
binary install path : ${zshbin2}
|
||||||
man page install path : ${zshman}
|
man page install path : ${zshman}
|
||||||
info install path : ${zshinfo}
|
info install path : ${zshinfo}"
|
||||||
|
if test "$zshfndir" != no; then
|
||||||
|
echo "functions install path : ${zshfndir}
|
||||||
|
installed functions : ${FUNCTIONS_INSTALL}
|
||||||
"
|
"
|
||||||
|
fi
|
||||||
|
|
Loading…
Reference in a new issue