mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-07-15 06:01:26 +02:00
32768 with further modifications: LOCAL_LOOPS option.
This commit is contained in:
parent
d6698d89a6
commit
b5198b10a1
7 changed files with 90 additions and 8 deletions
|
@ -1,5 +1,10 @@
|
|||
2014-06-13 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* 32768, with further modifications: Doc/Zsh/options.yo,
|
||||
Src/exec.c, Src/options.c, Src/zsh.h, Test/E01options.ztst,
|
||||
Test/ztst.zsh: LOCAL_LOOPS option to restrict effect of
|
||||
continue and break in function scope.
|
||||
|
||||
* 32666: Doc/Zsh/compat.yo: shell emulation based on executable
|
||||
name incompletely documented.
|
||||
|
||||
|
@ -18,6 +23,7 @@
|
|||
|
||||
* Jun T: 32755: Doc/Zsh/grammar.yo: move line that was in the
|
||||
wrong place.
|
||||
|
||||
2014-06-07 Barton E. Schaefer <schaefer@zsh.org>
|
||||
|
||||
* Nikolas Garofil: 32737: Src/utils.c: properly ifdef declarations
|
||||
|
|
|
@ -1631,6 +1631,21 @@ tt(FUNCTION_ARGZERO) from on to off (or off to on) does not change the
|
|||
current value of tt($0). Only the state upon entry to the function or
|
||||
script has an effect. Compare tt(POSIX_ARGZERO).
|
||||
)
|
||||
pindex(LOCAL_LOOPS)
|
||||
pindex(NO_LOCAL_LOOPS)
|
||||
pindex(LOCALLOOPS)
|
||||
pindex(NOLOCALLOOPS)
|
||||
cindex(break, inside function)
|
||||
cindex(continue, inside function)
|
||||
cinde(function, scope of break and continue)
|
||||
item(tt(LOCAL_LOOPS))(
|
||||
When this option is not set, the effect of tt(break) and tt(continue)
|
||||
commands may propagate outside function scope, affecting loops in
|
||||
calling functions. When the option is set in a calling function, a
|
||||
tt(break) or a tt(continue) that is not caught within a called function
|
||||
(regardless of the setting of the option within that function)
|
||||
produces a warning and the effect is cancelled.
|
||||
)
|
||||
pindex(LOCAL_OPTIONS)
|
||||
pindex(NO_LOCAL_OPTIONS)
|
||||
pindex(LOCALOPTIONS)
|
||||
|
@ -1639,10 +1654,10 @@ item(tt(LOCAL_OPTIONS) <K>)(
|
|||
If this option is set at the point of return from a shell function,
|
||||
most options (including this one) which were in force upon entry to
|
||||
the function are restored; options that are not restored are
|
||||
tt(PRIVILEGED) and tt(RESTRICTED). Otherwise, only this option and the
|
||||
tt(XTRACE) and tt(PRINT_EXIT_VALUE) options are restored. Hence
|
||||
if this is explicitly unset by a shell function the other options in
|
||||
force at the point of return will remain so.
|
||||
tt(PRIVILEGED) and tt(RESTRICTED). Otherwise, only this option,
|
||||
and the tt(LOCAL_LOOPS), tt(XTRACE) and tt(PRINT_EXIT_VALUE) options are
|
||||
restored. Hence if this is explicitly unset by a shell function the
|
||||
other options in force at the point of return will remain so.
|
||||
A shell function can also guarantee itself a known shell configuration
|
||||
with a formulation like `tt(emulate -L zsh)'; the tt(-L) activates
|
||||
tt(LOCAL_OPTIONS).
|
||||
|
|
17
Src/exec.c
17
Src/exec.c
|
@ -4614,7 +4614,7 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
|
|||
char *name = shfunc->node.nam;
|
||||
int flags = shfunc->node.flags, ooflags;
|
||||
char *fname = dupstring(name);
|
||||
int obreaks, saveemulation, restore_sticky;
|
||||
int obreaks, ocontflag, oloops, saveemulation, restore_sticky;
|
||||
Eprog prog;
|
||||
struct funcstack fstack;
|
||||
static int oflags;
|
||||
|
@ -4626,7 +4626,9 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
|
|||
pushheap();
|
||||
|
||||
oargv0 = NULL;
|
||||
obreaks = breaks;;
|
||||
obreaks = breaks;
|
||||
ocontflag = contflag;
|
||||
oloops = loops;
|
||||
if (trap_state == TRAP_STATE_PRIMED)
|
||||
trap_return--;
|
||||
oldlastval = lastval;
|
||||
|
@ -4814,6 +4816,17 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
|
|||
opts[XTRACE] = saveopts[XTRACE];
|
||||
opts[PRINTEXITVALUE] = saveopts[PRINTEXITVALUE];
|
||||
opts[LOCALOPTIONS] = saveopts[LOCALOPTIONS];
|
||||
opts[LOCALLOOPS] = saveopts[LOCALLOOPS];
|
||||
}
|
||||
|
||||
if (opts[LOCALLOOPS]) {
|
||||
if (contflag)
|
||||
zwarn("`continue' active at end of function scope");
|
||||
if (breaks)
|
||||
zwarn("`break' active at end of function scope");
|
||||
breaks = obreaks;
|
||||
contflag = ocontflag;
|
||||
loops = oloops;
|
||||
}
|
||||
|
||||
endtrapscope();
|
||||
|
|
|
@ -180,6 +180,7 @@ static struct optname optns[] = {
|
|||
{{NULL, "listrowsfirst", 0}, LISTROWSFIRST},
|
||||
{{NULL, "listtypes", OPT_ALL}, LISTTYPES},
|
||||
{{NULL, "localoptions", OPT_EMULATE|OPT_KSH}, LOCALOPTIONS},
|
||||
{{NULL, "localloops", OPT_EMULATE}, LOCALLOOPS},
|
||||
{{NULL, "localpatterns", OPT_EMULATE}, LOCALPATTERNS},
|
||||
{{NULL, "localtraps", OPT_EMULATE|OPT_KSH}, LOCALTRAPS},
|
||||
{{NULL, "login", OPT_SPECIAL}, LOGINSHELL},
|
||||
|
|
|
@ -2129,6 +2129,7 @@ enum {
|
|||
LISTPACKED,
|
||||
LISTROWSFIRST,
|
||||
LISTTYPES,
|
||||
LOCALLOOPS,
|
||||
LOCALOPTIONS,
|
||||
LOCALPATTERNS,
|
||||
LOCALTRAPS,
|
||||
|
|
|
@ -430,7 +430,7 @@
|
|||
foo
|
||||
unfunction foo
|
||||
0:FUNCTION_ARGZERO option
|
||||
>My name is ZTST_execchunk
|
||||
>My name is (anon)
|
||||
>My name is foo
|
||||
|
||||
setopt _NO_glob_
|
||||
|
@ -1114,3 +1114,45 @@
|
|||
>1
|
||||
>1
|
||||
>2
|
||||
|
||||
for (( i = 0; i < 10; i++ )); do
|
||||
() {
|
||||
print $i
|
||||
break
|
||||
}
|
||||
done
|
||||
0:NO_LOCAL_LOOPS
|
||||
>0
|
||||
|
||||
() {
|
||||
emulate -L zsh
|
||||
setopt localloops
|
||||
for (( i = 0; i < 10; i++ )); do
|
||||
() {
|
||||
setopt nolocalloops # ignored in parent
|
||||
print $i
|
||||
break
|
||||
}
|
||||
done
|
||||
}
|
||||
0:LOCAL_LOOPS
|
||||
>0
|
||||
>1
|
||||
>2
|
||||
>3
|
||||
>4
|
||||
>5
|
||||
>6
|
||||
>7
|
||||
>8
|
||||
>9
|
||||
?(anon):4: `break' active at end of function scope
|
||||
?(anon):4: `break' active at end of function scope
|
||||
?(anon):4: `break' active at end of function scope
|
||||
?(anon):4: `break' active at end of function scope
|
||||
?(anon):4: `break' active at end of function scope
|
||||
?(anon):4: `break' active at end of function scope
|
||||
?(anon):4: `break' active at end of function scope
|
||||
?(anon):4: `break' active at end of function scope
|
||||
?(anon):4: `break' active at end of function scope
|
||||
?(anon):4: `break' active at end of function scope
|
||||
|
|
|
@ -260,8 +260,12 @@ $ZTST_redir"
|
|||
# Execute an indented chunk. Redirections will already have
|
||||
# been set up, but we need to handle the options.
|
||||
ZTST_execchunk() {
|
||||
setopt localloops # don't let continue & break propagate out
|
||||
options=($ZTST_testopts)
|
||||
eval "$ZTST_code"
|
||||
() {
|
||||
unsetopt localloops
|
||||
eval "$ZTST_code"
|
||||
}
|
||||
ZTST_status=$?
|
||||
# careful... ksh_arrays may be in effect.
|
||||
ZTST_testopts=(${(kv)options[*]})
|
||||
|
|
Loading…
Reference in a new issue