Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: interface from main shell to zle



I'd like to simply the function call interface from the main shell into
zle.  (The interface from zle back into the main shell is probably too
horrible to think about.)  This patch reduces the current mess of pointers
to a single entry point, which has autoload behaviour for all functions,
not just a chosen few.

The main disadvantage is less type checking (the extra overhead is
negligible since anything involving zle is fairly leisurely anyway).
This could be fixed by putting in intervening functions in the main
shell when the DEBUG option is defined, although the code in question
doesn't change very often anyway.  In any case I'd prefer to make it
easier to maintain than harder to break simply by means of obscurity.

Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.198
diff -u -r1.198 builtin.c
--- Src/builtin.c	25 Jul 2008 08:55:29 -0000	1.198
+++ Src/builtin.c	28 Jul 2008 17:27:13 -0000
@@ -4753,7 +4753,7 @@
     char *reply, *readpmpt;
     int bsiz, c = 0, gotnl = 0, al = 0, first, nchars = 1, bslash, keys = 0;
     int haso = 0;	/* true if /dev/tty has been opened specially */
-    int isem = !strcmp(term, "emacs"), izle = zleactive && getkeyptr;
+    int isem = !strcmp(term, "emacs"), izle = zleactive;
     char *buf, *bptr, *firstarg, *zbuforig;
     LinkList readll = newlinklist();
     FILE *oshout = NULL;
