mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-11 13:01:28 +02:00
Massive improvement of --max-procs handling; reorganize option parsing to
do only what's necessary for each early-bailout test; bump version number.
This commit is contained in:
parent
58ff8e64c6
commit
62878a462d
1 changed files with 68 additions and 44 deletions
|
@ -40,13 +40,17 @@
|
||||||
# With the --max-procs option, zargs may not correctly capture the exit
|
# With the --max-procs option, zargs may not correctly capture the exit
|
||||||
# status of the backgrounded jobs, because of limitations of the "wait"
|
# status of the backgrounded jobs, because of limitations of the "wait"
|
||||||
# builtin. If the zsh/parameter module is not available, the status is
|
# builtin. If the zsh/parameter module is not available, the status is
|
||||||
# NEVER correctly returned.
|
# NEVER correctly returned, otherwise the status of the longest-running
|
||||||
|
# job in each batch is captured.
|
||||||
|
#
|
||||||
|
# Also because of "wait" limitations, --max-procs spawns max-procs jobs,
|
||||||
|
# then waits for all of those, then spawns another batch, etc.
|
||||||
#
|
#
|
||||||
|
|
||||||
emulate -L zsh || return 1
|
emulate -L zsh || return 1
|
||||||
local -a opts eof n s l P i
|
local -a opts eof n s l P i
|
||||||
|
|
||||||
local ZARGS_VERSION="1.0"
|
local ZARGS_VERSION="1.3"
|
||||||
|
|
||||||
if zparseopts -a opts -D -- \
|
if zparseopts -a opts -D -- \
|
||||||
-eof::=eof e::=eof \
|
-eof::=eof e::=eof \
|
||||||
|
@ -153,31 +157,16 @@ else command=( print -r -- )
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local wait bg
|
local wait bg
|
||||||
if (( P != 1 ))
|
local execute='
|
||||||
then
|
|
||||||
setopt nonotify nomonitor
|
|
||||||
bg='&'
|
|
||||||
fi
|
|
||||||
if (( P > 1 ))
|
|
||||||
then
|
|
||||||
if zmodload -i zsh/parameter 2>/dev/null
|
|
||||||
then
|
|
||||||
integer j=$#jobtexts
|
|
||||||
wait='(( $#jobtexts - j < P )) || wait %${(k)^jobtexts} 2>/dev/null;'
|
|
||||||
else
|
|
||||||
wait='{ (( P )) && (( P-- )) } || wait;'
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
local last='return $ret' execute='
|
|
||||||
if (( $opts[(I)-(-interactive|p)] ))
|
if (( $opts[(I)-(-interactive|p)] ))
|
||||||
then read -q "?$call?..." || eval "$last"
|
then read -q "?$call?..." || continue
|
||||||
elif (( $opts[(I)-(-verbose|t)] ))
|
elif (( $opts[(I)-(-verbose|t)] ))
|
||||||
then print -u2 -r -- "$call"
|
then print -u2 -r -- "$call"
|
||||||
fi
|
fi
|
||||||
eval "{
|
eval "{
|
||||||
\$call
|
\$call
|
||||||
} $bg $wait"
|
} $bg"'
|
||||||
|
local ret=0 analyze='
|
||||||
case $? in
|
case $? in
|
||||||
(0) ;;
|
(0) ;;
|
||||||
(<1-125>|128) ret=123;;
|
(<1-125>|128) ret=123;;
|
||||||
|
@ -186,21 +175,21 @@ local last='return $ret' execute='
|
||||||
(126) return 126;;
|
(126) return 126;;
|
||||||
(127) return 127;;
|
(127) return 127;;
|
||||||
(*) return 1;;
|
(*) return 1;;
|
||||||
esac
|
esac'
|
||||||
eval "$last"'
|
|
||||||
|
|
||||||
if (( ARGC == 0 ))
|
if (( ARGC == 0 ))
|
||||||
then
|
then
|
||||||
if (( $opts[(I)-(-no-run-if-empty|r)] ))
|
if (( $opts[(I)-(-no-run-if-empty|r)] ))
|
||||||
then return 0
|
then return 0
|
||||||
else call=($command); eval "$execute"
|
else
|
||||||
|
call=($command)
|
||||||
|
# Use "repeat" here so "continue" won't complain.
|
||||||
|
repeat 1 eval "$execute ; $analyze"
|
||||||
|
return $ret
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
n=${${n##-(n|-max-args(=|))}:-$[ARGC+c]}
|
n=${${n##-(n|-max-args(=|))}:-$[ARGC+c]}
|
||||||
s=${${s##-(s|-max-chars(=|))}:-20480}
|
|
||||||
l=${${l##-(l|-max-lines(=|))}:-${${l[1]:+1}:-$ARGC}}
|
|
||||||
P=${${P##-(P|-max-procs(=|))}:-1}
|
|
||||||
|
|
||||||
if (( n > c ))
|
if (( n > c ))
|
||||||
then (( n -= c ))
|
then (( n -= c ))
|
||||||
|
@ -209,12 +198,41 @@ else
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
last='shift $((end > ARGC ? ARGC : end)); continue'
|
P=${${P##-(P|-max-procs(=|))}:-1}
|
||||||
|
|
||||||
|
if (( P != 1 && ARGC > 1 ))
|
||||||
|
then
|
||||||
|
# These setopts are necessary for "wait" on multiple jobs to work.
|
||||||
|
setopt nonotify nomonitor
|
||||||
|
bg='&'
|
||||||
|
if zmodload -i zsh/parameter 2>/dev/null
|
||||||
|
then
|
||||||
|
wait='wait %${(k)^jobstates[(R)running:*]}'
|
||||||
|
else
|
||||||
|
wait='wait'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
s=${${s##-(s|-max-chars(=|))}:-20480}
|
||||||
|
l=${${l##-(l|-max-lines(=|))}:-${${l[1]:+1}:-$ARGC}}
|
||||||
|
|
||||||
|
# Everything has to be in a subshell just in case of backgrounding jobs,
|
||||||
|
# so that we don't unintentionally "wait" for jobs of the parent shell.
|
||||||
|
(
|
||||||
|
|
||||||
while ((ARGC))
|
while ((ARGC))
|
||||||
do
|
do
|
||||||
|
if (( P == 0 || P > ARGC ))
|
||||||
|
then (( P = ARGC ))
|
||||||
|
fi
|
||||||
|
|
||||||
|
repeat $P
|
||||||
|
do
|
||||||
|
((ARGC)) || break
|
||||||
for (( end=l; end && ${(c)#argv[1,end]} > s; end/=2 )) :
|
for (( end=l; end && ${(c)#argv[1,end]} > s; end/=2 )) :
|
||||||
(( end > n && ( end = n ) ))
|
(( end > n && ( end = n ) ))
|
||||||
args=( $argv[1,end] )
|
args=( $argv[1,end] )
|
||||||
|
shift $((end > ARGC ? ARGC : end))
|
||||||
if (( $#i ))
|
if (( $#i ))
|
||||||
then call=( ${command/$i/$args} )
|
then call=( ${command/$i/$args} )
|
||||||
else call=( $command $args )
|
else call=( $command $args )
|
||||||
|
@ -225,11 +243,17 @@ do
|
||||||
# GNU xargs exits here whether or not -x,
|
# GNU xargs exits here whether or not -x,
|
||||||
# but that just makes the option useless.
|
# but that just makes the option useless.
|
||||||
(( $opts[(I)-(-exit|x)] )) && return 1
|
(( $opts[(I)-(-exit|x)] )) && return 1
|
||||||
eval "$last"
|
continue
|
||||||
else
|
else
|
||||||
eval "$execute"
|
eval "$execute"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
eval "$wait
|
||||||
|
$analyze"
|
||||||
|
done
|
||||||
return $ret
|
return $ret
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
# }
|
# }
|
||||||
|
|
Loading…
Reference in a new issue