From f77a7a5b18f0650d32e5e8dac1f1cb284a9e4690 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 7 Nov 2013 15:19:07 +0000 Subject: 31937: zle -Fw uses widget semantics for file descriptor handler --- Src/Zle/zle_main.c | 38 ++++++++++++++++++++++++-------------- Src/Zle/zle_thingy.c | 16 ++++++++++++++-- Src/Zle/zle_utils.c | 7 +++---- Src/math.c | 23 ++++++++++++++++++++--- 4 files changed, 61 insertions(+), 23 deletions(-) (limited to 'Src') diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 5798e74b4..6822230b4 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -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 diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c index 49d715e06..78c7918d2 100644 --- a/Src/Zle/zle_thingy.c +++ b/Src/Zle/zle_thingy.c @@ -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; diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index b84d253bb..b82e54ce5 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -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); diff --git a/Src/math.c b/Src/math.c index eae283d19..b21a3adee 100644 --- a/Src/math.c +++ b/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); } -- cgit 1.4.1