aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--Src/Builtins/sched.c2
-rw-r--r--Src/Modules/parameter.c8
-rw-r--r--Src/Modules/stat.c39
-rw-r--r--Src/Modules/zftp.c6
-rw-r--r--Src/Zle/compcore.c12
-rw-r--r--Src/Zle/compctl.c30
-rw-r--r--Src/Zle/complete.c4
-rw-r--r--Src/Zle/computil.c2
-rw-r--r--Src/Zle/zle_keymap.c160
-rw-r--r--Src/Zle/zle_main.c160
-rw-r--r--Src/Zle/zle_refresh.c4
-rw-r--r--Src/Zle/zle_thingy.c20
-rw-r--r--Src/builtin.c8
-rw-r--r--Src/exec.c6
-rw-r--r--Src/hashtable.c14
-rw-r--r--Src/hist.c4
-rw-r--r--Src/init.c6
-rw-r--r--Src/input.c5
-rw-r--r--Src/jobs.c2
-rw-r--r--Src/mem.c102
-rw-r--r--Src/module.c413
-rw-r--r--Src/params.c6
-rw-r--r--Src/parse.c4
-rw-r--r--Src/pattern.c10
-rw-r--r--Src/prompt.c2
-rw-r--r--Src/utils.c16
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 <pws@csr.com>
+
+ * 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 <clint@zsh.org>
* 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);