about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--INSTALL3
-rw-r--r--Src/Zle/complist.c6
-rw-r--r--Src/utils.c44
-rw-r--r--Src/zsh.h2
5 files changed, 43 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 58c26c9b2..8cb8d2b96 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-03-29  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 23248: INSTALL, Src/utils.c, Src/zsh.h, Src/Zle/complist.c:
+	bug with completion lists on last line of group just shorter than
+	the line length; if compiled with debugging, ZSH_DEBUG_LOG is used
+	for dputs() output.
+
 2007-03-29  Clint Adams  <clint@zsh.org>
 
 	* unposted: Completion/Unix/Command/.distfiles: update
diff --git a/INSTALL b/INSTALL
index 7f604a27a..783aea57c 100644
--- a/INSTALL
+++ b/INSTALL
@@ -326,6 +326,9 @@ This enables the builtin "hashinfo".
 To add some sanity checks and generate debugging information for debuggers
 you can use the following option.  This also disables optimization.
  --enable-zsh-debug            # use it if you want to debug zsh
+In this mode, zsh may output extra information about internal errors
+to stderr.  The shell variable ZSH_DEBUG_LOG may be set to another file
+to which errors will be appended.
 
 Startup/shutdown files
 ----------------------
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index f06a5e8f4..43c93cf54 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -1139,6 +1139,10 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop)
 	    if (dopr == 1) {
 		if (ml == mlend - 1 && (cc % columns) == columns - 1) {
 		    dopr = 0;
+		    if (*p == Meta)
+			p += 2;
+		    else
+			p++;
 		    continue;
 		}
 		while (len--) {
@@ -1580,6 +1584,8 @@ clprintm(Cmgroup g, Cmatch *mp, int mc, int ml, int lastc, int width)
     Cmatch m;
     int len, subcols = 0, stop = 0, ret = 0;
 
+    DPUTS2(ml >= mlines, "clprintm called with ml too large (%d/%d)",
+	   ml, mlines);
     if (g != last_group)
         *last_cap = '\0';
 
diff --git a/Src/utils.c b/Src/utils.c
index 0e8404209..0c436029b 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -129,7 +129,7 @@ zwarning(const char *cmd, const char *fmt, va_list ap)
 	fputc((unsigned char)':', stderr);
     }
 
-    zerrmsg(fmt, ap);
+    zerrmsg(stderr, fmt, ap);
 }
 
 
@@ -218,14 +218,20 @@ mod_export void
 dputs(VA_ALIST1(const char *message))
 VA_DCL
 {
+    char *filename;
+    FILE *file;
     va_list ap;
     VA_DEF_ARG(const char *message);
 
     VA_START(ap, message);
     VA_GET_ARG(ap, message, const char *);
-    zerrmsg(message, ap);
+    if ((filename = getsparam("ZSH_DEBUG_LOG")) != NULL &&
+	(file = fopen(filename, "a")) != NULL) {
+	zerrmsg(file, message, ap);
+	fclose(file);
+    } else
+	zerrmsg(stderr, message, ap);
     va_end(ap);
-    fflush(stderr);
 }
 
 #endif /* DEBUG */
@@ -245,15 +251,15 @@ zz_plural_z_alpha(void)
 
 /**/
 void
-zerrmsg(const char *fmt, va_list ap)
+zerrmsg(FILE *file, const char *fmt, va_list ap)
 {
     const char *str;
     int num;
 
     if ((unset(SHINSTDIN) || locallevel) && lineno)
-	fprintf(stderr, "%ld: ", (long)lineno);
+	fprintf(file, "%ld: ", (long)lineno);
     else
-	fputc((unsigned char)' ', stderr);
+	fputc((unsigned char)' ', file);
 
     while (*fmt)
 	if (*fmt == '%') {
@@ -261,7 +267,7 @@ zerrmsg(const char *fmt, va_list ap)
 	    switch (*fmt++) {
 	    case 's':
 		str = va_arg(ap, const char *);
-		nicezputs(str, stderr);
+		nicezputs(str, file);
 		break;
 	    case 'l': {
 		char *s;
@@ -271,50 +277,50 @@ zerrmsg(const char *fmt, va_list ap)
 		s = zhalloc(num + 1);
 		memcpy(s, str, num);
 		s[num] = '\0';
-		nicezputs(s, stderr);
+		nicezputs(s, file);
 		break;
 	    }
 	    case 'd':
 		num = va_arg(ap, int);
-		fprintf(stderr, "%d", num);
+		fprintf(file, "%d", num);
 		break;
 	    case '%':
-		putc('%', stderr);
+		putc('%', file);
 		break;
 	    case 'c':
 		num = va_arg(ap, int);
 #ifdef MULTIBYTE_SUPPORT
 		mb_metacharinit();
-		zputs(wcs_nicechar(num, NULL, NULL), stderr);
+		zputs(wcs_nicechar(num, NULL, NULL), file);
 #else
-		zputs(nicechar(num), stderr);
+		zputs(nicechar(num), file);
 #endif
 		break;
 	    case 'e':
 		/* print the corresponding message for this errno */
 		num = va_arg(ap, int);
 		if (num == EINTR) {
-		    fputs("interrupt\n", stderr);
+		    fputs("interrupt\n", file);
 		    errflag = 1;
 		    return;
 		}
 		/* If the message is not about I/O problems, it looks better *
 		 * if we uncapitalize the first letter of the message        */
 		if (num == EIO)
-		    fputs(strerror(num), stderr);
+		    fputs(strerror(num), file);
 		else {
 		    char *errmsg = strerror(num);
-		    fputc(tulower(errmsg[0]), stderr);
-		    fputs(errmsg + 1, stderr);
+		    fputc(tulower(errmsg[0]), file);
+		    fputs(errmsg + 1, file);
 		}
 		break;
 	    }
 	} else {
-	    putc(*fmt == Meta ? *++fmt ^ 32 : *fmt, stderr);
+	    putc(*fmt == Meta ? *++fmt ^ 32 : *fmt, file);
 	    fmt++;
 	}
-    putc('\n', stderr);
-    fflush(stderr);
+    putc('\n', file);
+    fflush(file);
 }
 
 /* Output a single character, for the termcap routines.     *
diff --git a/Src/zsh.h b/Src/zsh.h
index a1bdbb036..d6e3d987a 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1925,10 +1925,12 @@ struct heap {
 # define DPUTS(X,Y) if (!(X)) {;} else dputs(ERRMSG(Y))
 # define DPUTS1(X,Y,Z1) if (!(X)) {;} else dputs(ERRMSG(Y), Z1)
 # define DPUTS2(X,Y,Z1,Z2) if (!(X)) {;} else dputs(ERRMSG(Y), Z1, Z2)
+# define DPUTS3(X,Y,Z1,Z2,Z3) if (!(X)) {;} else dputs(ERRMSG(Y), Z1, Z2, Z3)
 #else
 # define DPUTS(X,Y)
 # define DPUTS1(X,Y,Z1)
 # define DPUTS2(X,Y,Z1,Z2)
+# define DPUTS3(X,Y,Z1,Z2,Z3)
 #endif
 
 /**************************/