mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-12-07 06:02:21 +01:00
26546, 26556: sticky emulation for functions defined in emulate ... -c ...
environments, plus documentation
This commit is contained in:
parent
0d02cf343e
commit
c7d8b0dfb8
16 changed files with 322 additions and 69 deletions
12
ChangeLog
12
ChangeLog
|
|
@ -1,3 +1,13 @@
|
|||
2009-02-11 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* 26556: Doc/Zsh/builtins.yo: documentation for 26546.
|
||||
|
||||
* 26546: Src/builtin.c, Src/exec.c, Src/hashtable.c, Src/init.c,
|
||||
Src/mkbltnmlst.sh, Src/options.c, Src/params.c, Src/parse.c,
|
||||
Src/signals.c, Src/subst.c, Src/zsh.h, Src/Modules/newuser.c,
|
||||
Src/Modules/parameter.c, Test/B07emulate.ztst: sticky emulation
|
||||
for functions defined within emualate ... -c ... environments.
|
||||
|
||||
2009-02-11 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* unposted: Functions/Calendar/age: accidentally committed a
|
||||
|
|
@ -11157,5 +11167,5 @@
|
|||
|
||||
*****************************************************
|
||||
* This is used by the shell to define $ZSH_PATCHLEVEL
|
||||
* $Revision: 1.4562 $
|
||||
* $Revision: 1.4563 $
|
||||
*****************************************************
|
||||
|
|
|
|||
|
|
@ -356,10 +356,6 @@ noderef(Compatibility)
|
|||
)\
|
||||
.
|
||||
|
||||
If tt(-c) tt(arg) is given, evaluate tt(arg) after temporary setting
|
||||
requested emulation. Emulation and all options will be restored to their
|
||||
original values before tt(emulate) returns.
|
||||
|
||||
If the tt(-R) option is given, all options
|
||||
are reset to their default value corresponding to the specified emulation
|
||||
mode, except for certain options describing the interactive
|
||||
|
|
@ -370,6 +366,62 @@ well, causing the effects of the tt(emulate) command and any tt(setopt) and
|
|||
tt(trap) commands to be local to the immediately surrounding shell
|
||||
function, if any; normally these options are turned off in all emulation
|
||||
modes except tt(ksh). The tt(-L) and tt(-c) are mutually exclusive.
|
||||
|
||||
If tt(-c) tt(arg) is given, evaluate tt(arg) while the requested
|
||||
emulation is temporarily in effect. The emulation and all options will
|
||||
be restored to their original values before tt(emulate) returns. The
|
||||
tt(-R) flag may be used.
|
||||
|
||||
Use of tt(-c) enables `sticky' emulation mode for functions defined
|
||||
within the evaluated expression: the emulation mode is associated
|
||||
thereafter with the function so that whenever the function is executed
|
||||
the emulation (respecting the tt(-R) flag, if present) and all
|
||||
options are set before entry to the function, and restored after exit.
|
||||
If the function is called when the sticky emulation is already in
|
||||
effect, either within an `tt(emulate) var(shell) tt(-c)' expression or
|
||||
within another function with the same sticky emulation, entry and exit
|
||||
from the function do not cause options to be altered (except due to
|
||||
standard processing such as the tt(LOCAL_OPTIONS) option).
|
||||
|
||||
For example:
|
||||
|
||||
example(emulate sh -c 'fni+LPAR()RPAR() { setopt cshnullglob; }
|
||||
fno+LPAR()RPAR() { fni; }'
|
||||
fno
|
||||
)
|
||||
|
||||
The two functions tt(fni) and tt(fno) are defined with sticky tt(sh)
|
||||
emulation. tt(fno) is then executed, causing options associated
|
||||
with emulations to be set to their values in tt(sh). tt(fni) then
|
||||
calls tt(fno); because tt(fno) is also marked for sticky tt(sh)
|
||||
emulation, no option changes take place on entry to or exit from it.
|
||||
Hence the option tt(cshnullglob), turned off by tt(sh) emulation, will
|
||||
be turned on within tt(fni) and remain on on return to tt(fno). On exit
|
||||
from tt(fno), the emulation mode and all options will be restored to the
|
||||
state they were in before entry to the temporary emulation.
|
||||
|
||||
The documentation above is typically sufficient for the intended
|
||||
purpose of executing code designed for other shells in a suitable
|
||||
environment. More detailed rules follow.
|
||||
startsitem()
|
||||
sitem(1.)(The sticky emulation environment provided by `tt(emulate)
|
||||
var(shell) tt(-c)' is identical to that provided by entry to
|
||||
a function marked for sticky emulation as a consequence of being
|
||||
defined in such an environment. Hence, for example, the sticky
|
||||
emulation is inherited by subfunctions defined within functions
|
||||
with sticky emulation.)
|
||||
sitem(2.)(No change of options takes place on entry to or exit from
|
||||
functions that are not marked for sticky emulation, other than those
|
||||
that would normally take place, even if those functions are called
|
||||
within sticky emulation.)
|
||||
sitem(3.)(No special handling is provided for functions marked for
|
||||
tt(autoload) nor for functions present in wordcode created by
|
||||
the tt(zcompile) command.)
|
||||
sitem(4.)(The presence or absence of the tt(-R) flag to tt(emulate)
|
||||
corresponds to different sticky emulation modes, so for example
|
||||
`tt(emulate sh -c)', `tt(emulate -R sh -c)' and `tt(emulate csh -c)'
|
||||
are treated as three distinct sticky emulations.)
|
||||
endsitem()
|
||||
)
|
||||
findex(enable)
|
||||
cindex(enabling commands)
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ boot_(UNUSED(Module m))
|
|||
0 };
|
||||
const char **sp;
|
||||
|
||||
if (emulation != EMULATE_ZSH)
|
||||
if (!EMULATION(EMULATE_ZSH))
|
||||
return 0;
|
||||
|
||||
if (!dotdir) {
|
||||
|
|
|
|||
|
|
@ -289,6 +289,7 @@ setfunction(char *name, char *val, int dis)
|
|||
shf = (Shfunc) zshcalloc(sizeof(*shf));
|
||||
shf->funcdef = dupeprog(prog, 0);
|
||||
shf->node.flags = dis;
|
||||
shf->emulation = sticky_emulation;
|
||||
|
||||
if (!strncmp(name, "TRAP", 4) &&
|
||||
(sn = getsignum(name + 4)) != -1) {
|
||||
|
|
|
|||
|
|
@ -536,7 +536,7 @@ bin_set(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
|
|||
|
||||
/* Obsolescent sh compatibility: set - is the same as set +xv *
|
||||
* and set - args is the same as set +xv -- args */
|
||||
if (emulation != EMULATE_ZSH && *args && **args == '-' && !args[0][1]) {
|
||||
if (!EMULATION(EMULATE_ZSH) && *args && **args == '-' && !args[0][1]) {
|
||||
dosetopt(VERBOSE, 0, 0);
|
||||
dosetopt(XTRACE, 0, 0);
|
||||
if (!args[1])
|
||||
|
|
@ -2861,6 +2861,8 @@ bin_functions(char *name, char **argv, Options ops, int func)
|
|||
shf = (Shfunc) zshcalloc(sizeof *shf);
|
||||
shf->node.flags = on;
|
||||
shf->funcdef = mkautofn(shf);
|
||||
/* No sticky emulation for autoloaded functions */
|
||||
shf->emulation = 0;
|
||||
shfunctab->addnode(shfunctab, ztrdup(*argv), shf);
|
||||
|
||||
if (signum != -1) {
|
||||
|
|
@ -4834,21 +4836,38 @@ bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func))
|
|||
{
|
||||
int opt_L = OPT_ISSET(ops, 'L');
|
||||
int opt_R = OPT_ISSET(ops, 'R');
|
||||
int saveemulation ;
|
||||
int saveemulation, savesticky_emulation;
|
||||
int ret;
|
||||
char saveopts[OPT_SIZE];
|
||||
|
||||
/* without arguments just print current emulation */
|
||||
if (!*argv) {
|
||||
const char *shname;
|
||||
|
||||
if (opt_L || opt_R) {
|
||||
zwarnnam("emulate", "not enough arguments");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("%s\n", emulation == EMULATE_CSH ? "csh" :
|
||||
emulation == EMULATE_KSH ? "ksh" :
|
||||
emulation == EMULATE_SH ? "sh" :
|
||||
"zsh");
|
||||
switch(SHELL_EMULATION()) {
|
||||
case EMULATE_CSH:
|
||||
shname = "csh";
|
||||
break;
|
||||
|
||||
case EMULATE_KSH:
|
||||
shname = "ksh";
|
||||
break;
|
||||
|
||||
case EMULATE_SH:
|
||||
shname = "sh";
|
||||
break;
|
||||
|
||||
default:
|
||||
shname = "zsh";
|
||||
break;
|
||||
}
|
||||
|
||||
printf("%s\n", shname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -4880,9 +4899,12 @@ bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func))
|
|||
|
||||
memcpy(saveopts, opts, sizeof(opts));
|
||||
saveemulation = emulation;
|
||||
savesticky_emulation = sticky_emulation;
|
||||
emulate(*argv, OPT_ISSET(ops,'R'));
|
||||
sticky_emulation = emulation;
|
||||
ret = eval(argv+2);
|
||||
memcpy(opts, saveopts, sizeof(opts));
|
||||
sticky_emulation = savesticky_emulation;
|
||||
emulation = saveemulation;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
34
Src/exec.c
34
Src/exec.c
|
|
@ -3999,6 +3999,7 @@ execfuncdef(Estate state, UNUSED(int do_exec))
|
|||
shf->node.flags = 0;
|
||||
shf->filename = ztrdup(scriptfilename);
|
||||
shf->lineno = lineno;
|
||||
shf->emulation = sticky_emulation;
|
||||
|
||||
if (!names) {
|
||||
/*
|
||||
|
|
@ -4221,7 +4222,7 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
|
|||
char *name = shfunc->node.nam;
|
||||
int flags = shfunc->node.flags;
|
||||
char *fname = dupstring(name);
|
||||
int obreaks, saveemulation ;
|
||||
int obreaks, saveemulation, savesticky_emulation, restore_sticky;
|
||||
Eprog prog;
|
||||
struct funcstack fstack;
|
||||
#ifdef MAX_FUNCTION_DEPTH
|
||||
|
|
@ -4261,6 +4262,26 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
|
|||
* function we need to restore the original options on exit. */
|
||||
memcpy(saveopts, opts, sizeof(opts));
|
||||
saveemulation = emulation;
|
||||
savesticky_emulation = sticky_emulation;
|
||||
|
||||
if (shfunc->emulation && sticky_emulation != shfunc->emulation) {
|
||||
/*
|
||||
* Function is marked for sticky emulation.
|
||||
* Enable it now.
|
||||
*
|
||||
* We deliberately do not do this if the sticky emulation
|
||||
* in effect is the same as that requested. This enables
|
||||
* option setting naturally within emulation environments.
|
||||
* Note that a difference in EMULATE_FULLY (emulate with
|
||||
* or without -R) counts as a different environment.
|
||||
*
|
||||
* This propagates the sticky emulation to subfunctions.
|
||||
*/
|
||||
emulation = sticky_emulation = shfunc->emulation;
|
||||
restore_sticky = 1;
|
||||
installemulation();
|
||||
} else
|
||||
restore_sticky = 0;
|
||||
|
||||
if (flags & PM_TAGGED)
|
||||
opts[XTRACE] = 1;
|
||||
|
|
@ -4349,7 +4370,16 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
|
|||
zoptind = oldzoptind;
|
||||
scriptname = oldscriptname;
|
||||
|
||||
if (isset(LOCALOPTIONS)) {
|
||||
if (restore_sticky) {
|
||||
/*
|
||||
* If we switched to an emulation environment just for
|
||||
* this function, we interpret the option and emulation
|
||||
* switch as being a firewall between environments.
|
||||
*/
|
||||
memcpy(opts, saveopts, sizeof(opts));
|
||||
emulation = saveemulation;
|
||||
sticky_emulation = savesticky_emulation;
|
||||
} else if (isset(LOCALOPTIONS)) {
|
||||
/* restore all shell options except PRIVILEGED and RESTRICTED */
|
||||
saveopts[PRIVILEGED] = opts[PRIVILEGED];
|
||||
saveopts[RESTRICTED] = opts[RESTRICTED];
|
||||
|
|
|
|||
|
|
@ -588,7 +588,7 @@ mod_export HashTable cmdnamtab;
|
|||
|
||||
/**/
|
||||
mod_export char **pathchecked;
|
||||
|
||||
|
||||
/* Create a new command hash table */
|
||||
|
||||
/**/
|
||||
|
|
|
|||
15
Src/init.c
15
Src/init.c
|
|
@ -775,7 +775,7 @@ setupvals(void)
|
|||
if(unset(INTERACTIVE)) {
|
||||
prompt = ztrdup("");
|
||||
prompt2 = ztrdup("");
|
||||
} else if (emulation == EMULATE_KSH || emulation == EMULATE_SH) {
|
||||
} else if (EMULATION(EMULATE_KSH|EMULATE_SH)) {
|
||||
prompt = ztrdup(privasserted() ? "# " : "$ ");
|
||||
prompt2 = ztrdup("> ");
|
||||
} else {
|
||||
|
|
@ -783,7 +783,7 @@ setupvals(void)
|
|||
prompt2 = ztrdup("%_> ");
|
||||
}
|
||||
prompt3 = ztrdup("?# ");
|
||||
prompt4 = (emulation == EMULATE_KSH || emulation == EMULATE_SH)
|
||||
prompt4 = EMULATION(EMULATE_KSH|EMULATE_SH)
|
||||
? ztrdup("+ ") : ztrdup("+%N:%i> ");
|
||||
sprompt = ztrdup("zsh: correct '%R' to '%r' [nyae]? ");
|
||||
|
||||
|
|
@ -811,14 +811,14 @@ setupvals(void)
|
|||
/* Get password entry and set info for `USERNAME' */
|
||||
#ifdef USE_GETPWUID
|
||||
if ((pswd = getpwuid(cached_uid))) {
|
||||
if (emulation == EMULATE_ZSH)
|
||||
if (EMULATION(EMULATE_ZSH))
|
||||
home = metafy(pswd->pw_dir, -1, META_DUP);
|
||||
cached_username = ztrdup(pswd->pw_name);
|
||||
}
|
||||
else
|
||||
#endif /* USE_GETPWUID */
|
||||
{
|
||||
if (emulation == EMULATE_ZSH)
|
||||
if (EMULATION(EMULATE_ZSH))
|
||||
home = ztrdup("/");
|
||||
cached_username = ztrdup("");
|
||||
}
|
||||
|
|
@ -828,7 +828,7 @@ setupvals(void)
|
|||
* In non-native emulations HOME must come from the environment;
|
||||
* we're not allowed to set it locally.
|
||||
*/
|
||||
if (emulation == EMULATE_ZSH)
|
||||
if (EMULATION(EMULATE_ZSH))
|
||||
ptr = home;
|
||||
else
|
||||
ptr = zgetenv("HOME");
|
||||
|
|
@ -954,7 +954,7 @@ run_init_scripts(void)
|
|||
{
|
||||
noerrexit = -1;
|
||||
|
||||
if (emulation == EMULATE_KSH || emulation == EMULATE_SH) {
|
||||
if (EMULATION(EMULATE_KSH|EMULATE_SH)) {
|
||||
if (islogin)
|
||||
source("/etc/profile");
|
||||
if (unset(PRIVILEGED)) {
|
||||
|
|
@ -1160,8 +1160,7 @@ sourcehome(char *s)
|
|||
char *h;
|
||||
|
||||
queue_signals();
|
||||
if (emulation == EMULATE_SH || emulation == EMULATE_KSH ||
|
||||
!(h = getsparam("ZDOTDIR"))) {
|
||||
if (EMULATION(EMULATE_SH|EMULATE_KSH) || !(h = getsparam("ZDOTDIR"))) {
|
||||
h = home;
|
||||
if (!h)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ for x_mod in $x_mods; do
|
|||
unset moddeps autofeatures
|
||||
. $srcdir/../$modfile
|
||||
if test "x$autofeatures" != x; then
|
||||
echo " if (emulation == EMULATE_ZSH) {"
|
||||
echo " if (EMULATION(EMULATE_ZSH)) {"
|
||||
echo " char *features[] = { "
|
||||
for feature in $autofeatures; do
|
||||
echo " \"$feature\","
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@
|
|||
/**/
|
||||
mod_export int emulation;
|
||||
|
||||
/* current sticky emulation: 0 means none */
|
||||
|
||||
/**/
|
||||
mod_export int sticky_emulation;
|
||||
|
||||
/* the options; e.g. if opts[SHGLOB] != 0, SH_GLOB is turned on */
|
||||
|
||||
/**/
|
||||
|
|
@ -58,9 +63,12 @@ mod_export HashTable optiontab;
|
|||
#define OPT_NONBOURNE (OPT_ALL & ~OPT_BOURNE)
|
||||
#define OPT_NONZSH (OPT_ALL & ~OPT_ZSH)
|
||||
|
||||
#define OPT_EMULATE (1<<5) /* option is relevant to emulation */
|
||||
#define OPT_SPECIAL (1<<6) /* option should never be set by emulate() */
|
||||
#define OPT_ALIAS (1<<7) /* option is an alias to an other option */
|
||||
/* option is relevant to emulation */
|
||||
#define OPT_EMULATE (EMULATE_UNUSED)
|
||||
/* option should never be set by emulate() */
|
||||
#define OPT_SPECIAL (EMULATE_UNUSED<<1)
|
||||
/* option is an alias to an other option */
|
||||
#define OPT_ALIAS (EMULATE_UNUSED<<2)
|
||||
|
||||
#define defset(X) (!!((X)->node.flags & emulation))
|
||||
|
||||
|
|
@ -475,6 +483,14 @@ setemulate(HashNode hn, int fully)
|
|||
opts[on->optno] = defset(on);
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
installemulation(void)
|
||||
{
|
||||
scanhashtable(optiontab, 0, 0, 0, setemulate,
|
||||
!!(emulation & EMULATE_FULLY));
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
emulate(const char *zsh_name, int fully)
|
||||
|
|
@ -494,7 +510,9 @@ emulate(const char *zsh_name, int fully)
|
|||
else
|
||||
emulation = EMULATE_ZSH;
|
||||
|
||||
scanhashtable(optiontab, 0, 0, 0, setemulate, fully);
|
||||
if (fully)
|
||||
emulation |= EMULATE_FULLY;
|
||||
installemulation();
|
||||
}
|
||||
|
||||
/* setopt, unsetopt */
|
||||
|
|
|
|||
|
|
@ -642,7 +642,7 @@ createparamtable(void)
|
|||
/* Add the special parameters to the hash table */
|
||||
for (ip = special_params; ip->node.nam; ip++)
|
||||
paramtab->addnode(paramtab, ztrdup(ip->node.nam), ip);
|
||||
if (emulation != EMULATE_SH && emulation != EMULATE_KSH)
|
||||
if (!EMULATION(EMULATE_SH|EMULATE_KSH))
|
||||
while ((++ip)->node.nam)
|
||||
paramtab->addnode(paramtab, ztrdup(ip->node.nam), ip);
|
||||
|
||||
|
|
@ -720,7 +720,7 @@ createparamtable(void)
|
|||
#endif
|
||||
opts[ALLEXPORT] = oae;
|
||||
|
||||
if (emulation == EMULATE_ZSH)
|
||||
if (EMULATION(EMULATE_ZSH))
|
||||
{
|
||||
/*
|
||||
* For native emulation we always set the variable home
|
||||
|
|
@ -1881,7 +1881,7 @@ getstrvalue(Value v)
|
|||
switch(PM_TYPE(v->pm->node.flags)) {
|
||||
case PM_HASHED:
|
||||
/* (!v->isarr) should be impossible unless emulating ksh */
|
||||
if (!v->isarr && emulation == EMULATE_KSH) {
|
||||
if (!v->isarr && EMULATION(EMULATE_KSH)) {
|
||||
s = dupstring("[0]");
|
||||
if (getindex(&s, v, 0) == 0)
|
||||
s = getstrvalue(v);
|
||||
|
|
@ -2164,7 +2164,7 @@ export_param(Param pm)
|
|||
|
||||
if (PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)) {
|
||||
#if 0 /* Requires changes elsewhere in params.c and builtin.c */
|
||||
if (emulation == EMULATE_KSH /* isset(KSHARRAYS) */) {
|
||||
if (EMULATION(EMULATE_KSH) /* isset(KSHARRAYS) */) {
|
||||
struct value v;
|
||||
v.isarr = 1;
|
||||
v.flags = 0;
|
||||
|
|
|
|||
|
|
@ -3415,6 +3415,7 @@ dump_autoload(char *nam, char *file, int on, Options ops, int func)
|
|||
shf = (Shfunc) zshcalloc(sizeof *shf);
|
||||
shf->node.flags = on;
|
||||
shf->funcdef = mkautofn(shf);
|
||||
shf->emulation = 0;
|
||||
shfunctab->addnode(shfunctab, ztrdup(fdname(n) + fdhtail(n)), shf);
|
||||
if (OPT_ISSET(ops,'X') && eval_autoload(shf, shf->node.nam, ops, func))
|
||||
ret = 1;
|
||||
|
|
|
|||
|
|
@ -706,6 +706,7 @@ dosavetrap(int sig, int level)
|
|||
newshf->node.flags = shf->node.flags;
|
||||
newshf->funcdef = dupeprog(shf->funcdef, 0);
|
||||
newshf->filename = ztrdup(shf->filename);
|
||||
newshf->emulation = shf->emulation;
|
||||
if (shf->node.flags & PM_UNDEFINED)
|
||||
newshf->funcdef->shf = newshf;
|
||||
}
|
||||
|
|
@ -1201,7 +1202,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
|
|||
/* return triggered */
|
||||
retflag = 1;
|
||||
} else {
|
||||
if (traperr && emulation != EMULATE_SH)
|
||||
if (traperr && !EMULATION(EMULATE_SH))
|
||||
lastval = 1;
|
||||
if (try_tryflag)
|
||||
errflag = traperr;
|
||||
|
|
|
|||
|
|
@ -1534,7 +1534,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
|||
* doesn't have parameter flags it might be neater to
|
||||
* handle this with the ^, =, ~ stuff, below.
|
||||
*/
|
||||
if ((c = *s) == '!' && s[1] != Outbrace && emulation == EMULATE_KSH) {
|
||||
if ((c = *s) == '!' && s[1] != Outbrace && EMULATION(EMULATE_KSH)) {
|
||||
hkeys = SCANPM_WANTKEYS;
|
||||
s++;
|
||||
} else if (c == '(' || c == Inpar) {
|
||||
|
|
|
|||
15
Src/zsh.h
15
Src/zsh.h
|
|
@ -1067,6 +1067,7 @@ struct shfunc {
|
|||
char *filename; /* Name of file located in */
|
||||
zlong lineno; /* line number in above file */
|
||||
Eprog funcdef; /* function definition */
|
||||
int emulation; /* sticky emulation for function */
|
||||
};
|
||||
|
||||
/* Shell function context types. */
|
||||
|
|
@ -1790,6 +1791,20 @@ struct histent {
|
|||
#define EMULATE_SH (1<<3) /* Bourne shell */
|
||||
#define EMULATE_ZSH (1<<4) /* `native' mode */
|
||||
|
||||
/* Test for a shell emulation. Use this rather than emulation directly. */
|
||||
#define EMULATION(X) (emulation & (X))
|
||||
|
||||
/* Return only base shell emulation field. */
|
||||
#define SHELL_EMULATION() (emulation & ((1<<5)-1))
|
||||
|
||||
/* Additional flags */
|
||||
|
||||
#define EMULATE_FULLY (1<<5) /* "emulate -R" in effect */
|
||||
/*
|
||||
* Higher bits are used in options.c, record lowest unused bit...
|
||||
*/
|
||||
#define EMULATE_UNUSED (1<<6)
|
||||
|
||||
/* option indices */
|
||||
|
||||
enum {
|
||||
|
|
|
|||
|
|
@ -3,72 +3,176 @@
|
|||
%prep
|
||||
|
||||
isset() {
|
||||
print -n "${1}: "
|
||||
if [[ -o $1 ]]; then print yes; else print no; fi
|
||||
}
|
||||
showopts() {
|
||||
# Set for Bourne shell emulation
|
||||
isset shwordsplit
|
||||
# Set in native mode and unless "emulate -R" is in use
|
||||
isset banghist
|
||||
# Set for Bourne shell emulation
|
||||
isset shwordsplit
|
||||
# Set in native mode and unless "emulate -R" is in use
|
||||
isset banghist
|
||||
}
|
||||
cshowopts() {
|
||||
showopts
|
||||
# Show a csh option, too
|
||||
isset cshnullglob
|
||||
}
|
||||
|
||||
%test
|
||||
|
||||
(showopts
|
||||
(print Before
|
||||
showopts
|
||||
fn() {
|
||||
emulate sh
|
||||
}
|
||||
fn
|
||||
print After
|
||||
showopts)
|
||||
0:Basic use of emulate
|
||||
>no
|
||||
>yes
|
||||
>yes
|
||||
>yes
|
||||
>Before
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
>After
|
||||
>shwordsplit: yes
|
||||
>banghist: yes
|
||||
|
||||
fn() {
|
||||
emulate -L sh
|
||||
print During
|
||||
showopts
|
||||
}
|
||||
print Before
|
||||
showopts
|
||||
fn
|
||||
print After
|
||||
showopts
|
||||
0:Use of emulate -L
|
||||
>no
|
||||
>yes
|
||||
>yes
|
||||
>yes
|
||||
>no
|
||||
>yes
|
||||
>Before
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
>During
|
||||
>shwordsplit: yes
|
||||
>banghist: yes
|
||||
>After
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
|
||||
(showopts
|
||||
(print Before
|
||||
showopts
|
||||
emulate -R sh
|
||||
print After
|
||||
showopts)
|
||||
0:Use of emulate -R
|
||||
>no
|
||||
>yes
|
||||
>yes
|
||||
>no
|
||||
>Before
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
>After
|
||||
>shwordsplit: yes
|
||||
>banghist: no
|
||||
|
||||
print Before
|
||||
showopts
|
||||
emulate sh -c 'showopts'
|
||||
emulate sh -c 'print During; showopts'
|
||||
print After
|
||||
showopts
|
||||
0:Use of emulate -c
|
||||
>no
|
||||
>yes
|
||||
>yes
|
||||
>yes
|
||||
>no
|
||||
>yes
|
||||
|
||||
>Before
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
>During
|
||||
>shwordsplit: yes
|
||||
>banghist: yes
|
||||
>After
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
|
||||
print Before
|
||||
showopts
|
||||
emulate -R sh -c 'showopts'
|
||||
emulate -R sh -c 'print During; showopts'
|
||||
print After
|
||||
showopts
|
||||
0:Use of emulate -R -c
|
||||
>no
|
||||
>yes
|
||||
>yes
|
||||
>no
|
||||
>no
|
||||
>yes
|
||||
>Before
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
>During
|
||||
>shwordsplit: yes
|
||||
>banghist: no
|
||||
>After
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
|
||||
print Before
|
||||
showopts
|
||||
emulate -R sh -c 'shshowopts() { showopts; }'
|
||||
print After definition
|
||||
showopts
|
||||
print In sticky emulation
|
||||
shshowopts
|
||||
print After sticky emulation
|
||||
showopts
|
||||
0:Basic sticky function emulation
|
||||
>Before
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
>After definition
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
>In sticky emulation
|
||||
>shwordsplit: yes
|
||||
>banghist: no
|
||||
>After sticky emulation
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
|
||||
print Before
|
||||
cshowopts
|
||||
emulate -R sh -c 'shshowopts() { cshowopts; }'
|
||||
emulate csh -c 'cshshowopts() {
|
||||
cshowopts
|
||||
print In nested sh emulation
|
||||
shshowopts
|
||||
}'
|
||||
print After definition
|
||||
cshowopts
|
||||
print In sticky csh emulation
|
||||
cshshowopts
|
||||
print After sticky emulation
|
||||
cshowopts
|
||||
0:Basic sticky function emulation
|
||||
>Before
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
>cshnullglob: no
|
||||
>After definition
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
>cshnullglob: no
|
||||
>In sticky csh emulation
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
>cshnullglob: yes
|
||||
>In nested sh emulation
|
||||
>shwordsplit: yes
|
||||
>banghist: no
|
||||
>cshnullglob: no
|
||||
>After sticky emulation
|
||||
>shwordsplit: no
|
||||
>banghist: yes
|
||||
>cshnullglob: no
|
||||
|
||||
isalp() { if [[ -o alwayslastprompt ]]; then print on; else print off; fi; }
|
||||
emulate sh -c 'shfunc_inner() { setopt alwayslastprompt; }'
|
||||
emulate csh -c 'cshfunc_inner() { setopt alwayslastprompt; }'
|
||||
emulate sh -c 'shfunc_outer() {
|
||||
unsetopt alwayslastprompt;
|
||||
shfunc_inner;
|
||||
isalp
|
||||
unsetopt alwayslastprompt
|
||||
cshfunc_inner
|
||||
isalp
|
||||
}'
|
||||
shfunc_outer
|
||||
0:Sticky emulation not triggered if sticky emulation unchanged
|
||||
>on
|
||||
>off
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue