From 2a5a899a55fd2bce10efd01c75a4bec5285aa46c Mon Sep 17 00:00:00 2001 From: Tanaka Akira Date: Thu, 15 Apr 1999 18:10:10 +0000 Subject: zsh-3.1.5-pws-4 --- Src/Builtins/rlimits.c | 15 +++ Src/Builtins/sched.c | 14 +++ Src/Modules/cap.c | 15 +++ Src/Modules/clone.c | 15 +++ Src/Modules/example.c | 47 +++++---- Src/Modules/files.c | 15 +++ Src/Modules/stat.c | 14 +++ Src/Modules/zftp.c | 48 +++++++-- Src/Zle/comp.h | 5 +- Src/Zle/comp1.c | 16 ++- Src/Zle/compctl.c | 23 ++++- Src/Zle/deltochar.c | 15 +++ Src/Zle/zle_main.c | 35 +++++-- Src/Zle/zle_tricky.c | 18 +++- Src/builtin.c | 6 +- Src/cond.c | 58 ++++++++++- Src/exec.c | 22 ++--- Src/glob.c | 2 +- Src/init.c | 5 + Src/makepro.awk | 2 +- Src/mkbltnmlst.sh | 2 +- Src/modentry.c | 24 ++++- Src/module.c | 257 +++++++++++++++++++++++++++++++++++++------------ Src/params.c | 78 +++++++++------ Src/parse.c | 6 +- Src/signals.c | 4 + Src/subst.c | 28 ++++-- Src/utils.c | 22 +++-- Src/zsh.export | 3 + Src/zsh.h | 65 ++++++++----- 30 files changed, 677 insertions(+), 202 deletions(-) (limited to 'Src') diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c index 20b8d663d..31dcb71b1 100644 --- a/Src/Builtins/rlimits.c +++ b/Src/Builtins/rlimits.c @@ -574,6 +574,13 @@ static struct builtin bintab[] = { BUILTIN("unlimit", 0, bin_unlimit, 0, -1, 0, "hs", NULL), }; +/**/ +int +setup_rlimits(Module m) +{ + return 0; +} + /**/ int boot_rlimits(Module m) @@ -590,4 +597,12 @@ cleanup_rlimits(Module m) deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); return 0; } + +/**/ +int +finish_rlimits(Module m) +{ + return 0; +} + #endif diff --git a/Src/Builtins/sched.c b/Src/Builtins/sched.c index b4914899e..94661ccef 100644 --- a/Src/Builtins/sched.c +++ b/Src/Builtins/sched.c @@ -183,6 +183,13 @@ static struct builtin bintab[] = { BUILTIN("sched", 0, bin_sched, 0, -1, 0, NULL, NULL), }; +/**/ +int +setup_sched(Module m) +{ + return 0; +} + /**/ int boot_sched(Module m) @@ -211,4 +218,11 @@ cleanup_sched(Module m) return 0; } +/**/ +int +finish_sched(Module m) +{ + return 0; +} + #endif diff --git a/Src/Modules/cap.c b/Src/Modules/cap.c index 008b6932d..dfeca86ad 100644 --- a/Src/Modules/cap.c +++ b/Src/Modules/cap.c @@ -122,6 +122,13 @@ static struct builtin bintab[] = { BUILTIN("setcap", 0, bin_setcap, 2, -1, 0, NULL, NULL), }; +/**/ +int +setup_cap(Module m) +{ + return 0; +} + /**/ int boot_cap(Module m) @@ -138,4 +145,12 @@ cleanup_cap(Module m) deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); return 0; } + +/**/ +int +finish_cap(Module m) +{ + return 0; +} + #endif diff --git a/Src/Modules/clone.c b/Src/Modules/clone.c index 11387fc90..e2cfea8d9 100644 --- a/Src/Modules/clone.c +++ b/Src/Modules/clone.c @@ -96,6 +96,13 @@ static struct builtin bintab[] = { BUILTIN("clone", 0, bin_clone, 1, 1, 0, NULL, NULL), }; +/**/ +int +setup_clone(Module m) +{ + return 0; +} + /**/ int boot_clone(Module m) @@ -112,4 +119,12 @@ cleanup_clone(Module m) deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); return 0; } + +/**/ +int +finish_clone(Module m) +{ + return 0; +} + #endif diff --git a/Src/Modules/example.c b/Src/Modules/example.c index a71806c3a..95545172f 100644 --- a/Src/Modules/example.c +++ b/Src/Modules/example.c @@ -51,16 +51,14 @@ bin_example(char *nam, char **args, char *ops, int func) /**/ static int -cond_p_len(Conddef c, char **a) +cond_p_len(char **a, int id) { - char *s1 = a[0], *s2 = a[1]; - - singsub(&s1); - untokenize(s1); - if (s2) { - singsub(&s2); - untokenize(s2); - return strlen(s1) == matheval(s2); + char *s1 = cond_str(a, 0); + + if (a[1]) { + long v = cond_val(a, 1); + + return strlen(s1) == v; } else { return !s1[0]; } @@ -68,14 +66,10 @@ cond_p_len(Conddef c, char **a) /**/ static int -cond_i_ex(Conddef c, char **a) +cond_i_ex(char **a, int id) { - char *s1 = a[0], *s2 = a[1]; + char *s1 = cond_str(a, 0), *s2 = cond_str(a, 1); - singsub(&s1); - untokenize(s1); - singsub(&s2); - untokenize(s2); return !strcmp("example", dyncat(s1, s2)); } @@ -105,14 +99,23 @@ static struct builtin bintab[] = { }; static struct conddef cotab[] = { - CONDDEF("len", 0, 1, 2, cond_p_len), - CONDDEF("ex", CONDF_INFIX, 0, 0, cond_i_ex), + CONDDEF("len", 0, cond_p_len, 1, 2, 0), + CONDDEF("ex", CONDF_INFIX, cond_i_ex, 0, 0, 0), }; static struct funcwrap wrapper[] = { WRAPDEF(ex_wrapper), }; +/**/ +int +setup_example(Module m) +{ + printf("The example module has now been set up.\n"); + fflush(stdout); + return 0; +} + /**/ int boot_example(Module m) @@ -133,4 +136,14 @@ cleanup_example(Module m) deletewrapper(m, wrapper); return 0; } + +/**/ +int +finish_example(Module m) +{ + printf("Thank you for using the example module. Have a nice day.\n"); + fflush(stdout); + return 0; +} + #endif diff --git a/Src/Modules/files.c b/Src/Modules/files.c index 6127c5524..f52c54338 100644 --- a/Src/Modules/files.c +++ b/Src/Modules/files.c @@ -509,6 +509,13 @@ static struct builtin bintab[] = { BUILTIN("sync", 0, bin_sync, 0, 0, 0, NULL, NULL), }; +/**/ +int +setup_files(Module m) +{ + return 0; +} + /**/ int boot_files(Module m) @@ -525,4 +532,12 @@ cleanup_files(Module m) deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); return 0; } + +/**/ +int +finish_files(Module m) +{ + return 0; +} + #endif diff --git a/Src/Modules/stat.c b/Src/Modules/stat.c index 769b42b1a..5c56be5c6 100644 --- a/Src/Modules/stat.c +++ b/Src/Modules/stat.c @@ -569,6 +569,13 @@ static struct builtin bintab[] = { BUILTIN("stat", 0, bin_stat, 0, -1, 0, NULL, NULL), }; +/**/ +int +setup_stat(Module m) +{ + return 0; +} + /**/ int boot_stat(Module m) @@ -586,4 +593,11 @@ cleanup_stat(Module m) return 0; } +/**/ +int +finish_stat(Module m) +{ + return 0; +} + #endif diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index ca0843419..4bcd80c7f 100644 --- a/Src/Modules/zftp.c +++ b/Src/Modules/zftp.c @@ -62,9 +62,9 @@ /* it's a TELNET based protocol, but don't think I like doing this */ #include -/* bet there are machines which have neither INADDR_NONE nor in_addr_t. */ +/* pinch the definition from for deficient headers */ #ifndef INADDR_NONE -#define INADDR_NONE (in_addr_t)-1 +#define INADDR_NONE 0xffffffff #endif /* @@ -1354,7 +1354,11 @@ zfsenddata(char *name, int recv, int progress, long startat) * We do this here in case we needed to wait for a RETR * command to tell us how many bytes are coming. */ + int osc = sfcontext; + + sfcontext = SFC_HOOK; doshfunc("zftp_progress", l, NULL, 0, 1); + sfcontext = osc; /* Now add in the bit of the file we've got/sent already */ sofar = last_sofar = startat; } @@ -1482,8 +1486,12 @@ zfsenddata(char *name, int recv, int progress, long startat) break; if (!ret && sofar != last_sofar && progress && (l = getshfunc("zftp_progress")) != &dummy_list) { + int osc = sfcontext; + zfsetparam("ZFTP_COUNT", &sofar, ZFPM_READONLY|ZFPM_INTEGER); + sfcontext = SFC_HOOK; doshfunc("zftp_progress", l, NULL, 0, 1); + sfcontext = osc; last_sofar = sofar; } } @@ -1650,7 +1658,7 @@ zftp_open(char *name, char **args, int flags) zfsetparam("ZFTP_HOST", ztrdup(zhostp->h_name), ZFPM_READONLY); } - zsock.sin_port = ntohs(zservp->s_port); + zsock.sin_port = zservp->s_port; zcfd = zfmovefd(socket(zsock.sin_family, SOCK_STREAM, 0)); if (zcfd < 0) { zwarnnam(name, "socket failed: %e", NULL, errno); @@ -2102,9 +2110,13 @@ zfgetcwd(void) * front end. By putting it here, and in close when ZFTP_PWD is unset, * we at least cover the bases. */ - if ((l = getshfunc("zftp_chpwd")) != &dummy_list) - doshfunc("zftp_chpwd", l, NULL, 0, 1); + if ((l = getshfunc("zftp_chpwd")) != &dummy_list) { + int osc = sfcontext; + sfcontext = SFC_HOOK; + doshfunc("zftp_chpwd", l, NULL, 0, 1); + sfcontext = osc; + } return 0; } @@ -2303,9 +2315,13 @@ zftp_getput(char *name, char **args, int flags) zsfree(ln); if (progress && (l = getshfunc("zftp_progress")) != &dummy_list) { /* progress to finish: ZFTP_TRANSFER set to GF or PF */ + int osc = sfcontext; + zfsetparam("ZFTP_TRANSFER", ztrdup(recv ? "GF" : "PF"), ZFPM_READONLY); + sfcontext = SFC_HOOK; doshfunc("zftp_progress", l, NULL, 0, 1); + sfcontext = osc; } if (rest) { zsfree(rest); @@ -2428,9 +2444,13 @@ zftp_close(char *name, char **args, int flags) zfunsetparam(*aptr); /* Now ZFTP_PWD is unset. It's up to zftp_chpwd to notice. */ - if ((l = getshfunc("zftp_chpwd")) != &dummy_list) - doshfunc("zftp_chpwd", l, NULL, 0, 1); + if ((l = getshfunc("zftp_chpwd")) != &dummy_list) { + int osc = sfcontext; + sfcontext = SFC_HOOK; + doshfunc("zftp_chpwd", l, NULL, 0, 1); + sfcontext = osc; + } /* tidy up status variables, because mess is bad */ zfclosing = zfdrrrring = 0; @@ -2556,6 +2576,13 @@ bin_zftp(char *name, char **args, char *ops, int func) /* The load/unload routines required by the zsh library interface */ +/**/ +int +setup_zftp(Module m) +{ + return 0; +} + /**/ int boot_zftp(Module m) @@ -2593,4 +2620,11 @@ cleanup_zftp(Module m) return 0; } +/**/ +int +finish_zftp(Module m) +{ + return 0; +} + #endif diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h index 84f8c3c98..afd55b7f1 100644 --- a/Src/Zle/comp.h +++ b/Src/Zle/comp.h @@ -98,7 +98,7 @@ struct compcond { struct compctl { int refc; /* reference count */ Compctl next; /* next compctl for -x */ - unsigned long mask, mask2; /* mask of things to complete (CC_*) */ + unsigned long mask, mask2; /* masks of things to complete (CC_*) */ char *keyvar; /* for -k (variable) */ char *glob; /* for -g (globbing) */ char *str; /* for -s (expansion) */ @@ -110,7 +110,7 @@ struct compctl { char *withd; /* for -w (with directory */ char *hpat; /* for -H (history pattern) */ int hnum; /* for -H (number of events to search) */ - char *gname; + char *gname; /* for -J and -V (group name) */ Compctl ext; /* for -x (first of the compctls after -x) */ Compcond cond; /* for -x (condition for this compctl) */ Compctl xor; /* for + (next of the xor'ed compctls) */ @@ -169,7 +169,6 @@ struct cexpl { char *str; /* the string */ int count; /* the number of matches */ int fcount; /* number of matches with fignore ignored */ - }; /* This describes a group of matches. */ diff --git a/Src/Zle/comp1.c b/Src/Zle/comp1.c index 5ffce0da2..a0c013901 100644 --- a/Src/Zle/comp1.c +++ b/Src/Zle/comp1.c @@ -430,7 +430,7 @@ quotename(const char *s, char **e, char *te, int *pl) /**/ int -boot_comp1(Module m) +setup_comp1(Module m) { compctlreadptr = compctlread; clwords = (char **) zcalloc((clwsize = 16) * sizeof(char *)); @@ -446,11 +446,25 @@ boot_comp1(Module m) return 0; } +/**/ +int +boot_comp1(Module m) +{ + return 0; +} + #ifdef MODULE /**/ int cleanup_comp1(Module m) +{ + return 0; +} + +/**/ +int +finish_comp1(Module m) { deletehashtable(compctltab); zfree(clwords, clwsize * sizeof(char *)); diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index 7104bfc6e..4d192fef8 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -1638,26 +1638,41 @@ static struct builtin bintab[] = { /**/ int -boot_compctl(Module m) +setup_compctl(Module m) { - if(!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab))) - return 1; compctltab->printnode = printcompctlp; printcompctlptr = printcompctl; compctl_widgetptr = compctl_widget; return 0; } +/**/ +int +boot_compctl(Module m) +{ + if(!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab))) + return 1; + return 0; +} + #ifdef MODULE /**/ int cleanup_compctl(Module m) { - compctltab->printnode = NULL; deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); + return 0; +} + +/**/ +int +finish_compctl(Module m) +{ + compctltab->printnode = NULL; printcompctlptr = NULL; compctl_widgetptr = NULL; return 0; } + #endif diff --git a/Src/Zle/deltochar.c b/Src/Zle/deltochar.c index 8869eb147..66a301119 100644 --- a/Src/Zle/deltochar.c +++ b/Src/Zle/deltochar.c @@ -71,6 +71,13 @@ deltochar(void) feep(); } +/**/ +int +setup_deltochar(Module m) +{ + return 0; +} + /**/ int boot_deltochar(Module m) @@ -93,4 +100,12 @@ cleanup_deltochar(Module m) deletezlefunction(w_deletetochar); return 0; } + +/**/ +int +finish_deltochar(Module m) +{ + return 0; +} + #endif diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 57b75cd39..515405a0d 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -603,11 +603,15 @@ execzlefunc(Thingy func) zsfree(msg); feep(); } else { - startparamscope(); - makezleparams(); - doshfunc(w->u.fnnam, l, NULL, 0, 1); - endparamscope(); - lastcmd = 0; + int osc = sfcontext; + + startparamscope(); + makezleparams(); + sfcontext = SFC_WIDGET; + doshfunc(w->u.fnnam, l, NULL, 0, 1); + sfcontext = osc; + endparamscope(); + lastcmd = 0; } } } @@ -856,7 +860,7 @@ static struct builtin bintab[] = { /**/ int -boot_zle(Module m) +setup_zle(Module m) { /* Set up editor entry points */ trashzleptr = trashzle; @@ -875,6 +879,13 @@ boot_zle(Module m) /* initialise the keymap system */ init_keymaps(); + return 0; +} + +/**/ +int +boot_zle(Module m) +{ addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); return 0; } @@ -885,15 +896,21 @@ boot_zle(Module m) int cleanup_zle(Module m) { - int i; - if(zleactive) { zerrnam(m->nam, "can't unload the zle module while zle is active", NULL, 0); return 1; } - deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); + return 0; +} + +/**/ +int +finish_zle(Module m) +{ + int i; + cleanup_keymaps(); deletehashtable(thingytab); diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index cbc744601..8c976449e 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -3801,15 +3801,23 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) /* Completion after `~', maketildelist adds the usernames * * and named directories. */ - if (ic == Tilde) + if (ic == Tilde) { + char *oi = ipre; + + ipre = (ipre ? dyncat("~", ipre) : "~"); maketildelist(); - else if (ic == Equals) { + ipre = oi; + } else if (ic == Equals) { /* Completion after `=', get the command names from * * the cmdnamtab and aliases from aliastab. */ + char *oi = ipre; + + ipre = (ipre ? dyncat("=", ipre) : "="); if (isset(HASHLISTALL)) cmdnamtab->filltable(cmdnamtab); dumphashtable(cmdnamtab, -7); dumphashtable(aliastab, -2); + ipre = oi; } else { /* Normal file completion... */ if (ispattern & 1) { @@ -4082,6 +4090,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) if ((list = getshfunc(cc->func)) != &dummy_list) { /* We have it, so build a argument list. */ LinkList args = newlinklist(); + int osc = sfcontext; addlinknode(args, cc->func); @@ -4099,8 +4108,10 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) /* This flag allows us to use read -l and -c. */ incompctlfunc = 1; + sfcontext = SFC_COMPLETE; /* Call the function. */ doshfunc(cc->func, list, args, 0, 1); + sfcontext = osc; incompctlfunc = 0; /* And get the result from the reply parameter. */ if ((r = get_user_var("reply"))) @@ -4246,6 +4257,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) LinkList args = newlinklist(); LinkNode ln; Cmatch m; + int osc = sfcontext; addlinknode(args, cc->ylist); for (ln = firstnode(matches); ln; ln = nextnode(ln)) { @@ -4263,7 +4275,9 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) /* No harm in allowing read -l and -c here, too */ incompctlfunc = 1; + sfcontext = SFC_COMPLETE; doshfunc(cc->ylist, list, args, 0, 1); + sfcontext = osc; incompctlfunc = 0; uv = "reply"; } diff --git a/Src/builtin.c b/Src/builtin.c index 7e77bc190..6c41ce2fd 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -992,9 +992,13 @@ cd_new_pwd(int func, LinkNode dir, int chaselinks) /* execute the chpwd function */ if ((l = getshfunc("chpwd")) != &dummy_list) { + int osc = sfcontext; + fflush(stdout); fflush(stderr); + sfcontext = SFC_HOOK; doshfunc("chpwd", l, NULL, 0, 1); + sfcontext = osc; } dirstacksize = getiparam("DIRSTACKSIZE"); @@ -1469,7 +1473,7 @@ bin_typeset(char *name, char **argv, char *ops, int func) Param pm; Asgment asg; Comp com; - char *optstr = "aiLRZlurtxU----A"; + char *optstr = "aiALRZlurtxU"; int on = 0, off = 0, roff, bit = PM_ARRAY; int initon, initoff, of, i; int returnval = 0, printflags = 0; diff --git a/Src/cond.c b/Src/cond.c index ed91f72f3..906e81938 100644 --- a/Src/cond.c +++ b/Src/cond.c @@ -48,7 +48,8 @@ evalcond(Cond c) { Conddef cd; - if ((cd = getconddef((c->type == COND_MODI), (char *) c->left, 1))) { + if ((cd = getconddef((c->type == COND_MODI), + ((char *) c->left) + 1, 1))) { if (c->type == COND_MOD) { int l = arrlen((char **) c->right); @@ -57,10 +58,24 @@ evalcond(Cond c) return 0; } } - return cd->handler(cd, (char **) c->right); + return cd->handler((char **) c->right, cd->condid); + } + else { + char **a = (char **) c->right, *s = a[0]; + + if (s && s[0] == '-' && + (cd = getconddef(0, s + 1, 1))) { + int l = arrlen(a); + + if (l < cd->min || (cd->max >= 0 && l > cd->max)) { + zerr("unrecognized condition: `-%s'", (char *) c->left, 0); + return 0; + } + a[0] = (char *) c->left; + return cd->handler(a, cd->condid); + } else + zerr("unrecognized condition: `-%s'", (char *) c->left, 0); } - else - zerr("unrecognized condition: `-%s'", (char *) c->left, 0); return 0; } } @@ -244,3 +259,38 @@ optison(char *s) else return isset(i); } + +/**/ +char * +cond_str(char **args, int num) +{ + char *s = args[num]; + + singsub(&s); + untokenize(s); + + return s; +} + +/**/ +long +cond_val(char **args, int num) +{ + char *s = args[num]; + + singsub(&s); + untokenize(s); + + return matheval(s); +} + +/**/ +int +cond_match(char **args, int num, char *str) +{ + char *s = args[num]; + + singsub(&s); + + return matchpat(str, s); +} diff --git a/Src/exec.c b/Src/exec.c index a2d74a9f4..911559a02 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -113,7 +113,12 @@ pid_t cmdoutpid; /**/ int cmdoutval; - + +/* The context in which a shell function is called, see SFC_* in zsh.h. */ + +/**/ +int sfcontext; + /* Stack to save some variables before executing a signal handler function */ /**/ @@ -2771,19 +2776,14 @@ runshfunc(List list, FuncWrap wrap, char *name) char *ou; while (wrap) { - wrap->module->flags |= MOD_WRAPPER; - wrap->count++; + wrap->module->wrapper++; cont = wrap->handler(list, wrap->next, name); - wrap->count--; - if (!wrap->count) { - wrap->module->flags &= ~MOD_WRAPPER; + wrap->module->wrapper--; #ifdef DYNAMIC - if (wrap->module->flags & MOD_UNLOAD) { - wrap->module->flags &= ~MOD_UNLOAD; - unload_module(wrap->module, NULL); - } + if (!wrap->module->wrapper && + (wrap->module->flags & MOD_UNLOAD)) + unload_module(wrap->module, NULL); #endif - } if (!cont) return; wrap = wrap->next; diff --git a/Src/glob.c b/Src/glob.c index 194d535a4..9c1d08aa4 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -1947,7 +1947,7 @@ getmatch(char **sp, char *pat, int fl, int n, char *replstr) { Comp c; char *s = *sp, *t, *start, sav; - int i, j, l = strlen(*sp), matched; + int i, l = strlen(*sp), matched; MUSTUSEHEAP("getmatch"); /* presumably covered by prefork() test */ repllist = NULL; diff --git a/Src/init.c b/Src/init.c index decc7617e..0c874eead 100644 --- a/Src/init.c +++ b/Src/init.c @@ -111,13 +111,17 @@ loop(int toplevel, int justonce) if (toplevel && (prelist = getshfunc("preexec")) != &dummy_list) { Histent he = gethistent(curhist); LinkList args; + int osc = sfcontext; + PERMALLOC { args = newlinklist(); addlinknode(args, "preexec"); if (he && he->text) addlinknode(args, he->text); } LASTALLOC; + sfcontext = SFC_HOOK; doshfunc("preexec", prelist, args, 0, 1); + sfcontext = osc; freelinklist(args, (FreeFunc) NULL); errflag = 0; } @@ -613,6 +617,7 @@ setupvals(void) breaks = loops = 0; lastmailcheck = time(NULL); locallevel = sourcelevel = 0; + sfcontext = SFC_DIRECT; trapreturn = 0; noerrexit = -1; nohistsave = 1; diff --git a/Src/makepro.awk b/Src/makepro.awk index b5d2f3dc4..86117fcc1 100644 --- a/Src/makepro.awk +++ b/Src/makepro.awk @@ -104,7 +104,7 @@ BEGIN { gsub(/@!/, ",", dcltor) # If this is a module boot/cleanup function, conditionally rename it. - if(" " dtype " " ~ / int / && dcltor ~ / *@\+(boot|cleanup)_[_0-9A-Za-z]+@- *_\(\( *Module +[_0-9A-Za-z]+ *\)\) */) { + if(" " dtype " " ~ / int / && dcltor ~ / *@\+(boot|cleanup|setup|finish)_[_0-9A-Za-z]+@- *_\(\( *Module +[_0-9A-Za-z]+ *\)\) */) { modtype = dnam sub(/_.*$/, "", modtype) output = output "# if defined(DYNAMIC_NAME_CLASH_OK) && defined(MODULE)\n" diff --git a/Src/mkbltnmlst.sh b/Src/mkbltnmlst.sh index 4a90ecd20..2f988ec8f 100644 --- a/Src/mkbltnmlst.sh +++ b/Src/mkbltnmlst.sh @@ -55,6 +55,6 @@ for bin_mod in $bin_mods; do exit 1 ;; esac done - echo " mod.nam = \"$bin_mod\"; boot_$bin_mod(&mod);" + echo " mod.nam = \"$bin_mod\"; setup_$bin_mod(&mod); boot_$bin_mod(&mod);" done_mods="$done_mods$bin_mod " done diff --git a/Src/modentry.c b/Src/modentry.c index 63c4b825d..f177e0a6a 100644 --- a/Src/modentry.c +++ b/Src/modentry.c @@ -1,15 +1,35 @@ #include "zsh.mdh" +int setup_ _((Module)); int boot_ _((Module)); int cleanup_ _((Module)); +int finish_ _((Module)); int modentry _((int boot, Module m)); /**/ int modentry(int boot, Module m) { - if (boot) + switch (boot) { + case 0: + return setup_(m); + break; + + case 1: return boot_(m); - else + break; + + case 2: return cleanup_(m); + break; + + case 3: + return finish_(m); + break; + + default: + zerr("bad call to modentry", NULL, 0); + return 1; + break; + } } diff --git a/Src/module.c b/Src/module.c index 8ed4f1d3b..5780eb134 100644 --- a/Src/module.c +++ b/Src/module.c @@ -34,6 +34,13 @@ * as a separate module. It is initialised by main(), so there's nothing * * for the boot function to do. */ +/**/ +int +setup_zsh(Module m) +{ + return 0; +} + /**/ int boot_zsh(Module m) @@ -114,7 +121,6 @@ addwrapper(Module m, FuncWrap w) w->next = NULL; w->flags |= WRAPF_ADDED; w->module = m; - w->count = 0; return 0; } @@ -256,24 +262,58 @@ load_and_bind(const char *fn) #ifdef HAVE_DLFCN_H # include #else -# include -# include -# include +# ifdef HAVE_DL_H +# include +# define RTLD_LAZY BIND_DEFERRED +# define RTLD_GLOBAL DYNAMIC_PATH +# else +# include +# include +# include +# endif #endif -#ifndef HAVE_DLCLOSE -# define dlclose(X) ((X), 0) + +#ifdef HPUXDYNAMIC +# define dlopen(file,mode) (void *)shl_load((file), (mode), (long) 0) +# define dlclose(handle) shl_unload((shl_t)(handle)) + +/**/ +static +void * +hpux_dlsym(void *handle, char *name) +{ + void *sym_addr; + if (!shl_findsym((shl_t *)&handle, name, TYPE_UNDEFINED, &sym_addr)) + return sym_addr; + return NULL; +} + +# define dlsym(handle,name) hpux_dlsym(handle,name) +# define dlerror() 0 +#else +# ifndef HAVE_DLCLOSE +# define dlclose(X) ((X), 0) +# endif #endif #ifdef DLSYM_NEEDS_UNDERSCORE +# define STR_SETUP "_setup_" +# define STR_SETUP_S "_setup_%s" # define STR_BOOT "_boot_" # define STR_BOOT_S "_boot_%s" # define STR_CLEANUP "_cleanup_" # define STR_CLEANUP_S "_cleanup_%s" +# define STR_FINISH "_finish_" +# define STR_FINISH_S "_finish_%s" #else /* !DLSYM_NEEDS_UNDERSCORE */ +# define STR_SETUP "setup_" +# define STR_SETUP_S "setup_%s" # define STR_BOOT "boot_" # define STR_BOOT_S "boot_%s" # define STR_CLEANUP "cleanup_" # define STR_CLEANUP_S "cleanup_%s" +# define STR_FINISH "finish_" +# define STR_FINISH_S "finish_%s" #endif /* !DLSYM_NEEDS_UNDERSCORE */ #endif /* !AIXDYNAMIC */ @@ -355,6 +395,13 @@ find_module(const char *name) #ifdef AIXDYNAMIC +/**/ +static int +setup_module(Module m) +{ + return ((int (*)_((int,Module))) m->handle)(0, m); +} + /**/ static int init_module(Module m) @@ -366,14 +413,20 @@ init_module(Module m) static int cleanup_module(Module m) { - return ((int (*)_((int,Module))) m->handle)(0, m); + return ((int (*)_((int,Module))) m->handle)(2, m); } -#else - /**/ static int -init_module(Module m) +finish_module(Module m) +{ + return ((int (*)_((int,Module))) m->handle)(3, m); +} + +#else + +static Module_func +module_func(Module m, char *name, char *name_s) { char *s, *t; #ifndef DYNAMIC_NAME_CLASH_OK @@ -389,13 +442,34 @@ init_module(Module m) if ((t = strrchr(s, '.'))) *t = '\0'; #ifdef DYNAMIC_NAME_CLASH_OK - fn = (Module_func) dlsym(m->handle, STR_BOOT); + fn = (Module_func) dlsym(m->handle, name); #else /* !DYNAMIC_NAME_CLASH_OK */ if (strlen(s) + 6 > PATH_MAX) - return 1; - sprintf(buf, STR_BOOT_S, s); + return NULL; + sprintf(buf, name_s, s); fn = (Module_func) dlsym(m->handle, buf); #endif /* !DYNAMIC_NAME_CLASH_OK */ + return fn; +} + +/**/ +static int +setup_module(Module m) +{ + Module_func fn = module_func(m, STR_SETUP, STR_SETUP_S); + + if (fn) + return fn(m); + zwarnnam(m->nam, "no setup function", NULL, 0); + return 1; +} + +/**/ +static int +init_module(Module m) +{ + Module_func fn = module_func(m, STR_BOOT, STR_BOOT_S); + if(fn) return fn(m); zwarnnam(m->nam, "no boot function", NULL, 0); @@ -406,33 +480,34 @@ init_module(Module m) static int cleanup_module(Module m) { - char *s, *t; -#ifndef DYNAMIC_NAME_CLASH_OK - char buf[PATH_MAX + 1]; -#endif - Module_func fn; + Module_func fn = module_func(m, STR_CLEANUP, STR_CLEANUP_S); - s = strrchr(m->nam, '/'); - if (s) - s = dupstring(++s); - else - s = m->nam; - if ((t = strrchr(s, '.'))) - *t = '\0'; -#ifdef DYNAMIC_NAME_CLASH_OK - fn = (Module_func) dlsym(m->handle, STR_CLEANUP); -#else /* !DYNAMIC_NAME_CLASH_OK */ - if (strlen(s) + 9 > PATH_MAX) - return 1; - sprintf(buf, STR_CLEANUP_S, s); - fn = (Module_func) dlsym(m->handle, buf); -#endif /* !DYNAMIC_NAME_CLASH_OK */ if(fn) return fn(m); zwarnnam(m->nam, "no cleanup function", NULL, 0); return 1; } +/* Note that this function does more than just calling finish_foo(), * + * it really unloads the module. */ + +/**/ +static int +finish_module(Module m) +{ + Module_func fn = module_func(m, STR_FINISH, STR_FINISH_S); + int r; + + if (fn) + r = fn(m); + else { + zwarnnam(m->nam, "no finish function", NULL, 0); + r = 1; + } + dlclose(m->handle); + return r; +} + #endif /* !AIXDYNAMIC */ /**/ @@ -449,8 +524,8 @@ load_module(char const *name) m = zcalloc(sizeof(*m)); m->nam = ztrdup(name); m->handle = handle; - if (init_module(m)) { - dlclose(handle); + if (setup_module(m) || init_module(m)) { + finish_module(m); zsfree(m->nam); zfree(m, sizeof(*m)); return NULL; @@ -459,25 +534,35 @@ load_module(char const *name) addlinknode(modules, m); } LASTALLOC; return m; - } + } m = (Module) getdata(node); - if (m->handle) + if (m->flags & MOD_UNLOAD) + m->flags &= ~MOD_UNLOAD; + else if (m->handle) return m; if (m->flags & MOD_BUSY) { zerr("circular dependencies for module %s", name, 0); return NULL; } m->flags |= MOD_BUSY; - for (n = firstnode(m->deps); n; incnode(n)) - if (!load_module((char *) getdata(n))) { - m->flags &= ~MOD_BUSY; + if (m->deps) + for (n = firstnode(m->deps); n; incnode(n)) + if (!load_module((char *) getdata(n))) { + m->flags &= ~MOD_BUSY; + return NULL; + } + m->flags &= ~MOD_BUSY; + if (!m->handle) { + if (!(m->handle = do_load_module(name))) + return NULL; + if (setup_module(m)) { + finish_module(m->handle); + m->handle = NULL; return NULL; } - m->flags &= ~MOD_BUSY; - if (!(m->handle = do_load_module(name))) - return NULL; + } if (init_module(m)) { - dlclose(m->handle); + finish_module(m->handle); m->handle = NULL; return NULL; } @@ -756,12 +841,53 @@ bin_zmodload_cond(char *nam, char **args, char *ops) int unload_module(Module m, LinkNode node) { - if (m->handle && cleanup_module(m)) + if (m->handle && !(m->flags & MOD_UNLOAD) && cleanup_module(m)) return 1; else { + int del = (m->flags & MOD_UNLOAD); + + if (m->wrapper) { + m->flags |= MOD_UNLOAD; + return 0; + } + m->flags &= ~MOD_UNLOAD; if (m->handle) - dlclose(m->handle); + finish_module(m); m->handle = NULL; + if (del && m->deps) { + /* The module was unloaded delayed, unload all modules * + * on which it depended. */ + LinkNode n; + + for (n = firstnode(m->deps); n; incnode(n)) { + LinkNode dn = find_module((char *) getdata(n)); + Module dm; + + if (dn && (dm = (Module) getdata(dn)) && + (dm->flags & MOD_UNLOAD)) { + /* See if this is the only module depending on it. */ + + LinkNode an; + Module am; + int du = 1; + + for (an = firstnode(modules); du && an; incnode(an)) { + am = (Module) getdata(an); + if (am != m && am->handle && am->deps) { + LinkNode sn; + + for (sn = firstnode(am->deps); du && sn; + incnode(sn)) { + if (!strcmp((char *) getdata(sn), dm->nam)) + du = 0; + } + } + } + if (du) + unload_module(dm, NULL); + } + } + } if(!m->deps) { if (!node) { for (node = firstnode(modules); node; incnode(node)) @@ -791,24 +917,29 @@ bin_zmodload_load(char *nam, char **args, char *ops) node = find_module(*args); if (node) { LinkNode mn, dn; + int del = 0; for (mn = firstnode(modules); mn; incnode(mn)) { m = (Module) getdata(mn); if (m->deps && m->handle) for (dn = firstnode(m->deps); dn; incnode(dn)) if (!strcmp((char *) getdata(dn), *args)) { - zwarnnam(nam, "module %s is in use by another module and cannot be unloaded", *args, 0); - ret = 1; - goto cont; + if (m->flags & MOD_UNLOAD) + del = 1; + else { + zwarnnam(nam, "module %s is in use by another module and cannot be unloaded", *args, 0); + ret = 1; + goto cont; + } } } m = (Module) getdata(node); - if (!(m->flags & MOD_WRAPPER)) { - if (unload_module(m, node)) - ret = 1; - } - else - m->flags |= MOD_UNLOAD; + if (del) + m->wrapper++; + if (unload_module(m, node)) + ret = 1; + if (del) + m->wrapper--; } else if (!ops['i']) { zwarnnam(nam, "no such module %s", *args, 0); ret = 1; @@ -820,7 +951,7 @@ bin_zmodload_load(char *nam, char **args, char *ops) /* list modules */ for (node = firstnode(modules); node; incnode(node)) { m = (Module) getdata(node); - if (m->handle) { + if (m->handle && !(m->flags & MOD_UNLOAD)) { if(ops['L']) { printf("zmodload "); if(m->nam[0] == '-') @@ -835,8 +966,11 @@ bin_zmodload_load(char *nam, char **args, char *ops) } else { /* load modules */ for (; *args; args++) { + Module m; + node = find_module(*args); - if (node && ((Module) getdata(node))->handle) { + if (node && (m = ((Module) getdata(node)))->handle && + !(m->flags & MOD_UNLOAD)) { if (!ops['i']) { zwarnnam(nam, "module %s already loaded.", *args, 0); ret = 1; @@ -894,8 +1028,6 @@ getconddef(int inf, char *name, int autol) return p; } -#ifdef DYNAMIC - /* This adds the given condition definition. The return value is zero on * * success and 1 on failure. If there is a matching definition for an * * autoloaded condition, it is removed. */ @@ -909,10 +1041,11 @@ addconddef(Conddef c) if (p) { if (!p->module || (p->flags & CONDF_ADDED)) return 1; - +#ifdef DYNAMIC /* There is an autoload definition. */ deleteconddef(p); +#endif } c->next = condtab; condtab = c; @@ -942,6 +1075,8 @@ addconddefs(char const *nam, Conddef c, int size) return hadf ? hads : 1; } +#ifdef DYNAMIC + /* This adds a definition for autoloading a module for a condition. */ /**/ @@ -1014,4 +1149,4 @@ deleteconddefs(char const *nam, Conddef c, int size) return hadf ? hads : 1; } -#endif /* DYNAMIC */ +#endif diff --git a/Src/params.c b/Src/params.c index 54699476c..89a1ed6a1 100644 --- a/Src/params.c +++ b/Src/params.c @@ -301,14 +301,6 @@ copyparamtable(HashTable ht, char *name) return nht; } -#define SCANPM_WANTVALS (1<<0) -#define SCANPM_WANTKEYS (1<<1) -#define SCANPM_WANTINDEX (1<<2) /* Useful only if nested arrays */ -#define SCANPM_MATCHKEY (1<<3) -#define SCANPM_MATCHVAL (1<<4) -#define SCANPM_MATCHMANY (1<<5) -#define SCANPM_ISVAR_AT ((-1)<<15) /* Only sign bit is significant */ - static unsigned numparamvals; /**/ @@ -641,6 +633,7 @@ isident(char *s) if (!iident(*ss)) break; +#if 0 /* If this exhaust `s' or the next two characters * * are [(, then it is a valid identifier. */ if (!*ss || (*ss == '[' && ss[1] == '(')) @@ -650,6 +643,7 @@ isident(char *s) * definitely not a valid identifier. */ if (*ss != '[') return 0; + noeval = 1; (void)mathevalarg(++ss, &ss); if (*ss == ',') @@ -658,6 +652,19 @@ isident(char *s) if (*ss != ']' || ss[1]) return 0; return 1; +#else + /* If the next character is not [, then it is * + * definitely not a valid identifier. */ + if (!*ss) + return 1; + if (*ss != '[') + return 0; + + /* Require balanced [ ] pairs */ + if (skipparens('[', ']', &ss)) + return 0; + return !*ss; +#endif } static char **garr; @@ -755,6 +762,8 @@ getarg(char **str, int *inv, Value v, int a2, long *w) if (ind) { v->isarr |= SCANPM_WANTKEYS; v->isarr &= ~SCANPM_WANTVALS; + } else if (rev) { + v->isarr |= SCANPM_WANTVALS; } if (!down) v->isarr &= ~SCANPM_MATCHMANY; @@ -788,8 +797,9 @@ getarg(char **str, int *inv, Value v, int a2, long *w) v->pm = createparam(s, PM_SCALAR|PM_UNSET); paramtab = tht; } - v->isarr = 0; + v->isarr = (*inv ? SCANPM_WANTINDEX : 0); v->a = 0; + *inv = 0; /* We've already obtained the "index" (key) */ *w = v->b = -1; r = isset(KSHARRAYS) ? 1 : 0; } else @@ -979,9 +989,11 @@ getindex(char **pptr, Value v) } if (a > 0 && (isset(KSHARRAYS) || (v->pm->flags & PM_HASHED))) a--; - v->inv = 1; - v->isarr = 0; - v->a = v->b = a; + if (v->isarr != SCANPM_WANTINDEX) { + v->inv = 1; + v->isarr = 0; + v->a = v->b = a; + } if (*s == ',') { zerr("invalid subscript", NULL, 0); while (*s != ']' && *s != Outbrack) @@ -1546,35 +1558,37 @@ setaparam(char *s, char **val) /**/ Param -sethparam(char *s, char **kvarr) +sethparam(char *s, char **val) { Value v; - Param pm; - char *t; + char *t = s; if (!isident(s)) { zerr("not an identifier: %s", s, 0); - freearray(kvarr); + freearray(val); + errflag = 1; + return NULL; + } + if (strchr(s, '[')) { + freearray(val); + zerr("attempt to set slice of associative array", NULL, 0); errflag = 1; return NULL; + } else { + if (!(v = getvalue(&s, 1))) + createparam(t, PM_HASHED); + else if (!(PM_TYPE(v->pm->flags) & (PM_ARRAY|PM_HASHED)) && + !(v->pm->flags & PM_SPECIAL)) { + unsetparam(t); + createparam(t, PM_HASHED); + v = NULL; + } } - t=ztrdup(s); /* Is this a memory leak? */ - /* Why does getvalue(s, 1) set s to empty string? */ - if ((v = getvalue(&t, 1))) - if (v->pm->flags & PM_SPECIAL) { - zerr("not overriding a special: %s", s, 0); - freearray(kvarr); - errflag = 1; + if (!v) + if (!(v = getvalue(&t, 1))) return NULL; - } else - unsetparam(s); - - pm = createparam(s, PM_HASHED); - DPUTS(!pm, "BUG: parameter not created"); - - arrhashsetfn(pm, kvarr); - - return pm; + setarrvalue(v, val); + return v->pm; } /**/ diff --git a/Src/parse.c b/Src/parse.c index 9024a834e..eb8398b1a 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -1339,7 +1339,7 @@ par_cond_double(char *a, char *b) n->ntype = NT_SET(N_COND, NT_STR, NT_STR | NT_ARR, 0, 0); n->type = COND_MOD; - n->left = (void *) (a + 1); + n->left = (void *) a; d[0] = b; d[1] = NULL; n->right = (void *) arrdup(d); @@ -1386,7 +1386,7 @@ par_cond_triple(char *a, char *b, char *c) n->ntype = NT_SET(N_COND, NT_STR, NT_STR | NT_ARR, 0, 0); n->type = COND_MODI; - n->left = (void *) (b + 1); + n->left = (void *) b; d[0] = a; d[1] = c; d[2] = NULL; @@ -1397,7 +1397,7 @@ par_cond_triple(char *a, char *b, char *c) n->ntype = NT_SET(N_COND, NT_STR, NT_STR | NT_ARR, 0, 0); n->type = COND_MOD; - n->left = (void *) (a + 1); + n->left = (void *) a; d[0] = b; d[1] = c; d[2] = NULL; diff --git a/Src/signals.c b/Src/signals.c index e637a8ca9..65bac0f52 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -703,6 +703,8 @@ dotrapargs(int sig, int *sigtr, void *sigfn) execsave(); breaks = 0; if (*sigtr & ZSIG_FUNC) { + int osc = sfcontext; + PERMALLOC { args = newlinklist(); name = (char *) zalloc(5 + strlen(sigs[sig])); @@ -712,7 +714,9 @@ dotrapargs(int sig, int *sigtr, void *sigfn) addlinknode(args, num); } LASTALLOC; trapreturn = -1; + sfcontext = SFC_SIGNAL; doshfunc(name, sigfn, args, 0, 1); + sfcontext = osc; freelinklist(args, (FreeFunc) NULL); zsfree(name); } else HEAPALLOC { diff --git a/Src/subst.c b/Src/subst.c index 77f0249e2..cc7e87d3d 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -720,8 +720,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) int eval = 0; int nojoin = 0; char inbrace = 0; /* != 0 means ${...}, otherwise $... */ - char hkeys = 0; /* 1 means get keys from associative array */ - char hvals = 0; /* > hkeys get values of associative array */ + char hkeys = 0; + char hvals = 0; *s++ = '\0'; if (!ialnum(*s) && *s != '#' && *s != Pound && *s != '-' && @@ -739,7 +739,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) inbrace = 1; s++; if (*s == '!' && s[1] != Outbrace && emulation == EMULATE_KSH) { - hkeys = 1; + hkeys = SCANPM_WANTKEYS; s++; } else if (*s == '(' || *s == Inpar) { char *t, sav; @@ -762,7 +762,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) case Outpar: break; case 'A': - arrasg = 1; + ++arrasg; break; case '@': nojoin = 1; @@ -897,10 +897,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) break; case 'k': - hkeys = 1; + hkeys = SCANPM_WANTKEYS; break; case 'v': - hvals = 2; + hvals = SCANPM_WANTVALS; break; default: @@ -979,9 +979,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) *s = sav; v = (Value) NULL; } else { - /* 2 == SCANPM_WANTKEYS, 1 == SCANPM_WANTVALS, see params.c */ if (!(v = fetchvalue(&s, (unset(KSHARRAYS) || inbrace) ? 1 : -1, - (hkeys ? 2 : 0) + ((hvals > hkeys) ? 1 : 0)))) + hkeys|hvals))) vunset = 1; } while (v || ((inbrace || (unset(KSHARRAYS) && vunset)) && isbrack(*s))) { @@ -1010,7 +1009,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) if ((isarr = v->isarr)) { /* No way to get here with v->inv != 0, so getvaluearr() * * is called by getarrvalue(); needn't test PM_HASHED. */ - aval = getarrvalue(v); + if (v->isarr == SCANPM_WANTINDEX) { + isarr = v->isarr = 0; + val = dupstring(v->pm->nam); + } else + aval = getarrvalue(v); } else { if (v->pm->flags & PM_ARRAY) { int tmplen = arrlen(v->pm->gets.afn(v->pm)); @@ -1260,7 +1263,12 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) *p++ = ztrdup(*t++); } *p++ = NULL; - setaparam(idbeg, a); + if (arrasg > 1) { + Param pm = sethparam(idbeg, a); + if (pm) + aval = paramvalarr(pm->gets.hfn(pm), hkeys|hvals); + } else + setaparam(idbeg, a); } else { untokenize(val); setsparam(idbeg, ztrdup(val)); diff --git a/Src/utils.c b/Src/utils.c index af0247ebf..90da15368 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -427,7 +427,7 @@ get_username(void) cached_username = ztrdup(""); } #else /* !HAVE_GETPWUID */ - cached_uid = current_uid; + cached_uid = getuid(); #endif /* !HAVE_GETPWUID */ return cached_username; } @@ -510,16 +510,13 @@ adduserdir(char *s, char *t, int flags, int always) if ((flags & ND_USERNAME) && nameddirtab->getnode2(nameddirtab, s)) return; - /* Never hash PWD unless it was explicitly requested */ - if (!always && !strcmp(s, "PWD")) - return; - /* Normal parameter assignments generate calls to this function, * * with always==0. Unless the AUTO_NAME_DIRS option is set, we * * don't let such assignments actually create directory names. * * Instead, a reference to the parameter as a directory name can * - * cause the actual creation of the hash table entry. */ - if (!always && unset(AUTONAMEDIRS) && + * cause the actual creation of the hash table entry. Never hash * + * PWD unless it was explicitly requested (or already hashed). */ + if (!always && (unset(AUTONAMEDIRS) || !strcmp(s, "PWD")) && !nameddirtab->getnode2(nameddirtab, s)) return; @@ -633,8 +630,13 @@ preprompt(void) /* If a shell function named "precmd" exists, * * then execute it. */ - if ((list = getshfunc("precmd")) != &dummy_list) + if ((list = getshfunc("precmd")) != &dummy_list) { + int osc = sfcontext; + + sfcontext = SFC_HOOK; doshfunc("precmd", list, NULL, 0, 1); + sfcontext = osc; + } if (errflag) return; @@ -643,7 +645,11 @@ preprompt(void) * executed "periodic", then execute it now. */ if (period && (time(NULL) > lastperiodic + period) && (list = getshfunc("periodic")) != &dummy_list) { + int osc = sfcontext; + + sfcontext = SFC_HOOK; doshfunc("periodic", list, NULL, 0, 1); + sfcontext = osc; lastperiodic = time(NULL); } if (errflag) diff --git a/Src/zsh.export b/Src/zsh.export index c51699269..d8b0ddf19 100644 --- a/Src/zsh.export +++ b/Src/zsh.export @@ -23,6 +23,8 @@ closem cmdnamtab columns compctlreadptr +cond_str +cond_val coprocin coprocout countlinknodes @@ -173,6 +175,7 @@ sethparam setlimits setsparam settyinfo +sfcontext shfunctab shingetline shout diff --git a/Src/zsh.h b/Src/zsh.h index 6a962d8bf..a31a7469b 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -460,23 +460,24 @@ struct cond { #define COND_MOD 16 #define COND_MODI 17 -typedef int (*CondHandler) _((Conddef, char **)); +typedef int (*CondHandler) _((char **, int)); struct conddef { Conddef next; /* next in list */ char *name; /* the condition name */ int flags; /* see CONDF_* below */ + CondHandler handler; /* handler function */ int min; /* minimum number of strings */ int max; /* maximum number of strings */ - CondHandler handler; /* handler function */ + int condid; /* for overloading handler functions */ char *module; /* module to autoload */ }; #define CONDF_INFIX 1 #define CONDF_ADDED 2 -#define CONDDEF(name, flags, min, max, handler) \ - { NULL, name, flags, min, max, handler, NULL } +#define CONDDEF(name, flags, handler, min, max, condid) \ + { NULL, name, flags, handler, min, max, condid, NULL } struct forcmd { /* for/select */ /* Cmd->args contains list of words to loop thru */ @@ -772,6 +773,14 @@ struct shfunc { List funcdef; /* function definition */ }; +/* Shell function context types. */ + +#define SFC_DIRECT 0 /* called directly from the user */ +#define SFC_SIGNAL 1 /* signal handler */ +#define SFC_HOOK 2 /* one of the special functions */ +#define SFC_WIDGET 3 /* user defined widget */ +#define SFC_COMPLETE 4 /* called from completion code */ + /* node in list of function call wrappers */ typedef int (*WrapFunc) _((List, FuncWrap, char *)); @@ -781,13 +790,12 @@ struct funcwrap { int flags; WrapFunc handler; Module module; - int count; }; #define WRAPF_ADDED 1 #define WRAPDEF(func) \ - { NULL, 0, func, NULL, 0 } + { NULL, 0, func, NULL } /* node in builtin command hash table (builtintab) */ @@ -836,11 +844,11 @@ struct module { int flags; void *handle; LinkList deps; + int wrapper; }; #define MOD_BUSY (1<<0) -#define MOD_WRAPPER (1<<1) -#define MOD_UNLOAD (1<<2) +#define MOD_UNLOAD (1<<1) /* node used in parameter hash table (paramtab) */ @@ -890,28 +898,37 @@ struct param { #define PM_SCALAR 0 /* scalar */ #define PM_ARRAY (1<<0) /* array */ #define PM_INTEGER (1<<1) /* integer */ -#define PM_HASHED (1<<15) /* association */ +#define PM_HASHED (1<<2) /* association */ #define PM_TYPE(X) (X & (PM_SCALAR|PM_INTEGER|PM_ARRAY|PM_HASHED)) -#define PM_LEFT (1<<2) /* left justify and remove leading blanks */ -#define PM_RIGHT_B (1<<3) /* right justify and fill with leading blanks */ -#define PM_RIGHT_Z (1<<4) /* right justify and fill with leading zeros */ -#define PM_LOWER (1<<5) /* all lower case */ +#define PM_LEFT (1<<3) /* left justify and remove leading blanks */ +#define PM_RIGHT_B (1<<4) /* right justify and fill with leading blanks */ +#define PM_RIGHT_Z (1<<5) /* right justify and fill with leading zeros */ +#define PM_LOWER (1<<6) /* all lower case */ /* The following are the same since they * * both represent -u option to typeset */ -#define PM_UPPER (1<<6) /* all upper case */ -#define PM_UNDEFINED (1<<6) /* undefined (autoloaded) shell function */ - -#define PM_READONLY (1<<7) /* readonly */ -#define PM_TAGGED (1<<8) /* tagged */ -#define PM_EXPORTED (1<<9) /* exported */ -#define PM_UNIQUE (1<<10) /* remove duplicates */ -#define PM_SPECIAL (1<<11) /* special builtin parameter */ -#define PM_DONTIMPORT (1<<12) /* do not import this variable */ -#define PM_RESTRICTED (1<<13) /* cannot be changed in restricted mode */ -#define PM_UNSET (1<<14) /* has null value */ +#define PM_UPPER (1<<7) /* all upper case */ +#define PM_UNDEFINED (1<<7) /* undefined (autoloaded) shell function */ + +#define PM_READONLY (1<<8) /* readonly */ +#define PM_TAGGED (1<<9) /* tagged */ +#define PM_EXPORTED (1<<10) /* exported */ +#define PM_UNIQUE (1<<11) /* remove duplicates */ +#define PM_SPECIAL (1<<12) /* special builtin parameter */ +#define PM_DONTIMPORT (1<<13) /* do not import this variable */ +#define PM_RESTRICTED (1<<14) /* cannot be changed in restricted mode */ +#define PM_UNSET (1<<15) /* has null value */ + +/* Flags for extracting elements of arrays and associative arrays */ +#define SCANPM_WANTVALS (1<<0) +#define SCANPM_WANTKEYS (1<<1) +#define SCANPM_WANTINDEX (1<<2) +#define SCANPM_MATCHKEY (1<<3) +#define SCANPM_MATCHVAL (1<<4) +#define SCANPM_MATCHMANY (1<<5) +#define SCANPM_ISVAR_AT ((-1)<<15) /* Only sign bit is significant */ /* * Flags for doing matches inside parameter substitutions, i.e. -- cgit 1.4.1