From 6dd54b37656437e26012e966a2f7e8af4c67f9b8 Mon Sep 17 00:00:00 2001 From: Paul Ackersviller Date: Tue, 27 Nov 2007 04:35:22 +0000 Subject: Manually put in users/12230: fix problem setting killring to zero size. --- Src/Zle/zle_params.c | 441 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 386 insertions(+), 55 deletions(-) diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c index 26059c871..0be87ffc3 100644 --- a/Src/Zle/zle_params.c +++ b/Src/Zle/zle_params.c @@ -44,40 +44,86 @@ * RBUFFER (scalar) portion of buffer to the right of the cursor */ -#define FN(X) ( (void (*) _((void))) (X) ) +static const struct gsu_scalar buffer_gsu = +{ get_buffer, set_buffer, zleunsetfn }; +static const struct gsu_scalar context_gsu = +{ get_context, nullstrsetfn, zleunsetfn }; +static const struct gsu_scalar cutbuffer_gsu = +{ get_cutbuffer, set_cutbuffer, unset_cutbuffer }; +static const struct gsu_scalar keymap_gsu = +{ get_keymap, nullstrsetfn, zleunsetfn }; +static const struct gsu_scalar keys_gsu = +{ get_keys, nullstrsetfn, zleunsetfn }; +static const struct gsu_scalar lastsearch_gsu = +{ get_lsearch, nullstrsetfn, zleunsetfn }; +static const struct gsu_scalar lastwidget_gsu = +{ get_lwidget, nullstrsetfn, zleunsetfn }; +static const struct gsu_scalar lbuffer_gsu = +{ get_lbuffer, set_lbuffer, zleunsetfn }; +static const struct gsu_scalar postdisplay_gsu = +{ get_postdisplay, set_postdisplay, zleunsetfn }; +static const struct gsu_scalar prebuffer_gsu = +{ get_prebuffer, nullstrsetfn, zleunsetfn }; +static const struct gsu_scalar predisplay_gsu = +{ get_predisplay, set_predisplay, zleunsetfn }; +static const struct gsu_scalar rbuffer_gsu = +{ get_rbuffer, set_rbuffer, zleunsetfn }; +static const struct gsu_scalar widget_gsu = +{ get_widget, nullstrsetfn, zleunsetfn }; +static const struct gsu_scalar widgetfunc_gsu = +{ get_widgetfunc, nullstrsetfn, zleunsetfn }; +static const struct gsu_scalar widgetstyle_gsu = +{ get_widgetstyle, nullstrsetfn, zleunsetfn }; + +static const struct gsu_integer bufferlines_gsu = +{ get_bufferlines, NULL, zleunsetfn }; +static const struct gsu_integer cursor_gsu = +{ get_cursor, set_cursor, zleunsetfn }; +static const struct gsu_integer histno_gsu = +{ get_histno, set_histno, zleunsetfn }; +static const struct gsu_integer mark_gsu = +{ get_mark, set_mark, zleunsetfn }; +static const struct gsu_integer numeric_gsu = +{ get_numeric, set_numeric, unset_numeric }; +static const struct gsu_integer pending_gsu = +{ get_pending, NULL, zleunsetfn }; + +static const struct gsu_array killring_gsu = +{ get_killring, set_killring, unset_killring }; + +#define GSU(X) ( (GsuScalar)(void*)(&(X)) ) static struct zleparam { char *name; int type; - void (*setfn) _((void)); - void (*getfn) _((void)); - void (*unsetfn) _((Param, int)); + GsuScalar gsu; void *data; } zleparams[] = { - { "BUFFER", PM_SCALAR, FN(set_buffer), FN(get_buffer), - zleunsetfn, NULL }, - { "CURSOR", PM_INTEGER, FN(set_cursor), FN(get_cursor), - zleunsetfn, NULL }, - { "MARK", PM_INTEGER, FN(set_mark), FN(get_mark), - zleunsetfn, NULL }, - { "LBUFFER", PM_SCALAR, FN(set_lbuffer), FN(get_lbuffer), - zleunsetfn, NULL }, - { "RBUFFER", PM_SCALAR, FN(set_rbuffer), FN(get_rbuffer), - zleunsetfn, NULL }, - { "PREBUFFER", PM_SCALAR | PM_READONLY, NULL, FN(get_prebuffer), - zleunsetfn, NULL }, - { "WIDGET", PM_SCALAR | PM_READONLY, NULL, FN(get_widget), - zleunsetfn, NULL }, - { "LASTWIDGET", PM_SCALAR | PM_READONLY, NULL, FN(get_lwidget), - zleunsetfn, NULL }, - { "KEYS", PM_SCALAR | PM_READONLY, NULL, FN(get_keys), - zleunsetfn, NULL }, - { "NUMERIC", PM_INTEGER | PM_UNSET, FN(set_numeric), FN(get_numeric), - unset_numeric, NULL }, - { "HISTNO", PM_INTEGER | PM_READONLY, NULL, FN(get_histno), - zleunsetfn, NULL }, - { "BUFFERLINES", PM_INTEGER | PM_READONLY, NULL, FN(get_bufferlines), - zleunsetfn, NULL }, - { NULL, 0, NULL, NULL, NULL, NULL } + { "BUFFER", PM_SCALAR, GSU(buffer_gsu), NULL }, + { "BUFFERLINES", PM_INTEGER | PM_READONLY, GSU(bufferlines_gsu), + NULL }, + { "CONTEXT", PM_SCALAR | PM_READONLY, GSU(context_gsu), + NULL }, + { "CURSOR", PM_INTEGER, GSU(cursor_gsu), + NULL }, + { "CUTBUFFER", PM_SCALAR, GSU(cutbuffer_gsu), NULL }, + { "HISTNO", PM_INTEGER, GSU(histno_gsu), NULL }, + { "KEYMAP", PM_SCALAR | PM_READONLY, GSU(keymap_gsu), NULL }, + { "KEYS", PM_SCALAR | PM_READONLY, GSU(keys_gsu), NULL }, + { "killring", PM_ARRAY, GSU(killring_gsu), NULL }, + { "LASTSEARCH", PM_SCALAR | PM_READONLY, GSU(lastsearch_gsu), NULL }, + { "LASTWIDGET", PM_SCALAR | PM_READONLY, GSU(lastwidget_gsu), NULL }, + { "LBUFFER", PM_SCALAR, GSU(lbuffer_gsu), NULL }, + { "MARK", PM_INTEGER, GSU(mark_gsu), NULL }, + { "NUMERIC", PM_INTEGER | PM_UNSET, GSU(numeric_gsu), NULL }, + { "PENDING", PM_INTEGER | PM_READONLY, GSU(pending_gsu), NULL }, + { "POSTDISPLAY", PM_SCALAR, GSU(postdisplay_gsu), NULL }, + { "PREBUFFER", PM_SCALAR | PM_READONLY, GSU(prebuffer_gsu), NULL }, + { "PREDISPLAY", PM_SCALAR, GSU(predisplay_gsu), NULL }, + { "RBUFFER", PM_SCALAR, GSU(rbuffer_gsu), NULL }, + { "WIDGET", PM_SCALAR | PM_READONLY, GSU(widget_gsu), NULL }, + { "WIDGETFUNC", PM_SCALAR | PM_READONLY, GSU(widgetfunc_gsu), NULL }, + { "WIDGETSTYLE", PM_SCALAR | PM_READONLY, GSU(widgetstyle_gsu), NULL }, + { NULL, 0, NULL, NULL } }; /**/ @@ -97,20 +143,16 @@ makezleparams(int ro) pm->u.data = zp->data; switch(PM_TYPE(zp->type)) { case PM_SCALAR: - pm->sets.cfn = (void (*) _((Param, char *))) zp->setfn; - pm->gets.cfn = (char *(*) _((Param))) zp->getfn; + pm->gsu.s = zp->gsu; break; case PM_ARRAY: - pm->sets.afn = (void (*) _((Param, char **))) zp->setfn; - pm->gets.afn = (char **(*) _((Param))) zp->getfn; + pm->gsu.a = (GsuArray)zp->gsu; break; case PM_INTEGER: - pm->sets.ifn = (void (*) _((Param, zlong))) zp->setfn; - pm->gets.ifn = (zlong (*) _((Param))) zp->getfn; - pm->ct = 10; + pm->gsu.i = (GsuInteger)zp->gsu; + pm->base = 10; break; } - pm->unsetfn = zp->unsetfn; if ((zp->type & PM_UNSET) && (zmod.flags & MOD_MULT)) pm->flags &= ~PM_UNSET; } @@ -130,7 +172,7 @@ zleunsetfn(Param pm, int exp) /**/ static void -set_buffer(Param pm, char *x) +set_buffer(UNUSED(Param pm), char *x) { if(x) { unmetafy(x, &ll); @@ -147,14 +189,14 @@ set_buffer(Param pm, char *x) /**/ static char * -get_buffer(Param pm) +get_buffer(UNUSED(Param pm)) { return metafy((char *)line, ll, META_HEAPDUP); } /**/ static void -set_cursor(Param pm, zlong x) +set_cursor(UNUSED(Param pm), zlong x) { if(x < 0) cs = 0; @@ -168,14 +210,14 @@ set_cursor(Param pm, zlong x) /**/ static zlong -get_cursor(Param pm) +get_cursor(UNUSED(Param pm)) { return cs; } /**/ static void -set_mark(Param pm, zlong x) +set_mark(UNUSED(Param pm), zlong x) { if (x < 0) mark = 0; @@ -187,14 +229,14 @@ set_mark(Param pm, zlong x) /**/ static zlong -get_mark(Param pm) +get_mark(UNUSED(Param pm)) { return mark; } /**/ static void -set_lbuffer(Param pm, char *x) +set_lbuffer(UNUSED(Param pm), char *x) { char *y; int len; @@ -215,14 +257,14 @@ set_lbuffer(Param pm, char *x) /**/ static char * -get_lbuffer(Param pm) +get_lbuffer(UNUSED(Param pm)) { return metafy((char *)line, cs, META_HEAPDUP); } /**/ static void -set_rbuffer(Param pm, char *x) +set_rbuffer(UNUSED(Param pm), char *x) { char *y; int len; @@ -240,14 +282,14 @@ set_rbuffer(Param pm, char *x) /**/ static char * -get_rbuffer(Param pm) +get_rbuffer(UNUSED(Param pm)) { return metafy((char *)line + cs, ll - cs, META_HEAPDUP); } /**/ static char * -get_prebuffer(Param pm) +get_prebuffer(UNUSED(Param pm)) { if (chline) return dupstrpfx(chline, hptr - chline); @@ -257,28 +299,65 @@ get_prebuffer(Param pm) /**/ static char * -get_widget(Param pm) +get_widget(UNUSED(Param pm)) { return bindk->nam; } /**/ static char * -get_lwidget(Param pm) +get_widgetfunc(UNUSED(Param pm)) +{ + Widget widget = bindk->widget; + int flags = widget->flags; + + if (flags & WIDGET_INT) + return ".internal"; /* Don't see how this can ever be returned... */ + else if (flags & WIDGET_NCOMP) + return widget->u.comp.func; + else + return widget->u.fnnam; +} + +/**/ +static char * +get_widgetstyle(UNUSED(Param pm)) +{ + Widget widget = bindk->widget; + int flags = widget->flags; + + if (flags & WIDGET_INT) + return ".internal"; /* Don't see how this can ever be returned... */ + else if (flags & WIDGET_NCOMP) + return widget->u.comp.wid; + else + return ""; +} + +/**/ +static char * +get_lwidget(UNUSED(Param pm)) { return (lbindk ? lbindk->nam : ""); } /**/ static char * -get_keys(Param pm) +get_keymap(UNUSED(Param pm)) +{ + return dupstring(curkeymapname); +} + +/**/ +static char * +get_keys(UNUSED(Param pm)) { return keybuf; } /**/ static void -set_numeric(Param pm, zlong x) +set_numeric(UNUSED(Param pm), zlong x) { zmult = x; zmod.flags = MOD_MULT; @@ -286,7 +365,7 @@ set_numeric(Param pm, zlong x) /**/ static zlong -get_numeric(Param pm) +get_numeric(UNUSED(Param pm)) { return zmult; } @@ -302,16 +381,268 @@ unset_numeric(Param pm, int exp) } } +/**/ +static void +set_histno(UNUSED(Param pm), zlong x) +{ + Histent he; + + if (!(he = quietgethist((int)x))) + return; + zle_setline(he); +} + /**/ static zlong -get_histno(Param pm) +get_histno(UNUSED(Param pm)) { return histline; } /**/ static zlong -get_bufferlines(Param pm) +get_bufferlines(UNUSED(Param pm)) { return nlnct; } + +/**/ +static zlong +get_pending(UNUSED(Param pm)) +{ + return noquery(0); +} + +/**/ +static char * +get_cutbuffer(UNUSED(Param pm)) +{ + if (cutbuf.buf) + return metafy(cutbuf.buf, cutbuf.len, META_HEAPDUP); + else + return ""; +} + + +/**/ +static void +set_cutbuffer(UNUSED(Param pm), char *x) +{ + if (cutbuf.buf) + free(cutbuf.buf); + cutbuf.flags = 0; + if (x) { + int n; + unmetafy(x, &n); + cutbuf.len = n; + cutbuf.buf = zalloc(cutbuf.len); + memcpy((char *)cutbuf.buf, x, cutbuf.len); + free(x); + } else { + cutbuf.buf = NULL; + cutbuf.len = 0; + } +} + +/**/ +static void +unset_cutbuffer(Param pm, int exp) +{ + if (exp) { + stdunsetfn(pm, exp); + if (cutbuf.buf) { + free(cutbuf.buf); + cutbuf.buf = NULL; + cutbuf.len = 0; + } + } +} + +/**/ +static void +set_killring(UNUSED(Param pm), char **x) +{ + int kcnt; + Cutbuffer kptr; + char **p; + + if (kring) { + for (kptr = kring, kcnt = 0; kcnt < kringsize; kcnt++, kptr++) + if (kptr->buf) + zfree(kptr->buf, kptr->len); + zfree(kring, kringsize * sizeof(struct cutbuffer)); + kring = NULL; + kringsize = kringnum = 0; + } + if (x) { + /* + * Insert the elements into the kill ring. + * Regardless of the old order, we number it with the current + * entry first. + * + * Be careful to add elements by looping backwards; this + * fits in with how we cycle the ring. + */ + int kpos = 0; + kringsize = arrlen(x); + if (kringsize != 0) { + kring = (Cutbuffer)zshcalloc(kringsize * sizeof(struct cutbuffer)); + for (p = x; *p; p++) { + int n, len = strlen(*p); + kptr = kring + kpos; + unmetafy(*p, &n); + kptr->len = n; + kptr->buf = (char *)zalloc(kptr->len); + memcpy(kptr->buf, *p, kptr->len); + zfree(*p, len+1); + kpos = (kpos + kringsize -1 ) % kringsize; + } + } + free(x); + } +} + +/**/ +static char ** +get_killring(UNUSED(Param pm)) +{ + /* + * Return the kill ring with the most recently killed first. + * Since the kill ring is no longer a fixed length, we return + * all entries even if empty. + */ + int kpos, kcnt; + char **ret, **p; + + /* Supposed to work even if kring is NULL */ + if (!kring) { + kringsize = KRINGCTDEF; + kring = (Cutbuffer)zshcalloc(kringsize * sizeof(struct cutbuffer)); + } + + p = ret = (char **)zhalloc((kringsize+1) * sizeof(char *)); + + for (kpos = kringnum, kcnt = 0; kcnt < kringsize; kcnt++) { + Cutbuffer kptr = kring + kpos; + if (kptr->buf) + { + /* + * Need to use HEAPDUP to make sure there's room for the + * terminating NULL. + */ + *p++ = metafy((char *)kptr->buf, kptr->len, META_HEAPDUP); + } + else + *p++ = dupstring(""); + kpos = (kpos + kringsize - 1) % kringsize; + } + *p = NULL; + + return ret; +} + +/**/ +static void +unset_killring(Param pm, int exp) +{ + if (exp) { + set_killring(pm, NULL); + stdunsetfn(pm, exp); + } +} + +static void +set_prepost(unsigned char **textvar, int *lenvar, char *x) +{ + if (*lenvar) { + zfree(*textvar, *lenvar); + *textvar = NULL; + *lenvar = 0; + } + if (x) { + unmetafy(x, lenvar); + if (*lenvar) { + *textvar = (unsigned char *)zalloc(*lenvar); + memcpy((char *)*textvar, x, *lenvar); + } + free(x); + } +} + +static char * +get_prepost(unsigned char *text, int len) +{ + return metafy((char *)text, len, META_HEAPDUP); +} + +/**/ +static void +set_predisplay(UNUSED(Param pm), char *x) +{ + set_prepost(&predisplay, &predisplaylen, x); +} + +/**/ +static char * +get_predisplay(UNUSED(Param pm)) +{ + return get_prepost(predisplay, predisplaylen); +} + +/**/ +static void +set_postdisplay(UNUSED(Param pm), char *x) +{ + set_prepost(&postdisplay, &postdisplaylen, x); +} + +/**/ +static char * +get_postdisplay(UNUSED(Param pm)) +{ + return get_prepost(postdisplay, postdisplaylen); +} + +/**/ +void +free_prepostdisplay(void) +{ + if (predisplaylen) + set_prepost(&predisplay, &predisplaylen, NULL); + if (postdisplaylen) + set_prepost(&postdisplay, &postdisplaylen, NULL); +} + +/**/ +static char * +get_lsearch(UNUSED(Param pm)) +{ + if (previous_search_len) + return metafy(previous_search, previous_search_len, META_HEAPDUP); + else + return ""; +} + +/**/ +static char * +get_context(UNUSED(Param pm)) +{ + switch (zlecontext) { + case ZLCON_LINE_CONT: + return "cont"; + break; + + case ZLCON_SELECT: + return "select"; + break; + + case ZLCON_VARED: + return "vared"; + break; + + case ZLCON_LINE_START: + default: + return "start"; + break; + } +} -- cgit 1.4.1