1
0
Fork 0
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:
Peter Stephenson 2014-06-13 21:39:44 +01:00
parent d6698d89a6
commit b5198b10a1
7 changed files with 90 additions and 8 deletions

View file

@ -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

View file

@ -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).

View file

@ -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();

View file

@ -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},

View file

@ -2129,6 +2129,7 @@ enum {
LISTPACKED,
LISTROWSFIRST,
LISTTYPES,
LOCALLOOPS,
LOCALOPTIONS,
LOCALPATTERNS,
LOCALTRAPS,

View file

@ -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

View file

@ -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[*]})