aboutsummaryrefslogtreecommitdiff
path: root/Src/Zle/zle_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle/zle_main.c')
-rw-r--r--Src/Zle/zle_main.c160
1 files changed, 119 insertions, 41 deletions
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;