mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-01 17:24:50 +01:00
31937: zle -Fw uses widget semantics for file descriptor handler
This commit is contained in:
parent
375115c7df
commit
f77a7a5b18
7 changed files with 79 additions and 27 deletions
|
@ -1,3 +1,10 @@
|
|||
2013-11-07 Peter Stephenson <p.stephenson@samsung.com>
|
||||
|
||||
* 31937: Doc/Zsh/zle.yo, Src/Zle/zle_main.c,
|
||||
Src/Zle/zle_thingy.c, Src/Zle/zle_utils.c, Src/math.c,
|
||||
Test/C01arith.ztst: zle -Fw uses widget semantics for
|
||||
file descriptor handler.
|
||||
|
||||
2013-11-06 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* unposted: Completion/Debian/Command/.distfiles,
|
||||
|
|
|
@ -373,7 +373,7 @@ xitem(tt(zle) tt(-R) [ tt(-c) ] [ var(display-string) ] [ var(string) ... ])
|
|||
xitem(tt(zle) tt(-M) var(string))
|
||||
xitem(tt(zle) tt(-U) var(string))
|
||||
xitem(tt(zle) tt(-K) var(keymap))
|
||||
xitem(tt(zle) tt(-F) [ tt(-L) ] [ var(fd) [ var(handler) ] ])
|
||||
xitem(tt(zle) tt(-F) [ tt(-L) | tt(-w) ] [ var(fd) [ var(handler) ] ])
|
||||
xitem(tt(zle) tt(-I))
|
||||
xitem(tt(zle) tt(-T) [ tt(tc) var(function) | tt(-r) tt(tc) | tt(-L) ] )
|
||||
item(tt(zle) var(widget) tt([ -n) var(num) tt(]) tt([ -Nw ] [ -K) var(keymap) tt(]) var(args) ...)(
|
||||
|
@ -487,7 +487,7 @@ This keymap selection affects the interpretation of following keystrokes
|
|||
within this invocation of ZLE. Any following invocation (e.g., the next
|
||||
command line) will start as usual with the `tt(main)' keymap selected.
|
||||
)
|
||||
item(tt(-F) [ tt(-L) ] [ var(fd) [ var(handler) ] ])(
|
||||
item(tt(-F) [ tt(-L) | tt(-w) ] [ var(fd) [ var(handler) ] ])(
|
||||
Only available if your system supports one of the `poll' or `select' system
|
||||
calls; most modern systems do.
|
||||
|
||||
|
@ -502,6 +502,13 @@ Note that zle makes no attempt to check whether this fd is actually
|
|||
readable when installing the handler. The user must make their own
|
||||
arrangements for handling the file descriptor when zle is not active.
|
||||
|
||||
If the option tt(-w) is also given, the var(handler) is instead a
|
||||
line editor widget, typically a shell function made into a widget using
|
||||
tt(zle -N). In that case var(handler) can use all the facilities of
|
||||
zle to update the current editing line. Note, however, that as handling
|
||||
var(fd) takes place at a low level changes to the display will not
|
||||
automatically appear; the widget should call tt(zle -R) to force redisplay.
|
||||
|
||||
Any number of handlers for any number of readable file descriptors may be
|
||||
installed. Installing a handler for an var(fd) which is already handled
|
||||
causes the existing handler to be replaced.
|
||||
|
|
|
@ -201,6 +201,8 @@ int nwatch; /* Number of fd's we are watching */
|
|||
int *watch_fds; /* The list of fds, not terminated! */
|
||||
/**/
|
||||
char **watch_funcs; /* The corresponding functions to call, normal array */
|
||||
/**/
|
||||
int *watch_widgets; /* 1 if corresponding function is called as widget */
|
||||
|
||||
/* set up terminal */
|
||||
|
||||
|
@ -725,7 +727,9 @@ raw_getbyte(long do_keytmout, char *cptr)
|
|||
int lnwatch = nwatch;
|
||||
int *lwatch_fds = zalloc(lnwatch*sizeof(int));
|
||||
char **lwatch_funcs = zarrdup(watch_funcs);
|
||||
int *lwatch_widgets = zalloc(lnwatch*sizeof(int));
|
||||
memcpy(lwatch_fds, watch_fds, lnwatch*sizeof(int));
|
||||
memcpy(lwatch_widgets, watch_widgets, lnwatch*sizeof(int));
|
||||
for (i = 0; i < lnwatch; i++) {
|
||||
if (
|
||||
# ifdef HAVE_POLL
|
||||
|
@ -735,30 +739,37 @@ raw_getbyte(long do_keytmout, char *cptr)
|
|||
# endif
|
||||
) {
|
||||
/* Handle the fd. */
|
||||
LinkList funcargs = znewlinklist();
|
||||
zaddlinknode(funcargs, ztrdup(lwatch_funcs[i]));
|
||||
char *fdbuf;
|
||||
{
|
||||
char buf[BDIGBUFSIZE];
|
||||
convbase(buf, lwatch_fds[i], 10);
|
||||
zaddlinknode(funcargs, ztrdup(buf));
|
||||
fdbuf = ztrdup(buf);
|
||||
}
|
||||
|
||||
if (lwatch_widgets[i]) {
|
||||
zlecallhook(lwatch_funcs[i], fdbuf);
|
||||
zsfree(fdbuf);
|
||||
} else {
|
||||
LinkList funcargs = znewlinklist();
|
||||
zaddlinknode(funcargs, ztrdup(lwatch_funcs[i]));
|
||||
zaddlinknode(funcargs, fdbuf);
|
||||
# ifdef HAVE_POLL
|
||||
# ifdef POLLERR
|
||||
if (fds[i+1].revents & POLLERR)
|
||||
zaddlinknode(funcargs, ztrdup("err"));
|
||||
if (fds[i+1].revents & POLLERR)
|
||||
zaddlinknode(funcargs, ztrdup("err"));
|
||||
# endif
|
||||
# ifdef POLLHUP
|
||||
if (fds[i+1].revents & POLLHUP)
|
||||
zaddlinknode(funcargs, ztrdup("hup"));
|
||||
if (fds[i+1].revents & POLLHUP)
|
||||
zaddlinknode(funcargs, ztrdup("hup"));
|
||||
# endif
|
||||
# ifdef POLLNVAL
|
||||
if (fds[i+1].revents & POLLNVAL)
|
||||
zaddlinknode(funcargs, ztrdup("nval"));
|
||||
if (fds[i+1].revents & POLLNVAL)
|
||||
zaddlinknode(funcargs, ztrdup("nval"));
|
||||
# endif
|
||||
# endif
|
||||
|
||||
|
||||
callhookfunc(lwatch_funcs[i], funcargs, 0, NULL);
|
||||
callhookfunc(lwatch_funcs[i], funcargs, 0, NULL);
|
||||
freelinklist(funcargs, freestr);
|
||||
}
|
||||
if (errflag) {
|
||||
/* No sensible way of handling errors here */
|
||||
errflag = 0;
|
||||
|
@ -768,7 +779,6 @@ raw_getbyte(long do_keytmout, char *cptr)
|
|||
*/
|
||||
errtry = 1;
|
||||
}
|
||||
freelinklist(funcargs, freestr);
|
||||
}
|
||||
}
|
||||
/* Function may have invalidated the display. */
|
||||
|
@ -1960,7 +1970,7 @@ zle_main_entry(int cmd, va_list ap)
|
|||
static struct builtin bintab[] = {
|
||||
BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaM:ldDANmrsLRp", NULL),
|
||||
BUILTIN("vared", 0, bin_vared, 1, 1, 0, "aAcef:hi:M:m:p:r:t:", NULL),
|
||||
BUILTIN("zle", 0, bin_zle, 0, -1, 0, "aAcCDFgGIKlLmMNrRTU", NULL),
|
||||
BUILTIN("zle", 0, bin_zle, 0, -1, 0, "aAcCDFgGIKlLmMNrRTUw", NULL),
|
||||
};
|
||||
|
||||
/* The order of the entries in this table has to match the *HOOK
|
||||
|
|
|
@ -781,7 +781,8 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
|
|||
if (*args && watch_fds[i] != fd)
|
||||
continue;
|
||||
found = 1;
|
||||
printf("%s -F %d %s\n", name, watch_fds[i], watch_funcs[i]);
|
||||
printf("%s -F %s%d %s\n", name, watch_widgets[i] ? "-w " : "",
|
||||
watch_fds[i], watch_funcs[i]);
|
||||
}
|
||||
/* only return status 1 if fd given and not found */
|
||||
return *args && !found;
|
||||
|
@ -795,6 +796,7 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
|
|||
if (watch_fds[i] == fd) {
|
||||
zsfree(watch_funcs[i]);
|
||||
watch_funcs[i] = funcnam;
|
||||
watch_widgets[i] = OPT_ISSET(ops,'w') ? 1 : 0;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -807,9 +809,12 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
|
|||
newnwatch * sizeof(int));
|
||||
watch_funcs = (char **)zrealloc(watch_funcs,
|
||||
(newnwatch+1) * sizeof(char *));
|
||||
watch_widgets = (int *)zrealloc(watch_widgets,
|
||||
newnwatch * sizeof(int));
|
||||
watch_fds[nwatch] = fd;
|
||||
watch_funcs[nwatch] = funcnam;
|
||||
watch_funcs[newnwatch] = NULL;
|
||||
watch_widgets[nwatch] = OPT_ISSET(ops,'w') ? 1 : 0;
|
||||
nwatch = newnwatch;
|
||||
}
|
||||
} else {
|
||||
|
@ -817,32 +822,39 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
|
|||
for (i = 0; i < nwatch; i++) {
|
||||
if (watch_fds[i] == fd) {
|
||||
int newnwatch = nwatch-1;
|
||||
int *new_fds;
|
||||
int *new_fds, *new_widgets;
|
||||
char **new_funcs;
|
||||
|
||||
zsfree(watch_funcs[i]);
|
||||
if (newnwatch) {
|
||||
new_fds = zalloc(newnwatch*sizeof(int));
|
||||
new_funcs = zalloc((newnwatch+1)*sizeof(char*));
|
||||
new_widgets = zalloc(newnwatch*sizeof(int));
|
||||
if (i) {
|
||||
memcpy(new_fds, watch_fds, i*sizeof(int));
|
||||
memcpy(new_funcs, watch_funcs, i*sizeof(char *));
|
||||
memcpy(new_widgets, watch_widgets, i*sizeof(int));
|
||||
}
|
||||
if (i < newnwatch) {
|
||||
memcpy(new_fds+i, watch_fds+i+1,
|
||||
(newnwatch-i)*sizeof(int));
|
||||
memcpy(new_funcs+i, watch_funcs+i+1,
|
||||
(newnwatch-i)*sizeof(char *));
|
||||
memcpy(new_widgets+i, watch_widgets+i+1,
|
||||
(newnwatch-i)*sizeof(int));
|
||||
}
|
||||
new_funcs[newnwatch] = NULL;
|
||||
} else {
|
||||
new_fds = NULL;
|
||||
new_funcs = NULL;
|
||||
new_widgets = NULL;
|
||||
}
|
||||
zfree(watch_fds, nwatch*sizeof(int));
|
||||
zfree(watch_funcs, (nwatch+1)*sizeof(char *));
|
||||
zfree(watch_widgets, nwatch*sizeof(int));
|
||||
watch_fds = new_fds;
|
||||
watch_funcs = new_funcs;
|
||||
watch_widgets = new_widgets;
|
||||
nwatch = newnwatch;
|
||||
found = 1;
|
||||
break;
|
||||
|
|
|
@ -1643,7 +1643,7 @@ zlecallhook(char *name, char *arg)
|
|||
{
|
||||
Thingy thingy = rthingy_nocreate(name);
|
||||
int saverrflag, savretflag;
|
||||
char *args[3];
|
||||
char *args[2];
|
||||
|
||||
if (!thingy)
|
||||
return;
|
||||
|
@ -1651,9 +1651,8 @@ zlecallhook(char *name, char *arg)
|
|||
saverrflag = errflag;
|
||||
savretflag = retflag;
|
||||
|
||||
args[0] = thingy->nam;
|
||||
args[1] = arg;
|
||||
args[2] = NULL;
|
||||
args[0] = arg;
|
||||
args[1] = NULL;
|
||||
execzlefunc(thingy, args, 1);
|
||||
unrefthingy(thingy);
|
||||
|
||||
|
|
23
Src/math.c
23
Src/math.c
|
@ -1374,6 +1374,19 @@ mathevalarg(char *s, char **ss)
|
|||
mnumber x;
|
||||
int xmtok = mtok;
|
||||
|
||||
/*
|
||||
* At this entry point we don't allow an empty expression,
|
||||
* whereas we do with matheval(). I'm not sure if this
|
||||
* difference is deliberate, but it does mean that e.g.
|
||||
* $array[$ind] where ind hasn't been set produces an error,
|
||||
* which is probably safe.
|
||||
*
|
||||
* To avoid a more opaque error further in, bail out here.
|
||||
*/
|
||||
if (!*s) {
|
||||
zerr("bad math expression: empty string");
|
||||
return (zlong)0;
|
||||
}
|
||||
x = mathevall(s, MPREC_ARG, ss);
|
||||
if (mtok == COMMA)
|
||||
(*ss)--;
|
||||
|
@ -1401,6 +1414,7 @@ checkunary(int mtokc, char *mptr)
|
|||
}
|
||||
if (errmsg) {
|
||||
int len, over = 0;
|
||||
char *errtype = errmsg == 2 ? "operator" : "operand";
|
||||
while (inblank(*mptr))
|
||||
mptr++;
|
||||
len = ztrlen(mptr);
|
||||
|
@ -1408,9 +1422,12 @@ checkunary(int mtokc, char *mptr)
|
|||
len = 10;
|
||||
over = 1;
|
||||
}
|
||||
zerr("bad math expression: %s expected at `%l%s'",
|
||||
errmsg == 2 ? "operator" : "operand",
|
||||
mptr, len, over ? "..." : "");
|
||||
if (!*mptr)
|
||||
zerr("bad math expression: %s expected at end of string",
|
||||
errtype);
|
||||
else
|
||||
zerr("bad math expression: %s expected at `%l%s'",
|
||||
errtype, mptr, len, over ? "..." : "");
|
||||
}
|
||||
unary = !(tp & OP_OPF);
|
||||
}
|
||||
|
|
|
@ -134,11 +134,11 @@
|
|||
|
||||
print $(( a = ))
|
||||
1:empty assignment
|
||||
?(eval):1: bad math expression: operand expected at `'
|
||||
?(eval):1: bad math expression: operand expected at end of string
|
||||
|
||||
print $(( 3, ))
|
||||
1:empty right hand of comma
|
||||
?(eval):1: bad math expression: operand expected at `'
|
||||
?(eval):1: bad math expression: operand expected at end of string
|
||||
|
||||
print $(( 3,,4 ))
|
||||
1:empty middle of comma
|
||||
|
|
Loading…
Reference in a new issue