@@ -4963,7 +4963,8 @@
 
 	do {
 	    if (izle) {
-		if ((val = getkeyptr(izle_timeout, NULL)) < 0) {
+		zleentry(ZLE_CMD_GET_KEY, izle_timeout, NULL, &val);
+		if (val < 0) {
 		    eof = 1;
 		    break;
 		}
@@ -5068,9 +5069,13 @@
 	if (izle) {
 #ifdef MULTIBYTE_SUPPORT
 	    int key;
+	    char c;
 
-	    while ((key = getkeyptr(izle_timeout, NULL)) >= 0) {
-		char c = (char)key;
+	    for (;;) {
+		zleentry(ZLE_CMD_GET_KEY, izle_timeout, NULL, &key);
+		if (key < 0)
+		    break;
+		c = (char)key;
 		/*
 		 * If multibyte, it can't be y, so we don't care
 		 * what key gets set to; just read to end of character.
@@ -5080,7 +5085,8 @@
 		    break;
 	    }
 #else
-	    int key = getkeyptr(izle_timeout, NULL);
+	    int key;
+	    zleentry(ZLE_CMD_GET_KEY, izle_timeout, NULL, &key);
 #endif
 
 	    readbuf[0] = (key == 'y' ? 'y' : 'n');
@@ -5460,7 +5466,8 @@
     int ret;
 
     if (izle) {
-	int c = getkeyptr(izle_timeout, NULL);
+	int c;
+	zleentry(ZLE_CMD_GET_KEY, izle_timeout, NULL, &c);
 
 	return (c < 0 ? EOF : c);
     }
Index: Src/exec.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/exec.c,v
retrieving revision 1.134
diff -u -r1.134 exec.c
--- Src/exec.c	17 Jul 2008 11:27:57 -0000	1.134
+++ Src/exec.c	28 Jul 2008 17:27:13 -0000
@@ -1376,7 +1376,7 @@
 		    pipe(synch);
 
 		    if ((pid = zfork(&bgtime)) == -1) {
-			trashzleptr();
+			zleentry(ZLE_CMD_TRASH);
 			close(synch[0]);
 			close(synch[1]);
 			fprintf(stderr, "zsh: job can't be suspended\n");
Index: Src/hist.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/hist.c,v
retrieving revision 1.80
diff -u -r1.80 hist.c
--- Src/hist.c	17 Jul 2008 11:27:57 -0000	1.80
+++ Src/hist.c	28 Jul 2008 17:27:13 -0000
@@ -243,7 +243,7 @@
 	return;
     if (qbang && c == bangchar && stophist < 2) {
 	exlast--;
-	zleaddtolineptr('\\');
+	zleentry(ZLE_CMD_ADD_TO_LINE, '\\');
     }
     if (excs > zlemetacs) {
 	excs += 1 + inbufct - exlast;
@@ -253,7 +253,7 @@
 	    excs = zlemetacs;
     }
     exlast = inbufct;
-    zleaddtolineptr(itok(c) ? ztokens[c - Pound] : c);
+    zleentry(ZLE_CMD_ADD_TO_LINE, itok(c) ? ztokens[c - Pound] : c);
 }
 
 
@@ -2565,12 +2565,7 @@
 	int ll, cs;
 	char *linein;
 
-	if (zlegetlineptr) {
-	    linein = (char *)zlegetlineptr(&ll, &cs);
-	} else {
-	    linein = ztrdup("");
-	    ll = cs = 0;
-	}
+	linein = zleentry(ZLE_CMD_GET_LINE, &ll, &cs);
 	zlemetall = ll + 1; /* length of line plus space added below */
 	zlemetacs = cs;
 
Index: Src/init.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/init.c,v
retrieving revision 1.86
diff -u -r1.86 init.c
--- Src/init.c	17 Jul 2008 11:27:57 -0000	1.86
+++ Src/init.c	28 Jul 2008 17:27:13 -0000
@@ -84,11 +84,6 @@
 /**/
 mod_export int tccolours;
 
-/* Pointer to read-key function from zle */
-
-/**/
-mod_export int (*getkeyptr) _((long, int *));
-
 /* SIGCHLD mask */
 
 /**/
@@ -717,8 +712,6 @@
     zero_mnumber.type = MN_INTEGER;
     zero_mnumber.u.l = 0;
 
-    getkeyptr = NULL;
-
     lineno = 1;
     noeval = 0;
     curhist = 0;
@@ -1181,84 +1174,94 @@
     /* do nothing */
 }
 
-/* ZLE entry point pointers.  They are defined here because the initial *
- * values depend on whether ZLE is linked in or not -- if it is, we     *
- * avoid wasting space with the fallback functions.  No other source    *
- * file needs to know which modules are linked in.                      */
-
-#ifdef LINKED_XMOD_zshQszle
-
-/**/
-mod_export ZleVoidFn trashzleptr = noop_function;
-/**/
-mod_export ZleVoidFn zle_resetpromptptr = noop_function;
-/**/
-mod_export ZleVoidFn zrefreshptr = noop_function;
-/**/
-mod_export ZleVoidIntFn zleaddtolineptr = noop_function_int;
+/*
+ * ZLE entry point pointer.
+ * No other source file needs to know which modules are linked in.
+ */
 /**/
-mod_export ZleGetLineFn zlegetlineptr = NULL;
+mod_export ZleEntryPoint zle_entry_ptr;
+
+/*
+ * State of loading of zle.
+ * 0 = Not loaded, not attempted.
+ * 1 = Loaded successfully
+ * 2 = Failed to load.
+ */
 /**/
-mod_export ZleReadFn zlereadptr = autoload_zleread;
+mod_export int zle_load_state;
+
 /**/
-mod_export ZleVoidIntFn zlesetkeymapptr = noop_function_int;
+mod_export char *
+zleentry(VA_ALIST1(int cmd))
+VA_DCL
+{
+#if defined(LINKED_XMOD_zshQszle) || defined(UNLINKED_XMOD_zshQszle)
+    va_list ap;
+    VA_DEF_ARG(int cmd);
 
-#else /* !LINKED_XMOD_zshQszle */
+    VA_START(ap, cmd);
+    VA_GET_ARG(ap, cmd, int);
 
-mod_export ZleVoidFn trashzleptr = noop_function;
-mod_export ZleVoidFn zle_resetpromptptr = noop_function;
-mod_export ZleVoidFn zrefreshptr = noop_function;
-mod_export ZleVoidIntFn zleaddtolineptr = noop_function_int;
-mod_export ZleGetLineFn zlegetlineptr = NULL;
-# ifdef UNLINKED_XMOD_zshQszle
-mod_export ZleReadFn zlereadptr = autoload_zleread;
-mod_export ZleVoidIntFn zlesetkeymapptr = autoload_zlesetkeymap;
-# else /* !UNLINKED_XMOD_zshQszle */
-mod_export ZleReadFn zlereadptr = fallback_zleread;
-mod_export ZleVoidIntFn zlesetkeymapptr = noop_function_int;
-# endif /* !UNLINKED_XMOD_zshQszle */
+    /* autoload */
+    switch (zle_load_state) {
+    case 0:
+	if (load_module("zsh/zle", NULL, 0) != 1) {
+	    (void)load_module("zsh/compctl", NULL, 0);
+	    return zle_entry_ptr(cmd, ap);
+	} else {
+	    zle_load_state = 2;
+	    /* Execute fallback code below */
+	}
+	break;
 
-#endif /* !LINKED_XMOD_zshQszle */
+    case 1:
+	return zle_entry_ptr(cmd, ap);
 
-/**/
-char *
-autoload_zleread(char **lp, char **rp, int ha, int con)
-{
-    zlereadptr = fallback_zleread;
-    if (load_module("zsh/zle", NULL, 0) != 1)
-	(void)load_module("zsh/compctl", NULL, 0);
-    return zlereadptr(lp, rp, ha, con);
-}
+    case 2:
+	break;
+    }
+#endif
 
-/**/
-mod_export char *
-fallback_zleread(char **lp, UNUSED(char **rp), UNUSED(int ha), UNUSED(int con))
-{
-    char *pptbuf;
-    int pptlen;
+    switch (cmd) {
+	/*
+	 * Only the read command really needs a fallback if zle
+	 * is not available.  ZLE_CMD_GET_LINE has traditionally
+	 * had local code in bufferwords() to do this, but that'
+	 * probably only because bufferwords() is part of completion
+	 * and so everything to do with it is horribly complicated.
+	 */
+    case ZLE_CMD_READ:
+    {
+	char *pptbuf, **lp;
+	int pptlen;
 
-    pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL, NULL),
-		      &pptlen);
-    write(2, (WRITE_ARG_2_T)pptbuf, pptlen);
-    free(pptbuf);
+	lp = va_arg(ap, char **);
 
-    return shingetline();
-}
+	pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL,
+				       NULL),
+			  &pptlen);
+	write(2, (WRITE_ARG_2_T)pptbuf, pptlen);
+	free(pptbuf);
 
-/**/
-#ifdef UNLINKED_XMOD_zshQszle
+	return shingetline();
+    }
 
-/**/
-static void
-autoload_zlesetkeymap(int mode)
-{
-    zlesetkeymapptr = noop_function_int;
-    (void)load_module("zsh/zle", NULL, 0);
-    (*zlesetkeymapptr)(mode);
-}
+    case ZLE_CMD_GET_LINE:
+    {
+	int *ll, *cs;
 
-/**/
+	ll = va_arg(ap, int *);
+	cs = va_arg(ap, int *);
+	*ll = *cs = 0;
+	return ztrdup("");
+    }
+    }
+
+#if defined(LINKED_XMOD_zshQszle) || defined(UNLINKED_XMOD_zshQszle)
+    va_end(ap);
 #endif
+    return NULL;
+}
 
 /* compctl entry point pointers.  Similar to the ZLE ones. */
 
Index: Src/input.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/input.c,v
retrieving revision 1.16
diff -u -r1.16 input.c
--- Src/input.c	12 May 2008 13:50:42 -0000	1.16
+++ Src/input.c	28 Jul 2008 17:27:13 -0000
@@ -275,7 +275,8 @@
 	int flags = ZLRF_HISTORY|ZLRF_NOSETTY;
 	if (isset(IGNOREEOF))
 	    flags |= ZLRF_IGNOREEOF;
-	ingetcline = zlereadptr(ingetcpmptl, ingetcpmptr, flags, context);
+	ingetcline = zleentry(ZLE_CMD_READ, ingetcpmptl, ingetcpmptr,
+			      flags, context);
 	histdone |= HISTFLAG_SETTY;
     }
     if (!ingetcline) {
Index: Src/jobs.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/jobs.c,v
retrieving revision 1.63
diff -u -r1.63 jobs.c
--- Src/jobs.c	2 May 2008 22:48:58 -0000	1.63
+++ Src/jobs.c	28 Jul 2008 17:27:13 -0000
@@ -459,7 +459,7 @@
     if ((isset(NOTIFY) || job == thisjob) && (jn->stat & STAT_LOCKED)) {
 	if (printjob(jn, !!isset(LONGLISTJOBS), 0) &&
 	    zleactive)
-	    zrefreshptr();
+	    zleentry(ZLE_CMD_REFRESH);
     }
     if (sigtrapped[SIGCHLD] && job != thisjob)
 	dotrap(SIGCHLD);
@@ -895,7 +895,7 @@
 	Process qn;
 
 	if (!synch)
-	    trashzleptr();
+	    zleentry(ZLE_CMD_TRASH);
 	if (doputnl && !synch) {
 	    doneprint = 1;
 	    putc('\n', fout);
Index: Src/loop.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/loop.c,v
retrieving revision 1.24
diff -u -r1.24 loop.c
--- Src/loop.c	12 May 2008 13:50:42 -0000	1.24
+++ Src/loop.c	28 Jul 2008 17:27:13 -0000
@@ -245,7 +245,8 @@
 		    int oef = errflag;
 
 		    isfirstln = 1;
-		    str = zlereadptr(&prompt3, NULL, 0, ZLCON_SELECT);
+		    str = zleentry(ZLE_CMD_READ, &prompt3, NULL,
+				   0, ZLCON_SELECT);
 		    if (errflag)
 			str = NULL;
 		    errflag = oef;
@@ -313,7 +314,7 @@
     size_t longest = 1, fct, fw = 0, colsz, t0, t1, ct;
     char **arr, **ap;
 
-    trashzleptr();
+    zleentry(ZLE_CMD_TRASH);
     arr = hlinklist2array(l, 0);
     for (ap = arr; *ap; ap++)
 	if (strlen(*ap) > longest)
Index: Src/options.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/options.c,v
retrieving revision 1.42
diff -u -r1.42 options.c
--- Src/options.c	12 Jun 2008 13:45:06 -0000	1.42
+++ Src/options.c	28 Jul 2008 17:27:13 -0000
@@ -724,7 +724,7 @@
 	    return -1;
 #endif /* GETPWNAM_FAKED */
     } else if ((optno == EMACSMODE || optno == VIMODE) && value) {
-	(*zlesetkeymapptr)(optno);
+	zleentry(ZLE_CMD_SET_KEYMAP, optno);
 	opts[(optno == EMACSMODE) ? VIMODE : EMACSMODE] = 0;
     }
     opts[optno] = value;
Index: Src/signals.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/signals.c,v
retrieving revision 1.46
diff -u -r1.46 signals.c
--- Src/signals.c	2 May 2008 22:48:58 -0000	1.46
+++ Src/signals.c	28 Jul 2008 17:27:14 -0000
@@ -1213,7 +1213,7 @@
      * need to restore the display.
      */
     if (zleactive && resetneeded)
-	zrefreshptr();
+	zleentry(ZLE_CMD_REFRESH);
 
     if (*sigtr != ZSIG_IGNORED)
 	*sigtr &= ~ZSIG_IGNORED;
Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.197
diff -u -r1.197 utils.c
--- Src/utils.c	17 Jul 2008 11:27:57 -0000	1.197
+++ Src/utils.c	28 Jul 2008 17:27:14 -0000
@@ -108,7 +108,7 @@
 zwarning(const char *cmd, const char *fmt, va_list ap)
 {
     if (isatty(2))
-	trashzleptr();
+	zleentry(ZLE_CMD_TRASH);
 
     if (cmd) {
 	if (unset(SHINSTDIN) || locallevel) {
@@ -1573,8 +1573,8 @@
 	winchanged =
 #endif /* TIOCGWINSZ */
 	    resetneeded = 1;
-	zrefreshptr();
-	zle_resetpromptptr();
+	zleentry(ZLE_CMD_REFRESH);
+	zleentry(ZLE_CMD_RESET_PROMPT);
     }
 }
 
Index: Src/zsh.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v
retrieving revision 1.138
diff -u -r1.138 zsh.h
--- Src/zsh.h	12 Jun 2008 13:45:06 -0000	1.138
+++ Src/zsh.h	28 Jul 2008 17:27:14 -0000
@@ -2373,12 +2373,22 @@
 
 typedef int (*CompctlReadFn) _((char *, char **, Options, char *));
 
-/* ZLE entry point pointers */
+/* ZLE entry point pointer */
 
-typedef void (*ZleVoidFn) _((void));
-typedef void (*ZleVoidIntFn) _((int));
-typedef char *(*ZleReadFn) _((char **, char **, int, int));
-typedef char *(*ZleGetLineFn) _((int *, int *));
+typedef char * (*ZleEntryPoint)(int cmd, va_list ap);
+
+/* Commands to pass to entry point */
+
+enum {
+    ZLE_CMD_GET_LINE,
+    ZLE_CMD_READ,
+    ZLE_CMD_ADD_TO_LINE,
+    ZLE_CMD_TRASH,
+    ZLE_CMD_RESET_PROMPT,
+    ZLE_CMD_REFRESH,
+    ZLE_CMD_SET_KEYMAP,
+    ZLE_CMD_GET_KEY
+};
 
 /***************************************/
 /* Hooks in core.                      */
Index: Src/Zle/zle_main.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_main.c,v
retrieving revision 1.113
diff -u -r1.113 zle_main.c
--- Src/Zle/zle_main.c	17 Jul 2008 11:27:57 -0000	1.113
+++ Src/Zle/zle_main.c	28 Jul 2008 17:27:14 -0000
@@ -1809,6 +1809,72 @@
     return 0;
 }
 
+static char *
+zle_main_entry(int cmd, va_list ap)
+{
+    switch (cmd) {
+    case ZLE_CMD_GET_LINE:
+    {
+	int *ll, *cs;
+	ll = va_arg(ap, int *);
+	cs = va_arg(ap, int *);
+	return zlegetline(ll, cs);
+    }
+
+    case ZLE_CMD_READ:
+    {
+	char **lp, **rp;
+	int flags, context;
+
+	lp = va_arg(ap, char **);
+	rp = va_arg(ap, char **);
+	flags = va_arg(ap, int);
+	context = va_arg(ap, int);
+
+	return zleread(lp, rp, flags, context);
+    }
+
+    case ZLE_CMD_ADD_TO_LINE:
+	zleaddtoline(va_arg(ap, int));
+	break;
+
+    case ZLE_CMD_TRASH:
+	trashzle();
+	break;
+
+    case ZLE_CMD_RESET_PROMPT:
+	zle_resetprompt();
+	break;
+
+    case ZLE_CMD_REFRESH:
+	zrefresh();
+	break;
+
+    case ZLE_CMD_SET_KEYMAP:
+	zlesetkeymap(va_arg(ap, int));
+	break;
+
+    case ZLE_CMD_GET_KEY:
+    {
+	long do_keytmout;
+	int *timeout, *chrp;
+
+	do_keytmout = va_arg(ap, long);
+	timeout = va_arg(ap, int *);
+	chrp = va_arg(ap, int *);
+	*chrp = getbyte(do_keytmout, timeout);
+	break;
+    }
+
+    default:
+#ifdef DEBUG
+	    dputs("Bad command %d in zle_main_entry", cmd);
+#endif
+	    break;
+    }
+    return NULL;
+}
+
 static struct builtin bintab[] = {
     BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaM:ldDANmrsLRp", NULL),
     BUILTIN("vared",   0, bin_vared,   1,  1, 0, "aAcehM:m:p:r:", NULL),
@@ -1849,15 +1915,8 @@
 setup_(UNUSED(Module m))
 {
     /* Set up editor entry points */
-    trashzleptr = trashzle;
-    zle_resetpromptptr = zle_resetprompt;
-    zrefreshptr = zrefresh;
-    zleaddtolineptr = zleaddtoline;
-    zlegetlineptr = zlegetline;
-    zlereadptr = zleread;
-    zlesetkeymapptr = zlesetkeymap;
-
-    getkeyptr = getbyte;
+    zle_entry_ptr = zle_main_entry;
+    zle_load_state = 1;
 
     /* initialise the thingies */
     init_thingies();
@@ -1949,15 +2008,8 @@
 	zfree(vibuf[i].buf, vibuf[i].len);
 
     /* editor entry points */
-    trashzleptr = noop_function;
-    zle_resetpromptptr = noop_function;
-    zrefreshptr = noop_function;
-    zleaddtolineptr = noop_function_int;
-    zlegetlineptr = NULL;
-    zlereadptr = fallback_zleread;
-    zlesetkeymapptr= noop_function_int;
-
-    getkeyptr = NULL;
+    zle_entry_ptr = (ZleEntryPoint)0;
+    zle_load_state = 0;
 
     zfree(clwords, clwsize * sizeof(char *));
     zle_refresh_finish();


-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070



Messages sorted by: Reverse Date, Date, Thread, Author