summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog57
-rw-r--r--Config/version.mk4
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_git13
-rw-r--r--Src/Zle/comp.h4
-rw-r--r--Src/Zle/complete.c12
-rw-r--r--Src/exec.c11
-rw-r--r--Src/loop.c6
-rw-r--r--Src/params.c26
-rw-r--r--Src/subst.c2
-rw-r--r--Src/zsh.h1
-rw-r--r--Test/B02typeset.ztst10
-rw-r--r--Test/C02cond.ztst4
-rw-r--r--Test/C03traps.ztst98
-rw-r--r--Test/D04parameter.ztst13
-rwxr-xr-xTest/ztst.zsh18
15 files changed, 254 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 39ef878c7..f2f5cd052 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,58 @@
+2016-12-06 Peter Stephenson <p.w.stephenson@ntlworld.com>
+
+ * unposted: Config/version.mk: 5.2-test-2.
+
+2016-12-05 Peter Stephenson <p.stephenson@samsung.com>
+
+ * 40102: Test/ztst.zsh, Test/C02cond.ztst: create test IO
+ files in newly created temporary directory.
+
+ * 40100: Test/C03traps.ztst: Check ERR_EXIT and ERR_RETURN on
+ anonymous functions: should exit on function return even if
+ suppressed internally.
+
+ * 40097: Src/exec.c, Test/C03traps.ztst: Don't trigger ERR_EXIT
+ or ERR_RETURN on non-zero status after current shell group, either.
+
+ * 40096: Src/exec.c, Src/loop.c, Src/zsh.h, Test/C03traps.ztst:
+ Don't trigger ERR_EXIT or ERR_RETURN on non-zero status after
+ shell construct.
+
+2016-12-04 Daniel Shahaf <d.s@daniel.shahaf.name>
+
+ * unposted: Functions/VCS_Info/Backends/VCS_INFO_get_data_git:
+ vcs_info git: Handle rebase-apply sequences with >=10000 patches.
+
+ * 40074: Functions/VCS_Info/Backends/VCS_INFO_get_data_git:
+ vcs_info git: rfc822-unfold rebase-apply patch subjects when
+ msg-clean is unavailable.
+
+2016-12-04 Peter Stephenson <p.w.stephenson@ntlworld.com>
+
+ * 40088: Test/D04parameter.ztst: attempt to make output from
+ interactive test more robust.
+
+2016-12-03 Barton E. Schaefer <schaefer@zsh.org>
+
+ * unposted: Test/D04parameter.ztst: regression test for 40071
+
+ * 40071: Src/subst.c: change Dash back to "-" before evaluating
+ named directory expansions
+
+2016-12-03 Daniel Shahaf <d.s@daniel.shahaf.name>
+
+ * 40068: Src/params.c, Test/B02typeset.ztst: Abort execution
+ when setuid/setgid fail.
+
+ * 40067: Src/Zle/comp.h, Src/Zle/complete.c, Src/params.c:
+ internal: Document 'cmatcher', parse_cmatcher(), 'comptoend',
+ unsetparam_pm(), and getindex().
+
+2016-12-03 Daniel Hahler <zsh@thequod.de>
+
+ * 40029: Functions/VCS_Info/Backends/VCS_INFO_get_data_git:
+ Get subject of current patch in rebase-apply mode
+
2016-12-02 Peter Stephenson <p.w.stephenson@ntlworld.com>
* unposted: Config/version.mk: 5.2-test-1.
@@ -40,7 +95,7 @@
* 40036: Completion/Debian/Command/_bts: Complete removal
syntaxes correctly.
-2016-11-29 Barton E. Schaefer <schaefer@brasslantern.com>
+2016-11-29 Barton E. Schaefer <schaefer@zsh.org>
* 40034: Src/subst.c: clear badcshglob when ignoring errors
diff --git a/Config/version.mk b/Config/version.mk
index b63ad0cf0..ca3da65ca 100644
--- a/Config/version.mk
+++ b/Config/version.mk
@@ -27,5 +27,5 @@
# This must also serve as a shell script, so do not add spaces around the
# `=' signs.
-VERSION=5.2-test-1
-VERSION_DATE='December 2, 2016'
+VERSION=5.2-test-2
+VERSION_DATE='December 6, 2016'
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
index 18ba89a9a..65d8cb182 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
@@ -232,10 +232,19 @@ elif [[ -d "${gitdir}/rebase-apply" ]]; then
local cur=$(< $next)
local p subject
for ((p = 1; p < cur; p++)); do
- git_patches_applied+=("$(printf "%04d" $p) ?")
+ printf -v "git_patches_applied[$p]" "%04d ?" "$p"
done
if [[ -f "${patchdir}/msg-clean" ]]; then
subject="${$(< "${patchdir}/msg-clean")[(f)1]}"
+ elif local this_patch_file
+ printf -v this_patch_file "%s/%04d" "${patchdir}" "${cur}"
+ [[ -f $this_patch_file ]]
+ then
+ () {
+ local REPLY
+ VCS_INFO_patch2subject "${this_patch_file}"
+ subject=$REPLY
+ }
fi
if [[ -f "${patchdir}/original-commit" ]]; then
if [[ -n $subject ]]; then
@@ -261,6 +270,7 @@ elif [[ -f "${gitdir}/MERGE_HEAD" ]]; then
# This is 'git merge --no-commit'
local -a heads=( ${(@f)"$(<"${gitdir}/MERGE_HEAD")"} )
local subject;
+ # TODO: maybe read up to the first blank line
IFS='' read -r subject < "${gitdir}/MERGE_MSG"
# $subject is the subject line of the would-be commit
# Maybe we can get the subject lines of MERGE_HEAD's commits cheaply?
@@ -286,6 +296,7 @@ elif [[ -f "${gitdir}/CHERRY_PICK_HEAD" ]]; then
# ### be "1". The %u/%c tuple will assume the values [(1,2), (1,1), (1,0)],
# ### whereas the correct sequence would be [(1,2), (2,1), (3,0)].
local subject
+ # TODO: maybe read up to the first blank line
IFS='' read -r subject < "${gitdir}/MERGE_MSG"
git_patches_applied=( "$(<${gitdir}/CHERRY_PICK_HEAD) ${subject}" )
if [[ -f "${gitdir}/sequencer/todo" ]]; then
diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h
index 3711fde29..3e9834560 100644
--- a/Src/Zle/comp.h
+++ b/Src/Zle/comp.h
@@ -153,7 +153,9 @@ struct cmatcher {
Cpattern line; /* what matches on the line */
int llen; /* length of line pattern */
Cpattern word; /* what matches in the word */
- int wlen; /* length of word pattern */
+ int wlen; /* length of word pattern, or:
+ -1: word pattern is one asterisk
+ -2: word pattern is two asterisks */
Cpattern left; /* left anchor */
int lalen; /* length of left anchor */
Cpattern right; /* right anchor */
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 7980518b7..48fcd4751 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -67,7 +67,7 @@ char *compiprefix,
*compexact,
*compexactstr,
*comppatinsert,
- *comptoend,
+ *comptoend, /* compstate[to_end]; populates 'movetoend' */
*compoldlist,
*compoldins,
*compvared;
@@ -227,7 +227,15 @@ cpcpattern(Cpattern o)
return r;
}
-/* Parse a string for matcher control, containing multiple matchers. */
+/*
+ * Parse a string for matcher control, containing multiple matchers.
+ *
+ * 's' is the string to be parsed.
+ *
+ * 'name' is the name of the builtin from which this is called, for errors.
+ *
+ * Return 'pcm_err' on error; a NULL return value means ...
+ */
/**/
mod_export Cmatcher
diff --git a/Src/exec.c b/Src/exec.c
index f544a33e7..a439aec7f 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -46,6 +46,11 @@ enum {
/**/
int noerrexit;
+/* used to suppress ERREXIT for one occurrence */
+
+/**/
+int this_noerrexit;
+
/*
* noerrs = 1: suppress error messages
* noerrs = 2: don't set errflag on parse error, either
@@ -424,6 +429,7 @@ execcursh(Estate state, int do_exec)
cmdpop();
state->pc = end;
+ this_noerrexit = 1;
return lastval;
}
@@ -1238,7 +1244,8 @@ execlist(Estate state, int dont_change_job, int exiting)
}
while (wc_code(code) == WC_LIST && !breaks && !retflag && !errflag) {
int donedebug;
- int this_noerrexit = 0, this_donetrap = 0;
+ int this_donetrap = 0;
+ this_noerrexit = 0;
ltype = WC_LIST_TYPE(code);
csp = cmdsp;
@@ -5813,6 +5820,7 @@ execsave(void)
es->trapisfunc = trapisfunc;
es->traplocallevel = traplocallevel;
es->noerrs = noerrs;
+ es->this_noerrexit = this_noerrexit;
es->underscore = ztrdup(zunderscore);
es->next = exstack;
exstack = es;
@@ -5847,6 +5855,7 @@ execrestore(void)
trapisfunc = en->trapisfunc;
traplocallevel = en->traplocallevel;
noerrs = en->noerrs;
+ this_noerrexit = en->this_noerrexit;
setunderscore(en->underscore);
zsfree(en->underscore);
free(en);
diff --git a/Src/loop.c b/Src/loop.c
index 367c0df5c..ae87b2f5f 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -208,6 +208,7 @@ execfor(Estate state, int do_exec)
loops--;
simple_pline = old_simple_pline;
state->pc = end;
+ this_noerrexit = 1;
return lastval;
}
@@ -335,6 +336,7 @@ execselect(Estate state, UNUSED(int do_exec))
loops--;
simple_pline = old_simple_pline;
state->pc = end;
+ this_noerrexit = 1;
return lastval;
}
@@ -472,6 +474,7 @@ execwhile(Estate state, UNUSED(int do_exec))
popheap();
loops--;
state->pc = end;
+ this_noerrexit = 1;
return lastval;
}
@@ -523,6 +526,7 @@ execrepeat(Estate state, UNUSED(int do_exec))
loops--;
simple_pline = old_simple_pline;
state->pc = end;
+ this_noerrexit = 1;
return lastval;
}
@@ -573,6 +577,7 @@ execif(Estate state, int do_exec)
lastval = 0;
}
state->pc = end;
+ this_noerrexit = 1;
return lastval;
}
@@ -682,6 +687,7 @@ execcase(Estate state, int do_exec)
if (!anypatok)
lastval = 0;
+ this_noerrexit = 1;
return lastval;
}
diff --git a/Src/params.c b/Src/params.c
index aa8b196bd..c64d7486b 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -1761,6 +1761,18 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
return r;
}
+/*
+ * Parse a subscript.
+ *
+ * pptr: In/Out parameter. On entry, *ptr points to a "[foo]" string. On exit
+ * it will point one past the closing bracket.
+ *
+ * v: In/Out parameter. Its .start and .end members (at least) will be updated
+ * with the parsed indices.
+ *
+ * flags: can be either SCANPM_DQUOTED or zero. Other bits are not used.
+ */
+
/**/
int
getindex(char **pptr, Value v, int flags)
@@ -3245,7 +3257,11 @@ unsetparam(char *s)
unqueue_signals();
}
-/* Unset a parameter */
+/* Unset a parameter
+ *
+ * altflag: if true, don't remove pm->ename from the environment
+ * exp: See stdunsetfn()
+ */
/**/
mod_export int
@@ -4061,7 +4077,7 @@ uidsetfn(UNUSED(Param pm), zlong x)
{
#ifdef HAVE_SETUID
if (setuid((uid_t)x))
- zwarn("failed to change user ID: %e", errno);
+ zerr("failed to change user ID: %e", errno);
#endif
}
@@ -4082,7 +4098,7 @@ euidsetfn(UNUSED(Param pm), zlong x)
{
#ifdef HAVE_SETEUID
if (seteuid((uid_t)x))
- zwarn("failed to change effective user ID: %e", errno);
+ zerr("failed to change effective user ID: %e", errno);
#endif
}
@@ -4103,7 +4119,7 @@ gidsetfn(UNUSED(Param pm), zlong x)
{
#ifdef HAVE_SETUID
if (setgid((gid_t)x))
- zwarn("failed to change group ID: %e", errno);
+ zerr("failed to change group ID: %e", errno);
#endif
}
@@ -4124,7 +4140,7 @@ egidsetfn(UNUSED(Param pm), zlong x)
{
#ifdef HAVE_SETEUID
if (setegid((gid_t)x))
- zwarn("failed to change effective group ID: %e", errno);
+ zerr("failed to change effective group ID: %e", errno);
#endif
}
diff --git a/Src/subst.c b/Src/subst.c
index 06d2c9ea9..64b440027 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -650,6 +650,8 @@ filesubstr(char **namptr, int assign)
char *ptr, *tmp, *res, *ptr2;
int val;
+ if (str[1] == Dash)
+ str[1] = '-';
val = zstrtol(str + 1, &ptr, 10);
if (isend(str[1])) { /* ~ */
*namptr = dyncat(home ? home : "", str + 1);
diff --git a/Src/zsh.h b/Src/zsh.h
index dae2b2459..f2c030004 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1070,6 +1070,7 @@ struct execstack {
int trapisfunc;
int traplocallevel;
int noerrs;
+ int this_noerrexit;
char *underscore;
};
diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst
index 6d85a63fe..9c56c7e5e 100644
--- a/Test/B02typeset.ztst
+++ b/Test/B02typeset.ztst
@@ -711,3 +711,13 @@
typeset isreadonly=still
1:typeset returns status 1 if setting readonly variable
?(eval):2: read-only variable: isreadonly
+
+ if (( UID )); then
+ UID=$((UID+1)) date; echo "Status is printed, $?"
+ else
+ ZTST_skip="cannot test setuid error when tests run as superuser"
+ fi
+0:when cannot change UID, the command isn't run
+# 'date' did not run.
+>Status is printed, 1
+?(eval):2: failed to change user ID: operation not permitted
diff --git a/Test/C02cond.ztst b/Test/C02cond.ztst
index 40e4dfb0b..27a22593d 100644
--- a/Test/C02cond.ztst
+++ b/Test/C02cond.ztst
@@ -11,9 +11,9 @@
typeset -gi isnfs
[[ "$(find . -prune -fstype nfs 2>/dev/null)" == "." ]] && isnfs=1
if (( isnfs )) &&
- (cd -q ${TMPPREFIX:h} >/dev/null 2>&1 &&
+ (cd -q ${ZTST_tmp} >/dev/null 2>&1 &&
[[ "$(find . -prune -fstype nfs 2>/dev/null)" != "." ]]); then
- filetmpprefix=${TMPPREFIX}-$$-
+ filetmpprefix=${ZTST_tmp}/condtest-$$-
isnfs=0
else
filetmpprefix=
diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst
index c3bedb06c..7bc0b486d 100644
--- a/Test/C03traps.ztst
+++ b/Test/C03traps.ztst
@@ -626,6 +626,104 @@ F:Must be tested with a top-level script rather than source or function
>before-out
>before-in
+ (setopt err_exit
+ for x in y; do
+ false && true
+ done
+ print OK
+ )
+0:ERR_EXIT not triggered by status 1 at end of for
+>OK
+
+ (setopt err_exit
+ integer x=0
+ while (( ! x++ )); do
+ false && true
+ done
+ print OK
+ )
+0:ERR_EXIT not triggered by status 1 at end of while
+>OK
+
+ (setopt err_exit
+ repeat 1; do
+ false && true
+ done
+ print OK
+ )
+0:ERR_EXIT not triggered by status 1 at end of repeat
+>OK
+
+ (setopt err_exit
+ if true; then
+ false && true
+ fi
+ print OK
+ )
+0:ERR_EXIT not triggered by status 1 at end of if
+>OK
+
+ (setopt err_exit
+ {
+ false && true
+ }
+ print OK
+ )
+0:ERR_EXIT not triggered by status 1 at end of { }
+>OK
+
+ (setopt err_exit
+ for x in y; do
+ false
+ done
+ print OK
+ )
+1:ERR_EXIT triggered by status 1 within for
+
+ (setopt err_exit
+ integer x=0
+ while (( ! x++ )); do
+ false
+ done
+ print OK
+ )
+1:ERR_EXIT triggered by status 1 within while
+
+ (setopt err_exit
+ repeat 1; do
+ false
+ done
+ print OK
+ )
+1:ERR_EXIT triggered by status 1 within repeat
+
+ (setopt err_exit
+ if true; then
+ false
+ fi
+ print OK
+ )
+1:ERR_EXIT triggered by status 1 within if
+
+ (setopt err_exit
+ {
+ false
+ }
+ print OK
+ )
+1:ERR_EXIT triggered by status 1 within { }
+
+ (setopt err_exit
+ () {
+ false && true
+ print Still functioning
+ false && true
+ }
+ print OK
+ )
+1:ERR_EXIT triggered by status 1 at end of anon func
+>Still functioning
+
if zmodload zsh/system 2>/dev/null; then
(
trap 'echo TERM; exit 2' TERM
diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst
index 4cbd2fa0f..9128c3c38 100644
--- a/Test/D04parameter.ztst
+++ b/Test/D04parameter.ztst
@@ -97,16 +97,17 @@
PROMPT="" $ZTST_testdir/../Src/zsh -fis <<<'
unsetopt PROMPT_SP
- PS2="" PS3="" PS4="" RPS1="" RPS2=""
+ PS1="" PS2="" PS3="" PS4="" RPS1="" RPS2=""
+ exec 2>&1
foo() {
print ${1:?no arguments given}
print not reached
}
foo
print reached
- '
+ ' 2>/dev/null
0:interactive shell returns to top level on ${...?...} error
-?foo:1: 1: no arguments given
+*>*foo:1: 1: no arguments given
>reached
print ${set1:+word1} ${set1+word2} ${null1:+word3} ${null1+word4}
@@ -852,6 +853,7 @@
foo='b* e*'
print ${(e)~foo}
print ${(e)~=foo}
+ setopt nomatch
0:Rule 10: Re-Evaluation
>b* e*
>boringfile evenmoreboringfile
@@ -2049,3 +2051,8 @@
0:Out-of-range multiple array subscripts with quoting, with and without (@)
>1
>0
+
+ a='~-/'; echo $~a
+0:Regression: "-" became Dash in workers/37689, breaking ~- expansion
+*>*
+F:We do not care what $OLDPWD is, as long as it doesn't cause an error
diff --git a/Test/ztst.zsh b/Test/ztst.zsh
index 8ae06b832..f172ae143 100755
--- a/Test/ztst.zsh
+++ b/Test/ztst.zsh
@@ -104,19 +104,23 @@ fpath=( $ZTST_srcdir/../Functions/*~*/CVS(/)
$ZTST_srcdir/../Completion/*/*~*/CVS(/) )
: ${TMPPREFIX:=/tmp/zsh}
+ZTST_tmp=${TMPPREFIX}.ztst.$$
+if ! rm -f $ZTST_tmp || ! mkdir -p $ZTST_tmp || ! chmod go-w $ZTST_tmp; then
+ print "Can't create $ZTST_tmp for exclusive use." >&2
+ exit 1
+fi
# Temporary files for redirection inside tests.
-ZTST_in=${TMPPREFIX}.ztst.in.$$
+ZTST_in=${ZTST_tmp}/ztst.in
# hold the expected output
-ZTST_out=${TMPPREFIX}.ztst.out.$$
-ZTST_err=${TMPPREFIX}.ztst.err.$$
+ZTST_out=${ZTST_tmp}/ztst.out
+ZTST_err=${ZTST_tmp}/ztst.err
# hold the actual output from the test
-ZTST_tout=${TMPPREFIX}.ztst.tout.$$
-ZTST_terr=${TMPPREFIX}.ztst.terr.$$
+ZTST_tout=${ZTST_tmp}/ztst.tout
+ZTST_terr=${ZTST_tmp}/ztst.terr
ZTST_cleanup() {
cd $ZTST_testdir
- rm -rf $ZTST_testdir/dummy.tmp $ZTST_testdir/*.tmp(N) \
- ${TMPPREFIX}.ztst*$$(N)
+ rm -rf $ZTST_testdir/dummy.tmp $ZTST_testdir/*.tmp(N) ${ZTST_tmp}
}
# This cleanup always gets performed, even if we abort. Later,