From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13369 invoked from network); 10 Feb 2009 23:04:26 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00,URI_NOVOWEL autolearn=no version=3.2.5 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 10 Feb 2009 23:04:26 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 37037 invoked from network); 10 Feb 2009 23:04:15 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 10 Feb 2009 23:04:15 -0000 Received: (qmail 25064 invoked by alias); 10 Feb 2009 23:04:07 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 26546 Received: (qmail 25051 invoked from network); 10 Feb 2009 23:04:06 -0000 Received: from bifrost.dotsrc.org (130.225.254.106) by sunsite.dk with SMTP; 10 Feb 2009 23:04:06 -0000 Received: from mtaout03-winn.ispmail.ntl.com (mtaout03-winn.ispmail.ntl.com [81.103.221.49]) by bifrost.dotsrc.org (Postfix) with ESMTP id 19F9880271F0 for ; Wed, 11 Feb 2009 00:04:01 +0100 (CET) Received: from aamtaout02-winn.ispmail.ntl.com ([81.103.221.35]) by mtaout03-winn.ispmail.ntl.com (InterMail vM.7.08.04.00 201-2186-134-20080326) with ESMTP id <20090210230401.MLSI7670.mtaout03-winn.ispmail.ntl.com@aamtaout02-winn.ispmail.ntl.com> for ; Tue, 10 Feb 2009 23:04:01 +0000 Received: from pws-pc.ntlworld.com ([81.107.42.185]) by aamtaout02-winn.ispmail.ntl.com (InterMail vG.2.02.00.01 201-2161-120-102-20060912) with ESMTP id <20090210230358.TQVG21638.aamtaout02-winn.ispmail.ntl.com@pws-pc.ntlworld.com> for ; Tue, 10 Feb 2009 23:03:58 +0000 Received: from pws-pc (pws-pc [127.0.0.1]) by pws-pc.ntlworld.com (8.14.3/8.14.2) with ESMTP id n1AN3f3w018953 for ; Tue, 10 Feb 2009 23:03:41 GMT From: Peter Stephenson To: zsh-workers@sunsite.dk (Zsh hackers list) Subject: PATCH: sticky emulation X-Mailer: MH-E 8.0.3; nmh 1.3; GNU Emacs 22.3.1 Date: Tue, 10 Feb 2009 23:03:41 +0000 Message-ID: <18952.1234307021@pws-pc> X-Cloudmark-Analysis: v=1.0 c=1 a=NLZqzBF-AAAA:8 a=Jviz5gJZsyDx41bZ07IA:9 a=1ym7DjUNaQsDtRJ4q0gA:7 a=GVxfgOaRStt50Y3r0Xg2b3xEg14A:4 a=XF7b4UCPwd8A:10 a=_dQi-Dcv4p4A:10 X-Virus-Scanned: ClamAV 0.92.1/8977/Tue Feb 10 20:33:54 2009 on bifrost X-Virus-Status: Clean This is how I envision (and have already described, at least briefly) sticky emulation for functions working. This does not yet have documentation, nor a way of setting or querying sticky emulation for individual functions. It will have at least the former if it gets committed. There's a certain amount of administrative reorganisation of emulation flags here which isn't important; the key parts are in doshfunc() (the hunks containing references to "restore_sticky"). Pretty much everything else is straightforward---as discussed, "emulate ... -c" always causes sticky emulation to be set. Note that sticky emulation is not propagated to autoloaded functions, neither when the autoload is set up nor when they are loaded, nor does autoloading a function provide the same sort of firewall as sticky emulation. Defining a function with the special "functions" parameter is treated the same as defining a function inline in the normal way. Sticky emulation does propagate to functions defined within sticky emulation functions---this is inevitable: there should be no difference between whether a function was defined within the initial "emulate" or within a function defined there but called later. >>From the previous discussions, I think the most controversial features (though I'm happy these are reasonable, myself) are: - Sticky emulation does not cause options to be saved and reset while executing another function with the same sticky emulation. This is to provide consistent emulation environments --- something running in sh emulation doesn't expect a complete set of options to be imposed and later removed when it calls another function in the same emulation. - Functions without sticky emulation are not specially handled, so are entered with no option changes, and do not have options reset on exit except as normal shell handling, e.g. LOCAL_OPTIONS. Setting LOCAL_OPTIONS is in any case the right thing for a native zsh function to do to sanitise and protect its local environment, so I don't see any point in limiting its behaviour in the new code. You can of course use "emulate zsh -c 'fn() { ... }'" if you so desire; that's not really what this is intended for but it's supposed to work consistently. Someone can probably tell me if I should be keeping the RESTRICTED and PRIVILEGED options when restoring options after executing a sticky function, as for LOCAL_OPTIONS handling but not as for "emulate"; my brain hurts. I think the answer is "no" because it looks more like the latter case than the former, but it may not be that simple. Index: Src/builtin.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v retrieving revision 1.219 diff -u -r1.219 builtin.c --- Src/builtin.c 25 Jan 2009 18:19:29 -0000 1.219 +++ Src/builtin.c 10 Feb 2009 22:40:13 -0000 @@ -536,7 +536,7 @@ /* 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 @@ 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 @@ { 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 @@ 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; } Index: Src/exec.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/exec.c,v retrieving revision 1.162 diff -u -r1.162 exec.c --- Src/exec.c 17 Nov 2008 16:56:42 -0000 1.162 +++ Src/exec.c 10 Feb 2009 22:40:15 -0000 @@ -3999,6 +3999,7 @@ shf->node.flags = 0; shf->filename = ztrdup(scriptfilename); shf->lineno = lineno; + shf->emulation = sticky_emulation; if (!names) { /* @@ -4221,7 +4222,7 @@ 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 @@ * 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 @@ 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]; Index: Src/hashtable.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/hashtable.c,v retrieving revision 1.30 diff -u -r1.30 hashtable.c --- Src/hashtable.c 1 Nov 2008 01:19:35 -0000 1.30 +++ Src/hashtable.c 10 Feb 2009 22:40:15 -0000 @@ -588,7 +588,7 @@ /**/ mod_export char **pathchecked; - + /* Create a new command hash table */ /**/ Index: Src/init.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/init.c,v retrieving revision 1.97 diff -u -r1.97 init.c --- Src/init.c 16 Sep 2008 15:07:08 -0000 1.97 +++ Src/init.c 10 Feb 2009 22:40:15 -0000 @@ -775,7 +775,7 @@ 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 @@ 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 @@ /* 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 @@ * 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 @@ { 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 @@ 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; Index: Src/mkbltnmlst.sh =================================================================== RCS file: /cvsroot/zsh/zsh/Src/mkbltnmlst.sh,v retrieving revision 1.9 diff -u -r1.9 mkbltnmlst.sh --- Src/mkbltnmlst.sh 6 Jul 2007 21:52:39 -0000 1.9 +++ Src/mkbltnmlst.sh 10 Feb 2009 22:40:15 -0000 @@ -40,7 +40,7 @@ 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\"," Index: Src/options.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/options.c,v retrieving revision 1.46 diff -u -r1.46 options.c --- Src/options.c 11 Sep 2008 12:49:20 -0000 1.46 +++ Src/options.c 10 Feb 2009 22:40:16 -0000 @@ -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 @@ #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)) @@ -477,6 +485,14 @@ /**/ void +installemulation(void) +{ + scanhashtable(optiontab, 0, 0, 0, setemulate, + !!(emulation & EMULATE_FULLY)); +} + +/**/ +void emulate(const char *zsh_name, int fully) { char ch = *zsh_name; @@ -494,7 +510,9 @@ else emulation = EMULATE_ZSH; - scanhashtable(optiontab, 0, 0, 0, setemulate, fully); + if (fully) + emulation |= EMULATE_FULLY; + installemulation(); } /* setopt, unsetopt */ Index: Src/params.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/params.c,v retrieving revision 1.154 diff -u -r1.154 params.c --- Src/params.c 15 Jan 2009 19:47:20 -0000 1.154 +++ Src/params.c 10 Feb 2009 22:40:17 -0000 @@ -642,7 +642,7 @@ /* 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 @@ #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 @@ 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 @@ 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; Index: Src/parse.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/parse.c,v retrieving revision 1.77 diff -u -r1.77 parse.c --- Src/parse.c 18 Nov 2008 10:07:31 -0000 1.77 +++ Src/parse.c 10 Feb 2009 22:40:17 -0000 @@ -3415,6 +3415,7 @@ 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; Index: Src/signals.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/signals.c,v retrieving revision 1.53 diff -u -r1.53 signals.c --- Src/signals.c 29 Sep 2008 21:46:58 -0000 1.53 +++ Src/signals.c 10 Feb 2009 22:40:18 -0000 @@ -706,6 +706,7 @@ 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 @@ /* return triggered */ retflag = 1; } else { - if (traperr && emulation != EMULATE_SH) + if (traperr && !EMULATION(EMULATE_SH)) lastval = 1; if (try_tryflag) errflag = traperr; Index: Src/subst.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/subst.c,v retrieving revision 1.93 diff -u -r1.93 subst.c --- Src/subst.c 18 Nov 2008 10:07:31 -0000 1.93 +++ Src/subst.c 10 Feb 2009 22:40:18 -0000 @@ -1534,7 +1534,7 @@ * 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) { Index: Src/zsh.h =================================================================== RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v retrieving revision 1.151 diff -u -r1.151 zsh.h --- Src/zsh.h 18 Nov 2008 10:07:31 -0000 1.151 +++ Src/zsh.h 10 Feb 2009 22:40:19 -0000 @@ -1067,6 +1067,7 @@ 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 @@ #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 { Index: Src/Modules/newuser.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Modules/newuser.c,v retrieving revision 1.6 diff -u -r1.6 newuser.c --- Src/Modules/newuser.c 19 Jun 2007 20:37:40 -0000 1.6 +++ Src/Modules/newuser.c 10 Feb 2009 22:40:19 -0000 @@ -78,7 +78,7 @@ 0 }; const char **sp; - if (emulation != EMULATE_ZSH) + if (!EMULATION(EMULATE_ZSH)) return 0; if (!dotdir) { Index: Src/Modules/parameter.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Modules/parameter.c,v retrieving revision 1.50 diff -u -r1.50 parameter.c --- Src/Modules/parameter.c 29 Sep 2008 08:46:33 -0000 1.50 +++ Src/Modules/parameter.c 10 Feb 2009 22:40:19 -0000 @@ -289,6 +289,7 @@ 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) { Index: Test/B07emulate.ztst =================================================================== RCS file: /cvsroot/zsh/zsh/Test/B07emulate.ztst,v retrieving revision 1.1 diff -u -r1.1 B07emulate.ztst --- Test/B07emulate.ztst 10 Feb 2009 20:30:11 -0000 1.1 +++ Test/B07emulate.ztst 10 Feb 2009 22:40:19 -0000 @@ -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 -- Peter Stephenson Web page now at http://homepage.ntlworld.com/p.w.stephenson/