From 40dcdf68a2368b0e889a6be5d7b6323101fcbe9f Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 28 Oct 2003 16:52:17 +0000 Subject: 19209: Rename zcalloc to zshcalloc. --- ChangeLog | 13 ++ Src/Builtins/sched.c | 2 +- Src/Modules/parameter.c | 8 +- Src/Modules/stat.c | 39 ++++- Src/Modules/zftp.c | 6 +- Src/Zle/compcore.c | 12 +- Src/Zle/compctl.c | 30 ++-- Src/Zle/complete.c | 4 +- Src/Zle/computil.c | 2 +- Src/Zle/zle_keymap.c | 160 ++++++++++++++++--- Src/Zle/zle_main.c | 160 ++++++++++++++----- Src/Zle/zle_refresh.c | 4 +- Src/Zle/zle_thingy.c | 20 ++- Src/builtin.c | 8 +- Src/exec.c | 6 +- Src/hashtable.c | 14 +- Src/hist.c | 4 +- Src/init.c | 6 +- Src/input.c | 5 +- Src/jobs.c | 2 +- Src/mem.c | 102 +++++++----- Src/module.c | 413 +++++++++++++++++++++++++++++++++++++++--------- Src/params.c | 6 +- Src/parse.c | 4 +- Src/pattern.c | 10 +- Src/prompt.c | 2 +- Src/utils.c | 16 +- 27 files changed, 789 insertions(+), 269 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5b135edab..958b52f19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2003-10-28 Peter Stephenson + + * 19209: Src/builtin.c, Src/exec.c, Src/hashtable.c, Src/hist.c, + Src/init.c, Src/input.c, Src/jobs.c, Src/mem.c, Src/module.c, + Src/params.c, Src/parse.c, Src/pattern.c, Src/prompt.c, + Src/utils.c, Src/Builtins/sched.c, Src/Modules/parameter.c, + Src/Modules/stat.c, Src/Modules/zftp.c, Src/Zle/compcore.c, + Src/Zle/compctl.c, Src/Zle/complete.c, Src/Zle/computil.c, + Src/Zle/zle_keymap.c, Src/Zle/zle_main.c, Src/Zle/zle_refresh.c, + Src/Zle/zle_thingy.c: Rename zcalloc to zshcalloc since + zcalloc is used in zlib; apparently this underlies some + of the system databases on e.g. Debian. + 2003-10-24 Clint Adams * 19201: Completion/Unix/Command/_screen: patch from diff --git a/Src/Builtins/sched.c b/Src/Builtins/sched.c index f00a0da38..4397b84c8 100644 --- a/Src/Builtins/sched.c +++ b/Src/Builtins/sched.c @@ -141,7 +141,7 @@ bin_sched(char *nam, char **argv, char *ops, int func) } /* The time has been calculated; now add the new entry to the linked list of scheduled commands. */ - sch = (struct schedcmd *) zcalloc(sizeof *sch); + sch = (struct schedcmd *) zshcalloc(sizeof *sch); sch->time = t; sch->cmd = zjoin(argv, ' ', 0); sch->next = NULL; diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c index 6e19a377e..e023ca9fe 100644 --- a/Src/Modules/parameter.c +++ b/Src/Modules/parameter.c @@ -200,7 +200,7 @@ setpmcommand(Param pm, char *value) zwarn("restricted: %s", value, 0); zsfree(value); } else { - Cmdnam cn = zcalloc(sizeof(*cn)); + Cmdnam cn = zshcalloc(sizeof(*cn)); cn->flags = HASHED; cn->u.cmd = value; @@ -231,7 +231,7 @@ setpmcommands(Param pm, HashTable ht) for (i = 0; i < ht->hsize; i++) for (hn = ht->nodes[i]; hn; hn = hn->next) { - Cmdnam cn = zcalloc(sizeof(*cn)); + Cmdnam cn = zshcalloc(sizeof(*cn)); struct value v; v.isarr = v.inv = v.start = 0; @@ -1417,7 +1417,7 @@ setpmnameddir(Param pm, char *value) if (!value) zwarn("invalid value: ''", NULL, 0); else { - Nameddir nd = (Nameddir) zcalloc(sizeof(*nd)); + Nameddir nd = (Nameddir) zshcalloc(sizeof(*nd)); nd->flags = 0; nd->dir = value; @@ -1466,7 +1466,7 @@ setpmnameddirs(Param pm, HashTable ht) if (!(val = getstrvalue(&v))) zwarn("invalid value: ''", NULL, 0); else { - Nameddir nd = (Nameddir) zcalloc(sizeof(*nd)); + Nameddir nd = (Nameddir) zshcalloc(sizeof(*nd)); nd->flags = 0; nd->dir = ztrdup(val); diff --git a/Src/Modules/stat.c b/Src/Modules/stat.c index ab4316f7b..10f7e5c9b 100644 --- a/Src/Modules/stat.c +++ b/Src/Modules/stat.c @@ -35,7 +35,7 @@ enum statnum { ST_DEV, ST_INO, ST_MODE, ST_NLINK, ST_UID, ST_GID, ST_BLKSIZE, ST_BLOCKS, ST_READLINK, ST_COUNT }; enum statflags { STF_NAME = 1, STF_FILE = 2, STF_STRING = 4, STF_RAW = 8, STF_PICK = 16, STF_ARRAY = 32, STF_GMT = 64, - STF_HASH = 128 }; + STF_HASH = 128, STF_OCTAL = 256 }; static char *statelts[] = { "device", "inode", "mode", "nlink", "uid", "gid", "rdev", "size", "atime", "mtime", "ctime", "blksize", "blocks", @@ -47,19 +47,40 @@ static void statmodeprint(mode_t mode, char *outbuf, int flags) { if (flags & STF_RAW) { - sprintf(outbuf, "%lu", (unsigned long)mode); + sprintf(outbuf, (flags & STF_OCTAL) ? "0%lo" : "%lu", + (unsigned long)mode); if (flags & STF_STRING) strcat(outbuf, " ("); } if (flags & STF_STRING) { static const char *modes = "?rwxrwxrwx"; - static const mode_t mflags[] = { S_IRUSR, S_IWUSR, S_IXUSR, - S_IRGRP, S_IWGRP, S_IXGRP, - S_IROTH, S_IWOTH, S_IXOTH }; +#ifdef __CYGWIN__ + static mode_t mflags[9] = { 0 }; +#else + static const mode_t mflags[9] = { + S_IRUSR, S_IWUSR, S_IXUSR, + S_IRGRP, S_IWGRP, S_IXGRP, + S_IROTH, S_IWOTH, S_IXOTH + }; +#endif const mode_t *mfp = mflags; char pm[11]; int i; +#ifdef __CYGWIN__ + if (mflags[0] == 0) { + mflags[0] = S_IRUSR; + mflags[1] = S_IWUSR; + mflags[2] = S_IXUSR; + mflags[3] = S_IRGRP; + mflags[4] = S_IWGRP; + mflags[5] = S_IXGRP; + mflags[6] = S_IROTH; + mflags[7] = S_IWOTH; + mflags[8] = S_IXOTH; + } +#endif + if (S_ISBLK(mode)) *pm = 'b'; else if (S_ISCHR(mode)) @@ -359,7 +380,7 @@ bin_stat(char *name, char **args, char *ops, int func) flags |= STF_PICK; } else { for (; *arg; arg++) { - if (strchr("glLnNrstT", *arg)) + if (strchr("glLnNorstT", *arg)) ops[STOUC(*arg)] = 1; else if (*arg == 'A') { if (arg[1]) { @@ -472,6 +493,8 @@ bin_stat(char *name, char **args, char *ops, int func) flags |= STF_RAW; if (ops['n']) flags |= STF_FILE; + if (ops['o']) + flags |= STF_OCTAL; if (ops['t']) flags |= STF_NAME; @@ -495,7 +518,7 @@ bin_stat(char *name, char **args, char *ops, int func) arrsize = (flags & STF_PICK) ? 1 : ST_COUNT; if (flags & STF_FILE) arrsize++; - hashptr = hash = (char **)zcalloc((arrsize+1)*2*sizeof(char *)); + hashptr = hash = (char **)zshcalloc((arrsize+1)*2*sizeof(char *)); } if (arrnam) { @@ -503,7 +526,7 @@ bin_stat(char *name, char **args, char *ops, int func) if (flags & STF_FILE) arrsize++; arrsize *= nargs; - arrptr = array = (char **)zcalloc((arrsize+1)*sizeof(char *)); + arrptr = array = (char **)zshcalloc((arrsize+1)*sizeof(char *)); } for (; ops['f'] || *args; args++) { diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index 29ae98de5..081c6e2e2 100644 --- a/Src/Modules/zftp.c +++ b/Src/Modules/zftp.c @@ -2222,7 +2222,7 @@ zftp_params(char *name, char **args, int flags) return 0; } len = arrlen(args); - newarr = (char **)zcalloc((len+1)*sizeof(char *)); + newarr = (char **)zshcalloc((len+1)*sizeof(char *)); for (aptr = args, i = 0; *aptr && !errflag; aptr++, i++) { char *str; if (**aptr == '?') @@ -2935,10 +2935,10 @@ newsession(char *nm) } if (!nptr) { - zfsess = (Zftp_session) zcalloc(sizeof(struct zftp_session)); + zfsess = (Zftp_session) zshcalloc(sizeof(struct zftp_session)); zfsess->name = ztrdup(nm); zfsess->cfd = zfsess->dfd = -1; - zfsess->params = (char **) zcalloc(sizeof(zfparams)); + zfsess->params = (char **) zshcalloc(sizeof(zfparams)); zaddlinknode(zfsessions, zfsess); zfsesscnt++; diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 3ea9e8c4c..03e5eafc7 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -616,7 +616,7 @@ callcompfunc(char *s, char *fn) untokenize(*q = ztrdup(*p)); *q = NULL; } else - compwords = (char **) zcalloc(sizeof(char *)); + compwords = (char **) zshcalloc(sizeof(char *)); compparameter = ztrdup(compparameter); compredirect = ztrdup(compredirect); @@ -2706,7 +2706,7 @@ dupmatch(Cmatch m, int nbeg, int nend) { Cmatch r; - r = (Cmatch) zcalloc(sizeof(struct cmatch)); + r = (Cmatch) zshcalloc(sizeof(struct cmatch)); r->str = ztrdup(m->str); r->ipre = ztrdup(m->ipre); @@ -2803,7 +2803,7 @@ permmatches(int last) if (g->mcount > 1) diffmatches = 1; - n = (Cmgroup) zcalloc(sizeof(struct cmgroup)); + n = (Cmgroup) zshcalloc(sizeof(struct cmgroup)); if (g->perm) { g->perm->next = NULL; @@ -2821,7 +2821,7 @@ permmatches(int last) n->num = gn++; n->flags = g->flags; n->mcount = g->mcount; - n->matches = p = (Cmatch *) zcalloc((n->mcount + 1) * sizeof(Cmatch)); + n->matches = p = (Cmatch *) zshcalloc((n->mcount + 1) * sizeof(Cmatch)); n->name = ztrdup(g->name); for (q = g->matches; *q; q++, p++) *p = dupmatch(*q, nbrbeg, nbrend); @@ -2835,9 +2835,9 @@ permmatches(int last) n->ylist = NULL; if ((n->ecount = g->ecount)) { - n->expls = ep = (Cexpl *) zcalloc((n->ecount + 1) * sizeof(Cexpl)); + n->expls = ep = (Cexpl *) zshcalloc((n->ecount + 1) * sizeof(Cexpl)); for (eq = g->expls; (o = *eq); eq++, ep++) { - *ep = e = (Cexpl) zcalloc(sizeof(struct cexpl)); + *ep = e = (Cexpl) zshcalloc(sizeof(struct cexpl)); e->count = (fi ? o->fcount : o->count); e->fcount = 0; e->str = ztrdup(o->str); diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index b4981a842..d364e09d4 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -242,7 +242,7 @@ compctlread(char *name, char **args, char *ops, char *reply) if (ops['A'] && !ops['e']) { /* the -A option means that one array is specified, instead of many parameters */ - char **p, **b = (char **)zcalloc((clwnum + 1) * sizeof(char *)); + char **p, **b = (char **)zshcalloc((clwnum + 1) * sizeof(char *)); for (i = 0, p = b; i < clwnum; p++, i++) *p = ztrdup(clwords[i]); @@ -893,7 +893,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl) cc->xor = &cc_default; } else { /* more flags follow: prepare to loop again */ - cc->xor = (Compctl) zcalloc(sizeof(*cc)); + cc->xor = (Compctl) zshcalloc(sizeof(*cc)); cc = cc->xor; memset((void *)&cct, 0, sizeof(cct)); cct.mask2 = CC_CCCONT; @@ -930,7 +930,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef) /* o keeps track of or's, m remembers the starting condition, * c is the current condition being parsed */ - o = m = c = (Compcond) zcalloc(sizeof(*c)); + o = m = c = (Compcond) zshcalloc(sizeof(*c)); /* Loop over each condition: something like 's[...][...], p[...]' */ for (t = *argv; *t;) { while (*t == ' ') @@ -1021,20 +1021,20 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef) /* Allocate space for all the arguments of the conditions */ if (c->type == CCT_POS || c->type == CCT_NUMWORDS) { - c->u.r.a = (int *)zcalloc(n * sizeof(int)); - c->u.r.b = (int *)zcalloc(n * sizeof(int)); + c->u.r.a = (int *)zshcalloc(n * sizeof(int)); + c->u.r.b = (int *)zshcalloc(n * sizeof(int)); } else if (c->type == CCT_CURSUF || c->type == CCT_CURPRE || c->type == CCT_QUOTE) - c->u.s.s = (char **)zcalloc(n * sizeof(char *)); + c->u.s.s = (char **)zshcalloc(n * sizeof(char *)); else if (c->type == CCT_RANGESTR || c->type == CCT_RANGEPAT) { - c->u.l.a = (char **)zcalloc(n * sizeof(char *)); - c->u.l.b = (char **)zcalloc(n * sizeof(char *)); + c->u.l.a = (char **)zshcalloc(n * sizeof(char *)); + c->u.l.b = (char **)zshcalloc(n * sizeof(char *)); } else { - c->u.s.p = (int *)zcalloc(n * sizeof(int)); - c->u.s.s = (char **)zcalloc(n * sizeof(char *)); + c->u.s.p = (int *)zshcalloc(n * sizeof(int)); + c->u.s.s = (char **)zshcalloc(n * sizeof(char *)); } /* Now loop over the actual arguments */ for (l = 0; *t == '['; l++, t++) { @@ -1137,17 +1137,17 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef) t++; if (*t == ',') { /* Another condition to `or' */ - o->or = c = (Compcond) zcalloc(sizeof(*c)); + o->or = c = (Compcond) zshcalloc(sizeof(*c)); o = c; t++; } else if (*t) { /* Another condition to `and' */ - c->and = (Compcond) zcalloc(sizeof(*c)); + c->and = (Compcond) zshcalloc(sizeof(*c)); c = c->and; } } /* Assign condition to current compctl */ - *next = (Compctl) zcalloc(sizeof(*cc)); + *next = (Compctl) zshcalloc(sizeof(*cc)); (*next)->cond = m; argv++; /* End of the condition; get the flags that go with it. */ @@ -1271,7 +1271,7 @@ cc_reassign(Compctl cc) */ Compctl c2; - c2 = (Compctl) zcalloc(sizeof *cc); + c2 = (Compctl) zshcalloc(sizeof *cc); c2->xor = cc->xor; c2->ext = cc->ext; c2->refc = 1; @@ -1587,7 +1587,7 @@ bin_compctl(char *name, char **argv, char *ops, int func) if ((ret = get_gmatcher(name, argv))) return ret - 1; - cc = (Compctl) zcalloc(sizeof(*cc)); + cc = (Compctl) zshcalloc(sizeof(*cc)); if (get_compctl(name, &argv, cc, 1, 0, 0)) { freecompctl(cc); return 1; diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c index 5f034a4a9..b9dc9f27a 100644 --- a/Src/Zle/complete.c +++ b/Src/Zle/complete.c @@ -686,7 +686,7 @@ restrict_range(int b, int e) e = wl; i = e - b + 1; - p = (char **) zcalloc((i + 1) * sizeof(char *)); + p = (char **) zshcalloc((i + 1) * sizeof(char *)); for (q = p, pp = compwords + b; i; i--, q++, pp++) *q = ztrdup(*pp); @@ -1158,7 +1158,7 @@ compunsetfn(Param pm, int exp) *((char **) pm->u.data) = ztrdup(""); } else if (PM_TYPE(pm->flags) == PM_ARRAY) { freearray(*((char ***) pm->u.data)); - *((char ***) pm->u.data) = zcalloc(sizeof(char *)); + *((char ***) pm->u.data) = zshcalloc(sizeof(char *)); } else if (PM_TYPE(pm->flags) == PM_HASHED) { deleteparamtable(pm->u.hash); pm->u.hash = NULL; diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index 157a179af..500ad3163 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -124,7 +124,7 @@ cd_init(char *nam, char *sep, char **args, int disp) cd_state.showd = disp; while (*args) { - *setp = set = (Cdset) zcalloc(sizeof(*set)); + *setp = set = (Cdset) zshcalloc(sizeof(*set)); setp = &(set->next); if (!(ap = get_user_var(*args))) { diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index 28203655e..9ac6dc8ed 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -86,6 +86,16 @@ struct bindstate { char *lastseq; Thingy bind; char *str; + char *prefix; + int prefixlen; +}; + +/* This structure is used when scanning for prefix bindings to remove */ + +struct remprefstate { + Keymap km; + char *prefix; + int prefixlen; }; #define BS_LIST (1<<0) @@ -146,7 +156,7 @@ createkeymapnamtab(void) static KeymapName makekeymapnamnode(Keymap keymap) { - KeymapName kmn = (KeymapName) zcalloc(sizeof(*kmn)); + KeymapName kmn = (KeymapName) zshcalloc(sizeof(*kmn)); kmn->keymap = keymap; return kmn; @@ -191,7 +201,7 @@ newkeytab(char *kmname) static Key makekeynode(Thingy t, char *str) { - Key k = (Key) zcalloc(sizeof(*k)); + Key k = (Key) zshcalloc(sizeof(*k)); k->bind = t; k->str = str; @@ -220,7 +230,7 @@ static HashTable copyto; mod_export Keymap newkeymap(Keymap tocopy, char *kmname) { - Keymap km = zcalloc(sizeof(*km)); + Keymap km = zshcalloc(sizeof(*km)); int i; km->rc = 0; @@ -834,6 +844,19 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, char *ops, ch zwarnnam(name, "keymap `%s' is protected", kmname, 0); return 1; } + if (func == 'r' && ops['p']) { + char *useq, *bseq; + int len; + struct remprefstate rps; + rps.km = km; + while ((useq = *argv++)) { + bseq = getkeystring(useq, &len, 2, NULL); + rps.prefix = metafy(bseq, len, META_USEHEAP); + rps.prefixlen = strlen(rps.prefix); + scankeymap(km, 0, scanremoveprefix, &rps); + } + return 0; + } do { char *useq = *argv, *bseq, *seq, *str; int len; @@ -878,6 +901,20 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, char *ops, ch return ret; } +/* Remove bindings for key sequences which have the given (proper) prefix. */ + +/**/ +static void +scanremoveprefix(char *seq, Thingy bind, char *str, void *magic) +{ + struct remprefstate *rps = magic; + + if (strncmp(seq, rps->prefix, rps->prefixlen) || !seq[rps->prefixlen]) + return; + + bindkey(rps->km, seq, refthingy(t_undefinedkey), NULL); +} + /* List key bindings. If an argument is given, list just that one * * binding, otherwise list the entire keymap. If the -L option is * * given, list in the form of bindkey commands. */ @@ -890,7 +927,7 @@ bin_bindkey_list(char *name, char *kmname, Keymap km, char **argv, char *ops, ch bs.flags = ops['L'] ? BS_LIST : 0; bs.kmname = kmname; - if(argv[0]) { + if(argv[0] && !ops['p']) { int len; char *seq; @@ -899,8 +936,23 @@ bin_bindkey_list(char *name, char *kmname, Keymap km, char **argv, char *ops, ch bs.flags |= BS_ALL; bs.firstseq = bs.lastseq = seq; bs.bind = keybind(km, seq, &bs.str); + bs.prefix = NULL; + bs.prefixlen = 0; bindlistout(&bs); } else { + /* empty prefix is equivalent to no prefix */ + if (ops['p'] && (!argv[0] || argv[0][0])) { + if (!argv[0]) { + zwarnnam(name, "option -p requires a prefix string", NULL, 0); + return 1; + } + bs.prefix = getkeystring(argv[0], &bs.prefixlen, 2, NULL); + bs.prefix = metafy(bs.prefix, bs.prefixlen, META_HREALLOC); + bs.prefixlen = strlen(bs.prefix); + } else { + bs.prefix = NULL; + bs.prefixlen = 0; + } bs.firstseq = ztrdup(""); bs.lastseq = ztrdup(""); bs.bind = t_undefinedkey; @@ -919,6 +971,10 @@ scanbindlist(char *seq, Thingy bind, char *str, void *magic) { struct bindstate *bs = magic; + if (bs->prefixlen && + (strncmp(seq, bs->prefix, bs->prefixlen) || !seq[bs->prefixlen])) + return; + if(bind == bs->bind && (bind || !strcmp(str, bs->str)) && ztrlen(seq) == 1 && ztrlen(bs->lastseq) == 1) { int l = bs->lastseq[1] ? @@ -1011,6 +1067,66 @@ cleanup_keymaps(void) zfree(keybuf, keybufsz); } +static char *cursorptr; + +/* utility function for termcap output routine to add to string */ + +static int +add_cursor_char(int c) +{ + *cursorptr++ = c; + return 0; +} + +/* interrogate termcap for cursor keys and add bindings to keymap */ + +/**/ +static void +add_cursor_key(Keymap km, int tccode, Thingy thingy, int defchar) +{ + char buf[2048]; + int ok = 0; + + /* + * Be careful not to try too hard with bindings for dubious or + * dysfunctional terminals. + */ + if (tccan(tccode) && !(termflags & (TERM_NOUP|TERM_BAD|TERM_UNKNOWN))) { + /* + * We can use the real termcap sequence. We need to + * persuade termcap to output `move cursor 1 char' and capture it. + */ + cursorptr = buf; + tputs(tcstr[tccode], 1, add_cursor_char); + *cursorptr = '\0'; + + /* + * Sanity checking. If the cursor key is zero-length (unlikely, + * but this is termcap we're talking about), or it's a single + * character, then we don't bind it. + */ + if (buf[0] && buf[1] && (buf[0] != Meta || buf[2])) + ok = 1; + } + if (!ok) { + /* Assume the normal VT100-like values. */ + sprintf(buf, "\33[%c", defchar); + } + bindkey(km, buf, refthingy(thingy), NULL); + + /* + * If the string looked like \e[? or \eO?, bind the other one, too. + * This is necessary to make cursor keys work on many xterms with + * both normal and application modes. + */ + if (buf[0] == '\33' && (buf[1] == '[' || buf[1] == 'O') && + buf[2] && !buf[3]) + { + buf[1] = (buf[1] == '[') ? 'O' : '['; + bindkey(km, buf, refthingy(thingy), NULL); + } +} + /* Create the default keymaps. For efficiency reasons, this function * * assigns directly to the km->first array. It knows that there are no * * prefix bindings in the way, and that it is using a simple keymap. */ @@ -1023,6 +1139,7 @@ default_bindings(void) Keymap emap = newkeymap(NULL, "emacs"); Keymap amap = newkeymap(NULL, "vicmd"); Keymap smap = newkeymap(NULL, ".safe"); + Keymap vimaps[2], kptr; char buf[3], *ed; int i; @@ -1066,25 +1183,22 @@ default_bindings(void) /* vt100 arrow keys are bound by default, for historical reasons. * * Both standard and keypad modes are supported. */ - /* vi command mode: arrow keys */ - bindkey(amap, "\33[A", refthingy(t_uplineorhistory), NULL); - bindkey(amap, "\33[B", refthingy(t_downlineorhistory), NULL); - bindkey(amap, "\33[C", refthingy(t_viforwardchar), NULL); - bindkey(amap, "\33[D", refthingy(t_vibackwardchar), NULL); - bindkey(amap, "\33OA", refthingy(t_uplineorhistory), NULL); - bindkey(amap, "\33OB", refthingy(t_downlineorhistory), NULL); - bindkey(amap, "\33OC", refthingy(t_viforwardchar), NULL); - bindkey(amap, "\33OD", refthingy(t_vibackwardchar), NULL); - - /* emacs mode: arrow keys */ - bindkey(emap, "\33[A", refthingy(t_uplineorhistory), NULL); - bindkey(emap, "\33[B", refthingy(t_downlineorhistory), NULL); - bindkey(emap, "\33[C", refthingy(t_forwardchar), NULL); - bindkey(emap, "\33[D", refthingy(t_backwardchar), NULL); - bindkey(emap, "\33OA", refthingy(t_uplineorhistory), NULL); - bindkey(emap, "\33OB", refthingy(t_downlineorhistory), NULL); - bindkey(emap, "\33OC", refthingy(t_forwardchar), NULL); - bindkey(emap, "\33OD", refthingy(t_backwardchar), NULL); + vimaps[0] = vmap; + vimaps[1] = amap; + for (i = 0; i < 2; i++) { + kptr = vimaps[i]; + /* vi command and insert modes: arrow keys */ + add_cursor_key(kptr, TCUPCURSOR, t_uplineorhistory, 'A'); + add_cursor_key(kptr, TCDOWNCURSOR, t_downlineorhistory, 'B'); + add_cursor_key(kptr, TCLEFTCURSOR, t_vibackwardchar, 'D'); + add_cursor_key(kptr, TCRIGHTCURSOR, t_viforwardchar, 'C'); + } + + /* emacs mode: arrow keys */ + add_cursor_key(emap, TCUPCURSOR, t_uplineorhistory, 'A'); + add_cursor_key(emap, TCDOWNCURSOR, t_downlineorhistory, 'B'); + add_cursor_key(emap, TCLEFTCURSOR, t_backwardchar, 'D'); + add_cursor_key(emap, TCRIGHTCURSOR, t_forwardchar, 'C'); /* emacs mode: ^X sequences */ bindkey(emap, "\30*", refthingy(t_expandword), NULL); diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index aa5086597..6156b40d0 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -76,7 +76,10 @@ mod_export Thingy lbindk, bindk; /**/ int insmode; -static int eofchar, eofsent; +/**/ +mod_export int eofchar; + +static int eofsent; static long keytimeout; #ifdef HAVE_SELECT @@ -313,6 +316,7 @@ breakread(int fd, char *buf, int n) FD_ZERO(&f); FD_SET(fd, &f); + return (select(fd + 1, (SELECT_ARG_2_T) & f, NULL, NULL, NULL) == -1 ? EOF : read(fd, buf, n)); } @@ -395,7 +399,13 @@ getkey(int keytmout) # endif #endif } - while ((r = read(SHTTY, &cc, 1)) != 1) { + for (;;) { + int q = queue_signal_level(); + dont_queue_signals(); + r = read(SHTTY, &cc, 1); + restore_queue_signals(q); + if (r == 1) + break; if (r == 0) { /* The test for IGNOREEOF was added to make zsh ignore ^Ds that were typed while commands are running. Unfortuantely @@ -556,7 +566,7 @@ zleread(char *lp, char *rp, int flags) reselectkeymap(); selectlocalmap(NULL); bindk = getkeycmd(); - if (!ll && isfirstln && c == eofchar) { + if (!ll && isfirstln && unset(IGNOREEOF) && c == eofchar) { eofsent = 1; break; } @@ -630,23 +640,36 @@ execzlefunc(Thingy func, char **args) } else if((w = func->widget)->flags & (WIDGET_INT|WIDGET_NCOMP)) { int wflags = w->flags; - if(!(wflags & ZLE_KEEPSUFFIX)) - removesuffix(); - if(!(wflags & ZLE_MENUCMP)) { - fixsuffix(); - invalidatelist(); + if (keybuf[0] == eofchar && !keybuf[1] && + !ll && isfirstln && isset(IGNOREEOF)) { + showmsg((!islogin) ? "zsh: use 'exit' to exit." : + "zsh: use 'logout' to logout."); + ret = 1; + } else { + if(!(wflags & ZLE_KEEPSUFFIX)) + removesuffix(); + if(!(wflags & ZLE_MENUCMP)) { + fixsuffix(); + invalidatelist(); + } + if (wflags & ZLE_LINEMOVE) + vilinerange = 1; + if(!(wflags & ZLE_LASTCOL)) + lastcol = -1; + if (wflags & WIDGET_NCOMP) { + int atcurhist = histline == curhist; + compwidget = w; + ret = completecall(args); + if (atcurhist) + histline = curhist; + } else { + queue_signals(); + ret = w->u.fn(args); + unqueue_signals(); + } + if (!(wflags & ZLE_NOTCOMMAND)) + lastcmd = wflags; } - if (wflags & ZLE_LINEMOVE) - vilinerange = 1; - if(!(wflags & ZLE_LASTCOL)) - lastcol = -1; - if (wflags & WIDGET_NCOMP) { - compwidget = w; - ret = completecall(args); - } else - ret = w->u.fn(args); - if (!(wflags & ZLE_NOTCOMMAND)) - lastcmd = wflags; r = 1; } else { Eprog prog = getshfunc(w->u.fnnam); @@ -735,11 +758,15 @@ bin_vared(char *name, char **args, char *ops, int func) struct value vbuf; Value v; Param pm = 0; - int create = 0, ifl; + int create = 0, ifl, ieof; int type = PM_SCALAR, obreaks = breaks, haso = 0; char *p1 = NULL, *p2 = NULL; FILE *oshout = NULL; + if ((interact && unset(USEZLE)) || !strcmp(term, "emacs")) { + zwarnnam(name, "ZLE not enabled", NULL, 0); + return 1; + } if (zleactive) { zwarnnam(name, "ZLE cannot be used recursively (yet)", NULL, 0); return 1; @@ -810,17 +837,65 @@ bin_vared(char *name, char **args, char *ops, int func) } /* handle non-existent parameter */ s = args[0]; + queue_signals(); v = fetchvalue(&vbuf, &s, (!create || type == PM_SCALAR), SCANPM_WANTKEYS|SCANPM_WANTVALS|SCANPM_MATCHMANY); if (!v && !create) { + unqueue_signals(); zwarnnam(name, "no such variable: %s", args[0], 0); return 1; } else if (v) { - s = getstrvalue(v); - pm = v->pm; + if (v->isarr) { + /* Array: check for separators and quote them. */ + char **arr = getarrvalue(v), **aptr, **tmparr, **tptr; + tptr = tmparr = (char **)zhalloc(sizeof(char *)*(arrlen(arr)+1)); + for (aptr = arr; *aptr; aptr++) { + int sepcount = 0; + /* + * See if this word contains a separator character + * or backslash + */ + for (t = *aptr; *t; t++) { + if (*t == Meta) { + if (isep(t[1] ^ 32)) + sepcount++; + t++; + } else if (isep(*t) || *t == '\\') + sepcount++; + } + if (sepcount) { + /* Yes, so allocate enough space to quote it. */ + char *newstr, *nptr; + newstr = zhalloc(strlen(*aptr)+sepcount+1); + /* Go through string quoting separators */ + for (t = *aptr, nptr = newstr; *t; ) { + if (*t == Meta) { + if (isep(t[1] ^ 32)) + *nptr++ = '\\'; + *nptr++ = *t++; + } else if (isep(*t) || *t == '\\') + *nptr++ = '\\'; + *nptr++ = *t++; + } + *nptr = '\0'; + /* Stick this into the array of words to join up */ + *tptr++ = newstr; + } else + *tptr++ = *aptr; /* No, keep original array element */ + } + *tptr = NULL; + s = sepjoin(tmparr, NULL, 0); + } else { + s = ztrdup(getstrvalue(v)); + } + unqueue_signals(); } else if (*s) { + unqueue_signals(); zwarnnam(name, "invalid parameter name: %s", args[0], 0); return 1; + } else { + unqueue_signals(); + s = ztrdup(s); } if (SHTTY == -1) { @@ -835,22 +910,23 @@ bin_vared(char *name, char **args, char *ops, int func) haso = 1; } /* edit the parameter value */ - zpushnode(bufstack, ztrdup(s)); + zpushnode(bufstack, s); varedarg = *args; ifl = isfirstln; - if (ops['e']) - isfirstln = 1; if (ops['h']) - hbegin(1); + hbegin(2); + isfirstln = ops['e']; + ieof = opts[IGNOREEOF]; + opts[IGNOREEOF] = 0; t = (char *) zleread(p1, p2, ops['h'] ? ZLRF_HISTORY : 0); + opts[IGNOREEOF] = ieof; if (ops['h']) - hend(); + hend(NULL); isfirstln = ifl; varedarg = ova; if (haso) { - close(SHTTY); - fclose(shout); + fclose(shout); /* close(SHTTY) */ shout = oshout; SHTTY = -1; } @@ -864,24 +940,27 @@ bin_vared(char *name, char **args, char *ops, int func) if (t[strlen(t) - 1] == '\n') t[strlen(t) - 1] = '\0'; /* final assignment of parameter value */ - if (create && (!pm || (type && PM_TYPE(pm->flags) != type))) { - if (pm) - unsetparam(args[0]); + if (create) { + unsetparam(args[0]); createparam(args[0], type); - pm = 0; } - if (!pm) - pm = (Param) paramtab->getnode(paramtab, args[0]); + queue_signals(); + pm = (Param) paramtab->getnode(paramtab, args[0]); if (pm && (PM_TYPE(pm->flags) & (PM_ARRAY|PM_HASHED))) { char **a; - a = spacesplit(t, 1, 0); + /* + * Use spacesplit with fourth argument 1: identify quoted separators, + * unquote but don't split. + */ + a = spacesplit(t, 1, 0, 1); if (PM_TYPE(pm->flags) == PM_ARRAY) setaparam(args[0], a); else sethparam(args[0], a); } else setsparam(args[0], t); + unqueue_signals(); return 0; } @@ -1015,9 +1094,9 @@ zleaftertrap(Hookdef dummy, void *dat) } static struct builtin bintab[] = { - BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaMldDANmrsLR", NULL), + BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaMldDANmrsLRp", NULL), BUILTIN("vared", 0, bin_vared, 1, 7, 0, NULL, NULL), - BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgGcRaU", NULL), + BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgGcRaUI", NULL), }; /* The order of the entries in this table has to match the *HOOK @@ -1040,7 +1119,6 @@ setup_(Module m) { /* Set up editor entry points */ trashzleptr = trashzle; - gotwordptr = gotword; refreshptr = zrefresh; spaceinlineptr = spaceinline; zlereadptr = zleread; @@ -1054,6 +1132,7 @@ setup_(Module m) /* miscellaneous initialisations */ stackhist = stackcs = -1; kungetbuf = (char *) zalloc(kungetsz = 32); + comprecursive = 0; /* initialise the keymap system */ init_keymaps(); @@ -1062,7 +1141,7 @@ setup_(Module m) incompfunc = incompctlfunc = hascompmod = 0; - clwords = (char **) zcalloc((clwsize = 16) * sizeof(char *)); + clwords = (char **) zshcalloc((clwsize = 16) * sizeof(char *)); return 0; } @@ -1117,7 +1196,6 @@ finish_(Module m) /* editor entry points */ trashzleptr = noop_function; - gotwordptr = noop_function; refreshptr = noop_function; spaceinlineptr = noop_function_int; zlereadptr = fallback_zleread; diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index c432907d1..68860f391 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -133,8 +133,8 @@ resetvideo(void) free(nbuf); free(obuf); } - nbuf = (char **)zcalloc((winh + 1) * sizeof(char *)); - obuf = (char **)zcalloc((winh + 1) * sizeof(char *)); + nbuf = (char **)zshcalloc((winh + 1) * sizeof(char *)); + obuf = (char **)zshcalloc((winh + 1) * sizeof(char *)); nbuf[0] = (char *)zalloc(winw + 2); obuf[0] = (char *)zalloc(winw + 2); diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c index 1d1eaacf3..f40bd18b8 100644 --- a/Src/Zle/zle_thingy.c +++ b/Src/Zle/zle_thingy.c @@ -107,7 +107,7 @@ scanemptythingies(HashNode hn, int flags) static Thingy makethingynode(void) { - Thingy t = (Thingy) zcalloc(sizeof(*t)); + Thingy t = (Thingy) zshcalloc(sizeof(*t)); t->flags = DISABLED; return t; @@ -339,6 +339,7 @@ bin_zle(char *name, char **args, char *ops, int func) { 'R', bin_zle_refresh, 0, -1 }, { 'M', bin_zle_mesg, 1, 1 }, { 'U', bin_zle_unget, 1, 1 }, + { 'I', bin_zle_invalidate, 0, 0 }, { 0, bin_zle_call, 0, -1 }, }; struct opn const *op, *opp; @@ -396,10 +397,8 @@ bin_zle_refresh(char *name, char **args, char *ops, char func) char *s = statusline; int sl = statusll, ocl = clearlist; - if (!zleactive) { - zwarnnam(name, "can only be called from widget function", NULL, 0); + if (!zleactive) return 1; - } statusline = NULL; statusll = 0; if (*args) { @@ -628,7 +627,7 @@ bin_zle_call(char *name, char **args, char *ops, char func) return 1; } if (!args[0][1]) - args++; + *++args = "" - 1; modsave = zmod; saveflag = 1; zmod.mult = atoi(num); @@ -656,6 +655,17 @@ bin_zle_call(char *name, char **args, char *ops, char func) return ret; } +/**/ +static int +bin_zle_invalidate(char *name, char **args, char *ops, char func) +{ + if (zleactive) { + trashzle(); + return 0; + } else + return 1; +} + /*******************/ /* initialiasation */ /*******************/ diff --git a/Src/builtin.c b/Src/builtin.c index c1468c6aa..bfb2f85b8 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2207,7 +2207,7 @@ bin_functions(char *name, char **argv, char *ops, int func) DPUTS(!shf->funcdef, "BUG: Calling autoload from empty function"); } else { - shf = (Shfunc) zcalloc(sizeof *shf); + shf = (Shfunc) zshcalloc(sizeof *shf); shfunctab->addnode(shfunctab, ztrdup(scriptname), shf); } shf->flags = on; @@ -2278,7 +2278,7 @@ bin_functions(char *name, char **argv, char *ops, int func) } else if (on & PM_UNDEFINED) { /* Add a new undefined (autoloaded) function to the * * hash table with the corresponding flags set. */ - shf = (Shfunc) zcalloc(sizeof *shf); + shf = (Shfunc) zshcalloc(sizeof *shf); shf->flags = on; shf->funcdef = mkautofn(shf); shfunctab->addnode(shfunctab, ztrdup(*argv), shf); @@ -2665,11 +2665,11 @@ bin_hash(char *name, char **argv, char *ops, int func) /* The argument is of the form foo=bar, * * so define an entry for the table. */ if(ops['d']) { - Nameddir nd = hn = zcalloc(sizeof *nd); + Nameddir nd = hn = zshcalloc(sizeof *nd); nd->flags = 0; nd->dir = ztrdup(asg->value); } else { - Cmdnam cn = hn = zcalloc(sizeof *cn); + Cmdnam cn = hn = zshcalloc(sizeof *cn); cn->flags = HASHED; cn->u.cmd = ztrdup(asg->value); } diff --git a/Src/exec.c b/Src/exec.c index fec58c511..81c6ac641 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -688,7 +688,7 @@ hashcmd(char *arg0, char **pp) if (!*pp) return NULL; - cn = (Cmdnam) zcalloc(sizeof *cn); + cn = (Cmdnam) zshcalloc(sizeof *cn); cn->flags = 0; cn->u.name = pp; cmdnamtab->addnode(cmdnamtab, ztrdup(arg0), cn); @@ -3358,7 +3358,7 @@ doshfunc(char *name, Eprog prog, LinkList doshargs, int flags, int noreturnval) LinkNode node; node = doshargs->first; - pparams = x = (char **) zcalloc(((sizeof *x) * + pparams = x = (char **) zshcalloc(((sizeof *x) * (1 + countlinknodes(doshargs)))); if (isset(FUNCTIONARGZERO)) { oargv0 = argzero; @@ -3368,7 +3368,7 @@ doshfunc(char *name, Eprog prog, LinkList doshargs, int flags, int noreturnval) for (; node; node = node->next, x++) *x = ztrdup((char *) node->dat); } else { - pparams = (char **) zcalloc(sizeof *pparams); + pparams = (char **) zshcalloc(sizeof *pparams); if (isset(FUNCTIONARGZERO)) { oargv0 = argzero; argzero = ztrdup(argzero); diff --git a/Src/hashtable.c b/Src/hashtable.c index 332f9479a..5c93bd0c1 100644 --- a/Src/hashtable.c +++ b/Src/hashtable.c @@ -96,7 +96,7 @@ newhashtable(int size, char const *name, PrintTableStats printinfo) { HashTable ht; - ht = (HashTable) zcalloc(sizeof *ht); + ht = (HashTable) zshcalloc(sizeof *ht); #ifdef ZSH_HASH_DEBUG ht->next = NULL; if(!firstht) @@ -108,7 +108,7 @@ newhashtable(int size, char const *name, PrintTableStats printinfo) ht->printinfo = printinfo ? printinfo : printhashtabinfo; ht->tablename = ztrdup(name); #endif /* ZSH_HASH_DEBUG */ - ht->nodes = (HashNode *) zcalloc(size * sizeof(HashNode)); + ht->nodes = (HashNode *) zshcalloc(size * sizeof(HashNode)); ht->hsize = size; ht->ct = 0; ht->scan = NULL; @@ -458,7 +458,7 @@ expandhashtable(HashTable ht) onodes = ht->nodes; ht->hsize = osize * 4; - ht->nodes = (HashNode *) zcalloc(ht->hsize * sizeof(HashNode)); + ht->nodes = (HashNode *) zshcalloc(ht->hsize * sizeof(HashNode)); ht->ct = 0; /* scan through the old list of nodes, and * @@ -496,7 +496,7 @@ resizehashtable(HashTable ht, int newsize) * we free it and allocate a new nodes array. */ if (ht->hsize != newsize) { zfree(ht->nodes, ht->hsize * sizeof(HashNode)); - ht->nodes = (HashNode *) zcalloc(newsize * sizeof(HashNode)); + ht->nodes = (HashNode *) zshcalloc(newsize * sizeof(HashNode)); ht->hsize = newsize; } else { /* else we just re-zero the current nodes array */ @@ -639,7 +639,7 @@ hashdir(char **dirp) while ((fn = zreaddir(dir, 1))) { if (!cmdnamtab->getnode(cmdnamtab, fn)) { - cn = (Cmdnam) zcalloc(sizeof *cn); + cn = (Cmdnam) zshcalloc(sizeof *cn); cn->flags = 0; cn->u.name = dirp; cmdnamtab->addnode(cmdnamtab, ztrdup(fn), cn); @@ -654,7 +654,7 @@ hashdir(char **dirp) (exe[3] == 'E' || exe[3] == 'e') && exe[4] == 0) { *exe = 0; if (!cmdnamtab->getnode(cmdnamtab, fn)) { - cn = (Cmdnam) zcalloc(sizeof *cn); + cn = (Cmdnam) zshcalloc(sizeof *cn); cn->flags = 0; cn->u.name = dirp; cmdnamtab->addnode(cmdnamtab, ztrdup(fn), cn); @@ -1048,7 +1048,7 @@ createaliasnode(char *txt, int flags) { Alias al; - al = (Alias) zcalloc(sizeof *al); + al = (Alias) zshcalloc(sizeof *al); al->flags = flags; al->text = txt; al->inuse = 0; diff --git a/Src/hist.c b/Src/hist.c index 57e429a7d..e40007049 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -771,7 +771,7 @@ hbegin(int dohist) hwend = nohwe; addtoline = nohw; } else { - chline = hptr = zcalloc(hlinesz = 64); + chline = hptr = zshcalloc(hlinesz = 64); chwords = zalloc((chwordlen = 64) * sizeof(short)); hgetc = ihgetc; hungetc = ihungetc; @@ -933,7 +933,7 @@ prepnexthistent(void) } if (histlinect < histsiz) { - he = (Histent)zcalloc(sizeof *he); + he = (Histent)zshcalloc(sizeof *he); if (!hist_ring) hist_ring = he->up = he->down = he; else { diff --git a/Src/init.c b/Src/init.c index d2f8ec591..291351b9d 100644 --- a/Src/init.c +++ b/Src/init.c @@ -325,7 +325,7 @@ parseargs(char **argv) if(isset(SINGLECOMMAND)) opts[INTERACTIVE] &= 1; opts[INTERACTIVE] = !!opts[INTERACTIVE]; - pparams = x = (char **) zcalloc((countlinknodes(paramlist) + 1) * sizeof(char *)); + pparams = x = (char **) zshcalloc((countlinknodes(paramlist) + 1) * sizeof(char *)); while ((*x++ = (char *)getlinknode(paramlist))); free(paramlist); @@ -1191,9 +1191,9 @@ zsh_main(int argc, char **argv) break; } while (zsh_name); - /* Not zopenmax() here: it may return a number too big for zcalloc(). */ + /* Not zopenmax() here: it may return a number too big for zshcalloc(). */ fdtable_size = 256; /* This grows as necessary, see utils.c:movefd(). */ - fdtable = zcalloc(fdtable_size); + fdtable = zshcalloc(fdtable_size); createoptiontable(); emulate(zsh_name, 1); /* initialises most options */ diff --git a/Src/input.c b/Src/input.c index f90ac7b00..525a3202a 100644 --- a/Src/input.c +++ b/Src/input.c @@ -273,9 +273,6 @@ inputline(void) free(ingetcline); return lexstop = errflag = 1; } - /* Look for a space, to see if this shouldn't be put into history */ - if (isfirstln) - spaceflag = *ingetcline == ' '; if (isset(VERBOSE)) { /* Output the whole line read so far. */ zputs(ingetcline, stderr); @@ -374,7 +371,7 @@ inungetc(int c) * can't back up where we want to. Instead, we just push it * onto the input stack as an extra character. */ - char *cback = (char *)zcalloc(2); + char *cback = (char *)zshcalloc(2); cback[0] = (char) c; inpush(cback, INP_FREE|INP_CONT, NULL); } diff --git a/Src/jobs.c b/Src/jobs.c index c0f43b503..120e4a8e6 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -815,7 +815,7 @@ addproc(pid_t pid, char *text) Process pn; struct timezone dummy_tz; - pn = (Process) zcalloc(sizeof *pn); + pn = (Process) zshcalloc(sizeof *pn); pn->pid = pid; if (text) strcpy(pn->text, text); diff --git a/Src/mem.c b/Src/mem.c index cea3cec19..83c784165 100644 --- a/Src/mem.c +++ b/Src/mem.c @@ -32,7 +32,7 @@ /* There are two ways to allocate memory in zsh. The first way is - to call zalloc/zcalloc, which call malloc/calloc directly. It + to call zalloc/zshcalloc, which call malloc/calloc directly. It is legal to call realloc() or free() on memory allocated this way. The second way is to call zhalloc/hcalloc, which allocates memory from one of the memory pools on the heap stack. Such memory pools @@ -105,7 +105,8 @@ union mem_align { static Heap heaps; -/* first heap with free space, not always correct */ +/* a heap with free space, not always correct (it will be the last heap + * if that was newly allocated but it may also be another one) */ static Heap fheap; @@ -115,9 +116,13 @@ static Heap fheap; mod_export Heap new_heaps(void) { - Heap h = heaps; + Heap h; + + queue_signals(); + h = heaps; fheap = heaps = NULL; + unqueue_signals(); return h; } @@ -130,6 +135,7 @@ old_heaps(Heap old) { Heap h, n; + queue_signals(); for (h = heaps; h; h = n) { n = h->next; DPUTS(h->sp, "BUG: old_heaps() with pushed heaps"); @@ -141,6 +147,7 @@ old_heaps(Heap old) } heaps = old; fheap = NULL; + unqueue_signals(); } /* Temporarily switch to other heaps (or back again). */ @@ -149,10 +156,14 @@ old_heaps(Heap old) mod_export Heap switch_heaps(Heap new) { - Heap h = heaps; + Heap h; + + queue_signals(); + h = heaps; heaps = new; fheap = NULL; + unqueue_signals(); return h; } @@ -166,6 +177,8 @@ pushheap(void) Heap h; Heapstack hs; + queue_signals(); + #if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG) h_push++; #endif @@ -177,6 +190,7 @@ pushheap(void) h->sp = hs; hs->used = h->used; } + unqueue_signals(); } /* reset heaps to previous state */ @@ -187,6 +201,8 @@ freeheap(void) { Heap h, hn, hl = NULL; + queue_signals(); + #if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG) h_free++; #endif @@ -214,6 +230,8 @@ freeheap(void) hl->next = NULL; else heaps = NULL; + + unqueue_signals(); } /* reset heap to previous state and destroy state information */ @@ -225,6 +243,8 @@ popheap(void) Heap h, hn, hl = NULL; Heapstack hs; + queue_signals(); + #if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG) h_pop++; #endif @@ -255,6 +275,8 @@ popheap(void) hl->next = NULL; else heaps = NULL; + + unqueue_signals(); } /* allocate memory from the current memory pool */ @@ -268,16 +290,23 @@ zhalloc(size_t size) size = (size + H_ISIZE - 1) & ~(H_ISIZE - 1); + queue_signals(); + #if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG) h_m[size < (1024 * H_ISIZE) ? (size / H_ISIZE) : 1024]++; #endif /* find a heap with enough free space */ - for (h = (fheap ? fheap : heaps); h; h = h->next) { + for (h = ((fheap && HEAP_ARENA_SIZE >= (size + fheap->used)) ? fheap : heaps); + h; h = h->next) { if (HEAP_ARENA_SIZE >= (n = size + h->used)) { + void *ret; + h->used = n; - return arena(h) + n - size; + ret = arena(h) + n - size; + unqueue_signals(); + return ret; } } { @@ -289,7 +318,6 @@ zhalloc(size_t size) /* tricky, see above */ #endif - queue_signals(); n = HEAP_ARENA_SIZE > size ? HEAPSIZE : size + sizeof(*h); for (hp = NULL, h = heaps; h; hp = h, h = h->next); @@ -338,7 +366,7 @@ zhalloc(size_t size) hp->next = h; else heaps = h; - fheap = NULL; + fheap = h; unqueue_signals(); return arena(h); @@ -361,6 +389,7 @@ hrealloc(char *p, size_t old, size_t new) /* find the heap with p */ + queue_signals(); for (h = heaps, ph = NULL; h; ph = h, h = h->next) if (p >= arena(h) && p < arena(h) + HEAP_ARENA_SIZE) break; @@ -376,9 +405,12 @@ hrealloc(char *p, size_t old, size_t new) #ifdef ZSH_MEM_DEBUG memset(p, 0xff, old); #endif + unqueue_signals(); return ptr; - } else + } else { + unqueue_signals(); return new ? p : NULL; + } } DPUTS(p + old != arena(h) + h->used, "BUG: hrealloc more than allocated"); @@ -395,6 +427,7 @@ hrealloc(char *p, size_t old, size_t new) #else zfree(h, HEAPSIZE); #endif + unqueue_signals(); return NULL; } #ifndef USE_MMAP @@ -407,6 +440,7 @@ hrealloc(char *p, size_t old, size_t new) heaps = h = (Heap) realloc(h, n); } h->used = new; + unqueue_signals(); return arena(h); #endif } @@ -415,6 +449,7 @@ hrealloc(char *p, size_t old, size_t new) #endif if (h->used + (new - old) <= HEAP_ARENA_SIZE) { h->used += new - old; + unqueue_signals(); return p; } else { char *t = zhalloc(new); @@ -423,6 +458,7 @@ hrealloc(char *p, size_t old, size_t new) #ifdef ZSH_MEM_DEBUG memset(p, 0xff, old); #endif + unqueue_signals(); return t; } } @@ -450,26 +486,30 @@ zalloc(size_t size) if (!size) size = 1; + queue_signals(); if (!(ptr = (void *) malloc(size))) { zerr("fatal error: out of memory", NULL, 0); exit(1); } + unqueue_signals(); return ptr; } /**/ mod_export void * -zcalloc(size_t size) +zshcalloc(size_t size) { void *ptr; if (!size) size = 1; + queue_signals(); if (!(ptr = (void *) malloc(size))) { zerr("fatal error: out of memory", NULL, 0); exit(1); } + unqueue_signals(); memset(ptr, 0, size); return ptr; @@ -485,6 +525,7 @@ zcalloc(size_t size) mod_export void * zrealloc(void *ptr, size_t size) { + queue_signals(); if (ptr) { if (size) { /* Do normal realloc */ @@ -492,44 +533,22 @@ zrealloc(void *ptr, size_t size) zerr("fatal error: out of memory", NULL, 0); exit(1); } + unqueue_signals(); return ptr; } else /* If ptr is not NULL, but size is zero, * * then object pointed to is freed. */ free(ptr); + + ptr = NULL; } else { /* If ptr is NULL, then behave like malloc */ - return malloc(size); + ptr = malloc(size); } + unqueue_signals(); - return NULL; -} - -/**/ -mod_export char * -dupstring(const char *s) -{ - char *t; - - if (!s) - return NULL; - t = (char *) zhalloc(strlen((char *)s) + 1); - strcpy(t, s); - return t; -} - -/**/ -mod_export char * -ztrdup(const char *s) -{ - char *t; - - if (!s) - return NULL; - t = (char *)zalloc(strlen((char *)s) + 1); - strcpy(t, s); - return t; + return ptr; } /**/ @@ -1118,7 +1137,12 @@ zfree(void *p, int sz) long n = (m_lfree->len - M_MIN - M_KEEP) & ~(m_pgsz - 1); m_lfree->len -= n; +#ifdef HAVE_BRK if (brk(m_high -= n) == -1) { +#else + m_high -= n; + if (sbrk(-n) == (void *)-1) { +#endif /* HAVE_BRK */ DPUTS(1, "MEM: allocation error at brk."); } @@ -1221,6 +1245,7 @@ bin_mem(char *name, char **argv, char *ops, int func) char *b, *c, buf[40]; long u = 0, f = 0, to, cu; + queue_signals(); if (ops['v']) { printf("The lower and the upper addresses of the heap. Diff gives\n"); printf("the difference between them, i.e. the size of the heap.\n\n"); @@ -1349,6 +1374,7 @@ bin_mem(char *name, char **argv, char *ops, int func) if (h_m[1024]) printf("big\t%d\n", h_m[1024]); + unqueue_signals(); return 0; } diff --git a/Src/module.c b/Src/module.c index 63e0dc2f6..e943fb397 100644 --- a/Src/module.c +++ b/Src/module.c @@ -88,6 +88,27 @@ register_module(char *n, Module_func setup, Module_func boot, zaddlinknode(linkedmodules, m); } +/* Print an alias. */ + +/**/ +static void +printmodalias(Module m, char *ops) +{ + if (ops['L']) { + printf("zmodload -A "); + if (m->nam[0] == '-') + fputs("-- ", stdout); + quotedzputs(m->nam, stdout); + putchar('='); + quotedzputs(m->u.alias, stdout); + } else { + nicezputs(m->nam, stdout); + fputs(" -> ", stdout); + nicezputs(m->u.alias, stdout); + } + putchar('\n'); +} + /* Check if a module is linked in. */ /**/ @@ -164,6 +185,15 @@ addwrapper(Module m, FuncWrap w) { FuncWrap p, q; + /* + * We can't add a wrapper to an alias, since it's supposed + * to behave identically to the resolved module. This shouldn't + * happen since we usually add wrappers when a real module is + * loaded. + */ + if (m->flags & MOD_ALIAS) + return 1; + if (w->flags & WRAPF_ADDED) return 1; for (p = wrappers, q = NULL; p; q = p, p = p->next); @@ -196,7 +226,7 @@ mod_export LinkList modules; int add_autobin(char *nam, char *module) { - Builtin bn = zcalloc(sizeof(*bn)); + Builtin bn = zshcalloc(sizeof(*bn)); bn->nam = ztrdup(nam); bn->optstr = ztrdup(module); return addbuiltin(bn); @@ -256,6 +286,9 @@ deletewrapper(Module m, FuncWrap w) { FuncWrap p, q; + if (m->flags & MOD_ALIAS) + return 1; + if (w->flags & WRAPF_ADDED) { for (p = wrappers, q = NULL; p && p != w; q = p, p = p->next); @@ -292,7 +325,8 @@ load_and_bind(const char *fn) int err = loadbind(0, (void *) addbuiltin, ret); for (node = firstnode(modules); !err && node; incnode(node)) { Module m = (Module) getdata(node); - if (m->u.handle && !(m->flags & MOD_LINKED)) + if (!(m->flags & MOD_ALIAS) && + m->u.handle && !(m->flags & MOD_LINKED)) err |= loadbind(0, m->u.handle, ret); } @@ -431,21 +465,78 @@ do_load_module(char const *name) /**/ #endif /* !DYNAMIC */ +/* + * Find a module in the list. + * If aliasp is non-zero, resolve any aliases to the underlying module. + * If namep is set, this is set to point to the last alias value resolved, + * even if that module was not loaded. or the module name if no aliases. + * Hence this is always the physical module to load in a chain of aliases. + * Return NULL if the module named is not stored as a structure, or if we were + * resolving aliases and the final module named is not stored as a + * structure. + * + * TODO: now we have aliases, there may be some merit in using a hash + * table instead of a linked list. + */ /**/ static LinkNode -find_module(const char *name) +find_module(const char *name, int aliasp, const char **namep) { Module m; LinkNode node; for (node = firstnode(modules); node; incnode(node)) { m = (Module) getdata(node); - if (!strcmp(m->nam, name)) + if (!strcmp(m->nam, name)) { + if (aliasp && (m->flags & MOD_ALIAS)) { + if (namep) + *namep = m->u.alias; + return find_module(m->u.alias, 1, namep); + } + if (namep) + *namep = m->nam; return node; + } } return NULL; } +/* + * Unlink and free a module node from the linked list. + */ + +/**/ +static void +delete_module(LinkNode node) +{ + Module m = (Module) remnode(modules, node); + + if (m->flags & MOD_ALIAS) + zsfree(m->u.alias); + zsfree(m->nam); + if (m->deps) + freelinklist(m->deps, freestr); + zfree(m, sizeof(*m)); +} + +/**/ +mod_export int +module_loaded(const char *name) +{ + LinkNode node; + Module m; + + return ((node = find_module(name, 1, NULL)) && + (m = ((Module) getdata(node)))->u.handle && + !(m->flags & MOD_UNLOAD)); +} + +/* + * Setup and cleanup functions: we don't search for aliases here, + * since they should have been resolved before we try to load or unload + * the module. + */ + /**/ #ifdef DYNAMIC @@ -654,7 +745,7 @@ modname_ok(char const *p) } /**/ -int +mod_export int load_module(char const *name) { Module m; @@ -667,11 +758,19 @@ load_module(char const *name) zerr("invalid module name `%s'", name, 0); return 0; } - if (!(node = find_module(name))) { + /* + * The following function call may alter name to the final name in a + * chain of aliases. This makes sure the actual module loaded + * is the right one. + */ + queue_signals(); + if (!(node = find_module(name, 1, &name))) { if (!(linked = module_linked(name)) && - !(handle = do_load_module(name))) + !(handle = do_load_module(name))) { + unqueue_signals(); return 0; - m = zcalloc(sizeof(*m)); + } + m = zshcalloc(sizeof(*m)); m->nam = ztrdup(name); if (handle) { m->u.handle = handle; @@ -685,23 +784,26 @@ load_module(char const *name) if ((set = setup_module(m)) || boot_module(m)) { if (!set) finish_module(m); - remnode(modules, node); - zsfree(m->nam); - zfree(m, sizeof(*m)); - m->flags &= ~MOD_SETUP; + delete_module(node); + unqueue_signals(); return 0; } m->flags |= MOD_INIT_S | MOD_INIT_B; m->flags &= ~MOD_SETUP; + unqueue_signals(); return 1; } m = (Module) getdata(node); - if (m->flags & MOD_SETUP) + if (m->flags & MOD_SETUP) { + unqueue_signals(); return 1; + } if (m->flags & MOD_UNLOAD) m->flags &= ~MOD_UNLOAD; - else if ((m->flags & MOD_LINKED) ? m->u.linked : m->u.handle) + else if ((m->flags & MOD_LINKED) ? m->u.linked : m->u.handle) { + unqueue_signals(); return 1; + } if (m->flags & MOD_BUSY) { zerr("circular dependencies for module %s", name, 0); return 0; @@ -711,14 +813,17 @@ load_module(char const *name) for (n = firstnode(m->deps); n; incnode(n)) if (!load_module((char *) getdata(n))) { m->flags &= ~MOD_BUSY; + unqueue_signals(); return 0; } m->flags &= ~MOD_BUSY; if (!m->u.handle) { handle = NULL; if (!(linked = module_linked(name)) && - !(handle = do_load_module(name))) + !(handle = do_load_module(name))) { + unqueue_signals(); return 0; + } if (handle) { m->u.handle = handle; m->flags |= MOD_SETUP; @@ -732,6 +837,7 @@ load_module(char const *name) else m->u.linked = NULL; m->flags &= ~MOD_SETUP; + unqueue_signals(); return 0; } m->flags |= MOD_INIT_S; @@ -744,10 +850,12 @@ load_module(char const *name) else m->u.handle = NULL; m->flags &= ~MOD_SETUP; + unqueue_signals(); return 0; } m->flags |= MOD_INIT_B; m->flags &= ~MOD_SETUP; + unqueue_signals(); return 1; } @@ -761,38 +869,50 @@ load_module(char const *name) /**/ mod_export int -require_module(char *nam, char *module, int res, int test) +require_module(char *nam, const char *module, int res, int test) { Module m = NULL; LinkNode node; + int ret = 1; - /* First see if the module is linked in. */ - for (node = firstnode(linkedmodules); node; incnode(node)) { - if (!strcmp((char *) getdata(node), nam)) - return 1; - } - node = find_module(module); + /* Resolve aliases and actual loadable module as for load_module */ + queue_signals(); + node = find_module(module, 1, &module); if (node && (m = ((Module) getdata(node)))->u.handle && !(m->flags & MOD_UNLOAD)) { if (test) { + unqueue_signals(); zwarnnam(nam, "module %s already loaded.", module, 0); return 0; } } else - return load_module(module); + ret = load_module(module); + unqueue_signals(); - return 1; + return ret; } /**/ void -add_dep(char *name, char *from) +add_dep(const char *name, char *from) { LinkNode node; Module m; - if (!(node = find_module(name))) { - m = zcalloc(sizeof(*m)); + /* + * If we were passed an alias, we must resolve it to a final + * module name (and maybe add the corresponding struct), since otherwise + * we would need to check all modules to see if they happen + * to be aliased to the same thing to implement depencies properly. + * + * This should mean that an attempt to add an alias which would + * have the same name as a module which has dependencies is correctly + * rejected, because then the module named already exists as a non-alias. + * Better make sure. (There's no problem making a an alias which + * *points* to a module with dependencies, of course.) + */ + if (!(node = find_module(name, 1, &name))) { + m = zshcalloc(sizeof(*m)); m->nam = ztrdup(name); zaddlinknode(modules, m); } else @@ -838,12 +958,23 @@ autoloadscan(HashNode hn, int printflags) int bin_zmodload(char *nam, char **args, char *ops, int func) { - if ((ops['b'] || ops['c'] || ops['p'] || ops['f']) && - !(ops['a'] || ops['u'])) { + int ops_bcpf = ops['b'] || ops['c'] || ops['p'] || ops['f']; + int ops_au = ops['a'] || ops['u']; + int ret = 1; + + if (ops_bcpf && !ops_au) { zwarnnam(nam, "-b, -c, -f, and -p must be combined with -a or -u", NULL, 0); return 1; } + if (ops['A'] || ops['R']) { + if (ops_bcpf || ops_au || ops['d'] || (ops['R'] && ops['e'])) { + zwarnnam(nam, "illegal flags combined with -A or -R", NULL, 0); + return 1; + } + if (!ops['e']) + return bin_zmodload_alias(nam, args, ops); + } if (ops['d'] && ops['a']) { zwarnnam(nam, "-d cannot be combined with -a", NULL, 0); return 1; @@ -857,24 +988,137 @@ bin_zmodload(char *nam, char **args, char *ops, int func) zwarnnam(nam, "-e cannot be combined with other options", NULL, 0); return 1; } + queue_signals(); if (ops['e']) - return bin_zmodload_exist(nam, args, ops); + ret = bin_zmodload_exist(nam, args, ops); else if (ops['d']) - return bin_zmodload_dep(nam, args, ops); + ret = bin_zmodload_dep(nam, args, ops); else if ((ops['a'] || ops['b']) && !(ops['c'] || ops['p'] || ops['f'])) - return bin_zmodload_auto(nam, args, ops); + ret = bin_zmodload_auto(nam, args, ops); else if (ops['c'] && !(ops['b'] || ops['p'])) - return bin_zmodload_cond(nam, args, ops); + ret = bin_zmodload_cond(nam, args, ops); else if (ops['f'] && !(ops['b'] || ops['p'])) - return bin_zmodload_math(nam, args, ops); + ret = bin_zmodload_math(nam, args, ops); else if (ops['p'] && !(ops['b'] || ops['c'])) - return bin_zmodload_param(nam, args, ops); + ret = bin_zmodload_param(nam, args, ops); else if (!(ops['a'] || ops['b'] || ops['c'] || ops['p'])) - return bin_zmodload_load(nam, args, ops); + ret = bin_zmodload_load(nam, args, ops); else zwarnnam(nam, "use only one of -b, -c, or -p", NULL, 0); + unqueue_signals(); - return 1; + return ret; +} + +/**/ +static int +bin_zmodload_alias(char *nam, char **args, char *ops) +{ + /* + * TODO: while it would be too nasty to have aliases, as opposed + * to real loadable modules, with dependencies --- just what would + * we need to load when, exactly? --- there is in principle no objection + * to making it possible to force an alias onto an existing unloaded + * module which has dependencies. This would simply transfer + * the dependencies down the line to the aliased-to module name. + * This is actually useful, since then you can alias zsh/zle=mytestzle + * to load another version of zle. But then what happens when the + * alias is removed? Do you transfer the dependencies back? And + * suppose other names are aliased to the same file? It might be + * kettle of fish best left unwormed. + */ + LinkNode node; + Module m; + int ret = 0; + + if (!*args) { + if (ops['R']) { + zwarnnam(nam, "no module alias to remove", NULL, 0); + return 1; + } + for (node = firstnode(modules); node; incnode(node)) { + m = (Module) getdata(node); + if (m->flags & MOD_ALIAS) + printmodalias(m, ops); + } + return 0; + } + + for (; !ret && *args; args++) { + char *eqpos = strchr(*args, '='); + char *aliasname = eqpos ? eqpos+1 : NULL; + if (eqpos) + *eqpos = '\0'; + if (!modname_ok(*args)) { + zwarnnam(nam, "invalid module name `%s'", *args, 0); + return 1; + } + if (ops['R']) { + if (aliasname) { + zwarnnam(nam, "bad syntax for removing module alias: %s", + *args, 0); + return 1; + } + node = find_module(*args, 0, NULL); + if (node) { + m = (Module) getdata(node); + if (!(m->flags & MOD_ALIAS)) { + zwarnnam(nam, "module is not an alias: %s", *args, 0); + ret = 1; + break; + } + delete_module(node); + } else { + zwarnnam(nam, "no such module alias: %s", *args, 0); + return 1; + } + } else { + if (aliasname) { + const char *mname = aliasname; + if (!modname_ok(aliasname)) { + zwarnnam(nam, "invalid module name `%s'", aliasname, 0); + return 1; + } + find_module(aliasname, 1, &mname); + if (!strcmp(mname, *args)) { + zwarnnam(nam, "module alias would refer to itself: %s", + *args, 0); + return 1; + } + node = find_module(*args, 0, NULL); + if (node) { + m = (Module) getdata(node); + if (!(m->flags & MOD_ALIAS)) { + zwarnnam(nam, "module is not an alias: %s", *args, 0); + return 1; + } + zsfree(m->u.alias); + } else { + m = (Module) zshcalloc(sizeof(*m)); + m->nam = ztrdup(*args); + m->flags = MOD_ALIAS; + zaddlinknode(modules, m); + } + m->u.alias = ztrdup(aliasname); + } else { + if ((node = find_module(*args, 0, NULL))) { + m = (Module) getdata(node); + if (m->flags & MOD_ALIAS) + printmodalias(m, ops); + else { + zwarnnam(nam, "module is not an alias: %s", + *args, 0); + return 1; + } + } else { + zwarnnam(nam, "no such module alias: %s", *args, 0); + return 1; + } + } + } + } + + return 0; } /**/ @@ -883,28 +1127,33 @@ bin_zmodload_exist(char *nam, char **args, char *ops) { LinkNode node; Module m; + char *modname; if (!*args) { for (node = firstnode(modules); node; incnode(node)) { m = (Module) getdata(node); + modname = m->nam; + if (m->flags & MOD_ALIAS) { + LinkNode node2; + if (ops['A'] && (node2 = find_module(m->u.alias, 1, NULL))) + m = (Module) getdata(node2); + else + continue; + } if (m->u.handle && !(m->flags & MOD_UNLOAD)) { - nicezputs(m->nam, stdout); + nicezputs(modname, stdout); putchar('\n'); } } return 0; } else { - int ret = 0, f; + int ret = 0; for (; !ret && *args; args++) { - f = 0; - for (node = firstnode(modules); - !f && node; incnode(node)) { - m = (Module) getdata(node); - if (m->u.handle && !(m->flags & MOD_UNLOAD)) - f = !strcmp(*args, m->nam); - } - ret = !f; + if (!(node = find_module(*args, 1, NULL)) + || !(m = (Module) getdata(node))->u.handle + || (m->flags & MOD_UNLOAD)) + ret = 1; } return ret; } @@ -916,23 +1165,24 @@ bin_zmodload_dep(char *nam, char **args, char *ops) { LinkNode node; Module m; - if(ops['u']) { - /* remove dependencies */ - char *tnam = *args++; - node = find_module(tnam); + if (ops['u']) { + /* remove dependencies, which can't pertain to aliases */ + const char *tnam = *args++; + node = find_module(tnam, 1, &tnam); if (!node) return 0; m = (Module) getdata(node); - if(*args && m->deps) { + if (*args && m->deps) { do { - for(node = firstnode(m->deps); node; incnode(node)) - if(!strcmp(*args, getdata(node))) { - zsfree(getdata(node)); - remnode(m->deps, node); + LinkNode dnode; + for (dnode = firstnode(m->deps); dnode; incnode(dnode)) + if (!strcmp(*args, getdata(dnode))) { + zsfree(getdata(dnode)); + remnode(m->deps, dnode); break; } } while(*++args); - if(empty(m->deps)) { + if (empty(m->deps)) { freelinklist(m->deps, freestr); m->deps = NULL; } @@ -942,19 +1192,16 @@ bin_zmodload_dep(char *nam, char **args, char *ops) m->deps = NULL; } } - if (!m->deps && !m->u.handle) { - remnode(modules, node); - zsfree(m->nam); - zfree(m, sizeof(*m)); - } + if (!m->deps && !m->u.handle) + delete_module(node); return 0; - } else if(!args[0] || !args[1]) { + } else if (!args[0] || !args[1]) { /* list dependencies */ for (node = firstnode(modules); node; incnode(node)) { m = (Module) getdata(node); if (m->deps && (!args[0] || !strcmp(args[0], m->nam))) { LinkNode n; - if(ops['L']) { + if (ops['L']) { printf("zmodload -d "); if(m->nam[0] == '-') fputs("-- ", stdout); @@ -979,7 +1226,7 @@ bin_zmodload_dep(char *nam, char **args, char *ops) int ret = 0; char *tnam = *args++; - for(; *args; args++) + for (; *args; args++) add_dep(tnam, *args); return ret; } @@ -1099,7 +1346,7 @@ bin_zmodload_math(char *nam, char **args, char *ops) int ret = 0; if (ops['u']) { - /* remove autoloaded conditions */ + /* remove autoloaded math functions */ for (; *args; args++) { MathFunc f = getmathfunc(*args, 0); @@ -1108,7 +1355,7 @@ bin_zmodload_math(char *nam, char **args, char *ops) zwarnnam(nam, "%s: no such math function", *args, 0); ret = 1; } - } else if (f->flags & CONDF_ADDED) { + } else if (f->flags & MFF_ADDED) { zwarnnam(nam, "%s: math function is already defined", *args, 0); ret = 1; } else @@ -1130,7 +1377,7 @@ bin_zmodload_math(char *nam, char **args, char *ops) } return 0; } else { - /* add autoloaded conditions */ + /* add autoloaded math functions */ char *modnam; modnam = *args++; @@ -1209,6 +1456,15 @@ bin_zmodload_param(char *nam, char **args, char *ops) int unload_module(Module m, LinkNode node) { + /* + * Only unload the real module, so resolve aliases. + */ + if (m->flags & MOD_ALIAS) { + LinkNode node = find_module(m->u.alias, 1, NULL); + if (!node) + return 1; + m = (Module) getdata(node); + } if ((m->flags & MOD_INIT_S) && !(m->flags & MOD_UNLOAD) && ((m->flags & MOD_LINKED) ? @@ -1242,7 +1498,7 @@ unload_module(Module m, LinkNode node) LinkNode n; for (n = firstnode(m->deps); n; incnode(n)) { - LinkNode dn = find_module((char *) getdata(n)); + LinkNode dn = find_module((char *) getdata(n), 1, NULL); Module dm; if (dn && (dm = (Module) getdata(dn)) && @@ -1280,9 +1536,7 @@ unload_module(Module m, LinkNode node) if (!node) return 1; } - remnode(modules, node); - zsfree(m->nam); - zfree(m, sizeof(*m)); + delete_module(node); } } return 0; @@ -1297,8 +1551,9 @@ bin_zmodload_load(char *nam, char **args, char *ops) int ret = 0; if(ops['u']) { /* unload modules */ + const char *mname = *args; for(; *args; args++) { - node = find_module(*args); + node = find_module(*args, 1, &mname); if (node) { LinkNode mn, dn; int del = 0; @@ -1307,11 +1562,11 @@ bin_zmodload_load(char *nam, char **args, char *ops) m = (Module) getdata(mn); if (m->deps && m->u.handle) for (dn = firstnode(m->deps); dn; incnode(dn)) - if (!strcmp((char *) getdata(dn), *args)) { + if (!strcmp((char *) getdata(dn), mname)) { if (m->flags & MOD_UNLOAD) del = 1; else { - zwarnnam(nam, "module %s is in use by another module and cannot be unloaded", *args, 0); + zwarnnam(nam, "module %s is in use by another module and cannot be unloaded", mname, 0); ret = 1; goto cont; } @@ -1335,7 +1590,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->u.handle && !(m->flags & MOD_UNLOAD)) { + if (m->u.handle && !(m->flags & (MOD_UNLOAD|MOD_ALIAS))) { if(ops['L']) { printf("zmodload "); if(m->nam[0] == '-') @@ -1761,12 +2016,14 @@ add_autoparam(char *nam, char *module) { Param pm; + queue_signals(); if ((pm = (Param) gethashnode2(paramtab, nam))) unsetparam_pm(pm, 0, 1); - pm = setsparam(ztrdup(nam), ztrdup(module)); + pm = setsparam(nam, ztrdup(module)); pm->flags |= PM_AUTOLOAD; + unqueue_signals(); } /* List of math functions. */ @@ -1862,6 +2119,8 @@ add_automathfunc(char *nam, char *module) return 1; } + f->flags &= ~MFF_ADDED; /* still to autoload, not added yet */ + return 0; } diff --git a/Src/params.c b/Src/params.c index 255260467..aa80bcc78 100644 --- a/Src/params.c +++ b/Src/params.c @@ -318,7 +318,7 @@ scancopyparams(HashNode hn, int flags) { /* Going into a real parameter, so always use permanent storage */ Param pm = (Param)hn; - Param tpm = (Param) zcalloc(sizeof *tpm); + Param tpm = (Param) zshcalloc(sizeof *tpm); tpm->nam = ztrdup(pm->nam); copyparam(tpm, pm, 0); addhashnode(outtable, tpm->nam, tpm); @@ -687,7 +687,7 @@ createparam(char *name, int flags) pm->ct = 0; oldpm = pm->old; } else { - pm = (Param) zcalloc(sizeof *pm); + pm = (Param) zshcalloc(sizeof *pm); if ((pm->old = oldpm)) { /* * needed to avoid freeing oldpm, but we do take it @@ -1753,7 +1753,7 @@ setarrvalue(Value v, char **val) if (v->end <= n) ll += n - v->end + 1; - p = new = (char **) zcalloc(sizeof(char *) * (ll + 1)); + p = new = (char **) zshcalloc(sizeof(char *) * (ll + 1)); for (i = 0; i < v->start; i++) *p++ = i < n ? ztrdup(*q++) : ztrdup(""); diff --git a/Src/parse.c b/Src/parse.c index b3072201a..ddb163986 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -2064,7 +2064,7 @@ dupeprog(Eprog p, int heap) r->len = p->len; r->npats = p->npats; pp = r->pats = (heap ? (Patprog *) hcalloc(r->len) : - (Patprog *) zcalloc(r->len)); + (Patprog *) zshcalloc(r->len)); r->prog = (Wordcode) (r->pats + r->npats); r->strs = ((char *) r->prog) + (p->strs - ((char *) p->prog)); memcpy(r->prog, p->prog, r->len - (p->npats * sizeof(Patprog))); @@ -3161,7 +3161,7 @@ dump_autoload(char *nam, char *file, int on, char *ops, int func) for (n = firstfdhead(h), e = (FDHead) (h + fdheaderlen(h)); n < e; n = nextfdhead(n)) { - shf = (Shfunc) zcalloc(sizeof *shf); + shf = (Shfunc) zshcalloc(sizeof *shf); shf->flags = on; shf->funcdef = mkautofn(shf); shfunctab->addnode(shfunctab, ztrdup(fdname(n) + fdhtail(n)), shf); diff --git a/Src/pattern.c b/Src/pattern.c index b5f89f53c..be9f3b568 100644 --- a/Src/pattern.c +++ b/Src/pattern.c @@ -1430,9 +1430,9 @@ pattryrefs(Patprog prog, char *string, int *nump, int *begp, int *endp) char **matcharr, **mbeginarr, **mendarr; char numbuf[DIGBUFSIZE]; - matcharr = zcalloc(palen*sizeof(char *)); - mbeginarr = zcalloc(palen*sizeof(char *)); - mendarr = zcalloc(palen*sizeof(char *)); + matcharr = zshcalloc(palen*sizeof(char *)); + mbeginarr = zshcalloc(palen*sizeof(char *)); + mendarr = zshcalloc(palen*sizeof(char *)); sp = patbeginp; ep = patendp; @@ -1786,7 +1786,7 @@ patmatch(Upat prog) oldsyncstr = syncstrp->p; if (!patinlen) patinlen = strlen(patinstart)+1; - syncstrp->p = (unsigned char *)zcalloc(patinlen); + syncstrp->p = (unsigned char *)zshcalloc(patinlen); while ((ret = patmatch(P_OPERAND(scan)))) { unsigned char *syncpt; char savchar, *testptr; @@ -1909,7 +1909,7 @@ patmatch(Upat prog) if (!ptrp->p) { if (!patinlen) patinlen = strlen((char *)patinstart)+1; - ptrp->p = (unsigned char *)zcalloc(patinlen); + ptrp->p = (unsigned char *)zshcalloc(patinlen); pfree = 1; } ptr = ptrp->p + (patinput - patinstart); diff --git a/Src/prompt.c b/Src/prompt.c index d5df9d1ce..43dc12bee 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -171,7 +171,7 @@ promptexpand(char *s, int ns, char *rs, char *Rs) rstring = rs; Rstring = Rs; fm = s; - bp = bufline = buf = zcalloc(bufspc = 256); + bp = bufline = buf = zshcalloc(bufspc = 256); bp1 = NULL; trunclen = 0; putpromptchar(1, '\0'); diff --git a/Src/utils.c b/Src/utils.c index e2a6ab60f..cf202009f 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -293,7 +293,7 @@ slashsplit(char *s) int t0; if (!*s) - return (char **) zcalloc(sizeof(char **)); + return (char **) zshcalloc(sizeof(char **)); for (t = s, t0 = 0; *t; t++) if (*t == '/') @@ -541,7 +541,7 @@ adduserdir(char *s, char *t, int flags, int always) } /* add the name */ - nd = (Nameddir) zcalloc(sizeof *nd); + nd = (Nameddir) zshcalloc(sizeof *nd); nd->flags = flags; nd->dir = ztrdup(t); /* The variables PWD and OLDPWD are not to be displayed as ~PWD etc. */ @@ -1771,7 +1771,7 @@ zjoin(char **arr, int delim, int heap) len += strlen(*s) + 1; if (!len) return heap? "" : ztrdup(""); - ptr = ret = (heap ? (char *) hcalloc(len) : (char *) zcalloc(len)); + ptr = ret = (heap ? (char *) hcalloc(len) : (char *) zshcalloc(len)); for (s = arr; *s; s++) { strucpy(&ptr, *s); if (delim) @@ -1841,7 +1841,7 @@ spacesplit(char *s, int allownull, int heap, int quote) int l = sizeof(*ret) * (wordcount(s, NULL, -!allownull) + 1); char *(*dup)(const char *) = (heap ? dupstring : ztrdup); - ptr = ret = (heap ? (char **) hcalloc(l) : (char **) zcalloc(l)); + ptr = ret = (heap ? (char **) hcalloc(l) : (char **) zshcalloc(l)); if (quote) { /* @@ -1868,7 +1868,7 @@ spacesplit(char *s, int allownull, int heap, int quote) findsep(&s, NULL, quote); if (s > t || allownull) { *ptr = (heap ? (char *) hcalloc((s - t) + 1) : - (char *) zcalloc((s - t) + 1)); + (char *) zshcalloc((s - t) + 1)); ztrncpy(*ptr++, t, s - t); } else *ptr++ = dup(nulstring); @@ -2040,7 +2040,7 @@ sepjoin(char **s, char *sep, int heap) } sl = strlen(sep); for (t = s, l = 1 - sl; *t; l += strlen(*t) + sl, t++); - r = p = (heap ? (char *) hcalloc(l) : (char *) zcalloc(l)); + r = p = (heap ? (char *) hcalloc(l) : (char *) zshcalloc(l)); t = s; while (*t) { strucpy(&p, *t); @@ -2064,13 +2064,13 @@ sepsplit(char *s, char *sep, int allownull, int heap) sl = strlen(sep); n = wordcount(s, sep, 1); r = p = (heap ? (char **) hcalloc((n + 1) * sizeof(char *)) : - (char **) zcalloc((n + 1) * sizeof(char *))); + (char **) zshcalloc((n + 1) * sizeof(char *))); for (t = s; n--;) { tt = t; findsep(&t, sep, 0); *p = (heap ? (char *) hcalloc(t - tt + 1) : - (char *) zcalloc(t - tt + 1)); + (char *) zshcalloc(t - tt + 1)); strncpy(*p, tt, t - tt); (*p)[t - tt] = '\0'; p++; -- cgit 1.4.1