about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2006-05-30 22:35:03 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2006-05-30 22:35:03 +0000
commitdd5602f59b599177fb130512fc543f7efa951990 (patch)
tree93f50c0abbbc61dbea120afb6f497afe6b976fea
parentfd240e09b05ca15aa1deef35733124b6852fe809 (diff)
downloadzsh-dd5602f59b599177fb130512fc543f7efa951990.tar.gz
zsh-dd5602f59b599177fb130512fc543f7efa951990.tar.xz
zsh-dd5602f59b599177fb130512fc543f7efa951990.zip
22474: use variable argument lists to improve error message handling
-rw-r--r--ChangeLog5
-rw-r--r--Src/Builtins/rlimits.c60
-rw-r--r--Src/Builtins/sched.c14
-rw-r--r--Src/Modules/cap.c8
-rw-r--r--Src/Modules/clone.c10
-rw-r--r--Src/Modules/datetime.c4
-rw-r--r--Src/Modules/files.c14
-rw-r--r--Src/Modules/langinfo.c2
-rw-r--r--Src/Modules/mathfunc.c2
-rw-r--r--Src/Modules/parameter.c22
-rw-r--r--Src/Modules/pcre.c13
-rw-r--r--Src/Modules/socket.c28
-rw-r--r--Src/Modules/stat.c26
-rw-r--r--Src/Modules/system.c12
-rw-r--r--Src/Modules/tcp.c47
-rw-r--r--Src/Modules/termcap.c6
-rw-r--r--Src/Modules/terminfo.c6
-rw-r--r--Src/Modules/zftp.c88
-rw-r--r--Src/Modules/zpty.c28
-rw-r--r--Src/Modules/zselect.c21
-rw-r--r--Src/Modules/zutil.c42
-rw-r--r--Src/Zle/compctl.c125
-rw-r--r--Src/Zle/complete.c47
-rw-r--r--Src/Zle/complist.c3
-rw-r--r--Src/Zle/computil.c126
-rw-r--r--Src/Zle/deltochar.c3
-rw-r--r--Src/Zle/zle_keymap.c42
-rw-r--r--Src/Zle/zle_main.c23
-rw-r--r--Src/Zle/zle_thingy.c44
-rw-r--r--Src/Zle/zle_tricky.c2
-rw-r--r--Src/builtin.c238
-rw-r--r--Src/cond.c16
-rw-r--r--Src/exec.c72
-rw-r--r--Src/glob.c54
-rw-r--r--Src/hist.c44
-rw-r--r--Src/init.c21
-rw-r--r--Src/input.c4
-rw-r--r--Src/jobs.c50
-rw-r--r--Src/lex.c8
-rw-r--r--Src/loop.c2
-rw-r--r--Src/math.c47
-rw-r--r--Src/mem.c8
-rw-r--r--Src/modentry.c24
-rw-r--r--Src/module.c104
-rw-r--r--Src/options.c16
-rw-r--r--Src/params.c58
-rw-r--r--Src/parse.c49
-rw-r--r--Src/signals.c8
-rw-r--r--Src/subst.c43
-rw-r--r--Src/system.h4
-rw-r--r--Src/utils.c122
-rw-r--r--configure.ac3
52 files changed, 937 insertions, 931 deletions
diff --git a/ChangeLog b/ChangeLog
index 29b95ab81..6caf6c80e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2006-05-30  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 22474: most source files touched: use stdarg.h to implement
+	escape handling in error messages properly.
+
 2006-05-30  Wayne Davison  <wayned@users.sourceforge.net>
 
 	* unposted: Completion/Unix/Command/_rsync: some option changes
diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c
index 922a182a2..e7df978a9 100644
--- a/Src/Builtins/rlimits.c
+++ b/Src/Builtins/rlimits.c
@@ -161,7 +161,7 @@ showlimits(char *nam, int hard, int lim)
 	struct rlimit vals;
 	if (getrlimit(lim, &vals) < 0)
 	{
-	    zwarnnam(nam, "can't read limit: %e", NULL, errno);
+	    zwarnnam(nam, "can't read limit: %e", errno);
 	    return 1;
 	}
 	showlimitvalue(lim, hard ? vals.rlim_max : vals.rlim_cur);
@@ -199,7 +199,7 @@ printulimit(char *nam, int lim, int hard, int head)
 
 	if (getrlimit(lim, &vals) < 0)
 	{
-	    zwarnnam(nam, "can't read limit: %e", NULL, errno);
+	    zwarnnam(nam, "can't read limit: %e", errno);
 	    return 1;
 	}
 	limit = (hard) ? vals.rlim_max : vals.rlim_cur;
@@ -378,13 +378,13 @@ do_limit(char *nam, int lim, rlim_t val, int hard, int soft, int set)
 	if (getrlimit(lim, &vals) < 0)
 	{
 	    /* best guess about error */
-	    zwarnnam(nam, "can't read limit: %e", NULL, errno);
+	    zwarnnam(nam, "can't read limit: %e", errno);
 	    return 1;
 	}
 	if (hard)
 	{
 	    if (val > vals.rlim_max && geteuid()) {
-		zwarnnam(nam, "can't raise hard limits", NULL, 0);
+		zwarnnam(nam, "can't raise hard limits");
 		return 1;
 	    }
 	    vals.rlim_max = val;
@@ -397,7 +397,7 @@ do_limit(char *nam, int lim, rlim_t val, int hard, int soft, int set)
 	}
 	if (soft || !hard) {
 	    if (val > vals.rlim_max) {
-		zwarnnam(nam, "limit exceeds hard limit", NULL, 0);
+		zwarnnam(nam, "limit exceeds hard limit");
 		return 1;
 	    }
 	    else
@@ -407,12 +407,12 @@ do_limit(char *nam, int lim, rlim_t val, int hard, int soft, int set)
 	{
 	    zwarnnam(nam,
 		     "warning: unrecognised limit %d, use -s to set",
-		     NULL, lim);
+		     lim);
 	    return 1;
 	}
 	else if (setrlimit(lim, &vals) < 0)
 	{
-	    zwarnnam(nam, "setrlimit failed: %e", NULL, errno);
+	    zwarnnam(nam, "setrlimit failed: %e", errno);
 	    return 1;
 	}
     } else {
@@ -421,7 +421,7 @@ do_limit(char *nam, int lim, rlim_t val, int hard, int soft, int set)
 	if (hard) {
 	    /* can only raise hard limits if running as root */
 	    if (val > current_limits[lim].rlim_max && geteuid()) {
-		zwarnnam(nam, "can't raise hard limits", NULL, 0);
+		zwarnnam(nam, "can't raise hard limits");
 		return 1;
 	    } else {
 		limits[lim].rlim_max = val;
@@ -436,13 +436,13 @@ do_limit(char *nam, int lim, rlim_t val, int hard, int soft, int set)
 		{
 		    /* ulimit does this */
 		    if (val > current_limits[lim].rlim_max && geteuid()) {
-			zwarnnam(nam, "value exceeds hard limit", NULL, 0);
+			zwarnnam(nam, "value exceeds hard limit");
 			return 1;
 		    }
 		    limits[lim].rlim_max = limits[lim].rlim_cur = val;
 		} else {
 		    /* but limit does this */
-		    zwarnnam(nam, "limit exceeds hard limit", NULL, 0);
+		    zwarnnam(nam, "limit exceeds hard limit");
 		    return 1;
 		}
 	    } else
@@ -493,7 +493,7 @@ bin_limit(char *nam, char **argv, Options ops, UNUSED(int func))
 	if (lim < 0) {
 	    zwarnnam(nam,
 		     (lim == -2) ? "ambiguous resource specification: %s"
-		     : "no such resource: %s", s, 0);
+		     : "no such resource: %s", s);
 	    return 1;
 	}
 	/* without value for limit, display the current limit */
@@ -505,7 +505,7 @@ bin_limit(char *nam, char **argv, Options ops, UNUSED(int func))
 	    if (*s)
 	    {
 		/* unknown limit, no idea how to scale */
-		zwarnnam(nam, "unknown scaling factor: %s", s, 0);
+		zwarnnam(nam, "unknown scaling factor: %s", s);
 		return 1;
 	    }
 	}
@@ -523,7 +523,7 @@ bin_limit(char *nam, char **argv, Options ops, UNUSED(int func))
 		else if (*s == ':')
 		    val = val * 60 + zstrtorlimt(s + 1, &s, 10);
 		else {
-		    zwarnnam(nam, "unknown scaling factor: %s", s, 0);
+		    zwarnnam(nam, "unknown scaling factor: %s", s);
 		    return 1;
 		}
 	    }
@@ -533,7 +533,7 @@ bin_limit(char *nam, char **argv, Options ops, UNUSED(int func))
 	    char *t = s;
 	    val = zstrtorlimt(t, &s, 10);
 	    if (s == t) {
-		zwarnnam(nam, "limit must be a number", NULL, 0);
+		zwarnnam(nam, "limit must be a number");
 		return 1;
 	    }
 	} else {
@@ -546,7 +546,7 @@ bin_limit(char *nam, char **argv, Options ops, UNUSED(int func))
 	    } else if ((*s == 'M' || *s == 'm') && !s[1])
 		val *= 1024L * 1024;
 	    else {
-		zwarnnam(nam, "unknown scaling factor: %s", s, 0);
+		zwarnnam(nam, "unknown scaling factor: %s", s);
 		return 1;
 	    }
 	}
@@ -565,12 +565,12 @@ do_unlimit(char *nam, int lim, int hard, int soft, int set, int euid)
 	struct rlimit vals;
 	if (getrlimit(lim, &vals) < 0)
 	{
-	    zwarnnam(nam, "can't read limit: %e", NULL, errno);
+	    zwarnnam(nam, "can't read limit: %e", errno);
 	    return 1;
 	}
 	if (hard) {
 	    if (euid && vals.rlim_max != RLIM_INFINITY) {
-		zwarnnam(nam, "can't remove hard limits", NULL, 0);
+		zwarnnam(nam, "can't remove hard limits");
 		return 1;
 	    } else
 		vals.rlim_max = RLIM_INFINITY;
@@ -579,17 +579,16 @@ do_unlimit(char *nam, int lim, int hard, int soft, int set, int euid)
 	    vals.rlim_cur = vals.rlim_max;
 	if (!set) {
 	    zwarnnam(nam,
-		     "warning: unrecognised limit %d, use -s to set",
-		     NULL, lim);
+		     "warning: unrecognised limit %d, use -s to set", lim);
 	    return 1;
 	} else if (setrlimit(lim, &vals) < 0) {
-	    zwarnnam(nam, "setrlimit failed: %e", NULL, errno);
+	    zwarnnam(nam, "setrlimit failed: %e", errno);
 	    return 1;
 	}
     } else {
 	if (hard) {
 	    if (euid && current_limits[lim].rlim_max != RLIM_INFINITY) {
-		zwarnnam(nam, "can't remove hard limits", NULL, 0);
+		zwarnnam(nam, "can't remove hard limits");
 		return 1;
 	    } else
 		limits[lim].rlim_max = RLIM_INFINITY;
@@ -628,7 +627,7 @@ bin_unlimit(char *nam, char **argv, Options ops, UNUSED(int func))
 	if (OPT_ISSET(ops,'s'))
 	    ret += setlimits(nam);
 	if (ret)
-	    zwarnnam(nam, "can't remove hard limits", NULL, 0);
+	    zwarnnam(nam, "can't remove hard limits");
     } else {
 	for (; *argv; argv++) {
 	    /* Search for the appropriate resource name.  When a name     *
@@ -651,7 +650,7 @@ bin_unlimit(char *nam, char **argv, Options ops, UNUSED(int func))
 	    if (lim < 0) {
 		zwarnnam(nam,
 			 (lim == -2) ? "ambiguous resource specification: %s"
-			 : "no such resource: %s", *argv, 0);
+			 : "no such resource: %s", *argv);
 		return 1;
 	    }
 	    else if (do_unlimit(nam, lim, hard, !hard, OPT_ISSET(ops, 's'),
@@ -674,7 +673,7 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
     do {
 	options = *argv;
 	if (options && *options == '-' && !options[1]) {
-	    zwarnnam(name, "missing option letter", NULL, 0);
+	    zwarnnam(name, "missing option letter");
 	    return 1;
 	}
 	res = -1;
@@ -697,8 +696,7 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 		    } else if (*argv) {
 			res = (int)zstrtol(*argv++, NULL, 10);
 		    } else {
-			zwarnnam(name, "number required after -N",
-				 NULL, 0);
+			zwarnnam(name, "number required after -N");
 			return 1;
 		    }
 		    /*
@@ -709,8 +707,7 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 		    break;
 		case 'a':
 		    if (resmask) {
-			zwarnnam(name, "no limits allowed with -a",
-				 NULL, 0);
+			zwarnnam(name, "no limits allowed with -a");
 			return 1;
 		    }
 		    all = 1;
@@ -778,7 +775,7 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 # endif
 		default:
 		    /* unrecognised limit */
-		    zwarnnam(name, "bad option: -%c", NULL, *options);
+		    zwarnnam(name, "bad option: -%c", *options);
 		    return 1;
 		}
 		if (options[1]) {
@@ -786,8 +783,7 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 		    nres++;
 		}
 		if (all && res != -1) {
-		    zwarnnam(name, "no limits allowed with -a",
-			     NULL, 0);
+		    zwarnnam(name, "no limits allowed with -a");
 		    return 1;
 		}
 	    }
@@ -804,7 +800,7 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 	    continue;
 	}
 	if (all) {
-	    zwarnnam(name, "no arguments allowed after -a", NULL, 0);
+	    zwarnnam(name, "no arguments allowed after -a");
 	    return 1;
 	}
 	if (res < 0)
diff --git a/Src/Builtins/sched.c b/Src/Builtins/sched.c
index 0c96b76b2..558a00ba6 100644
--- a/Src/Builtins/sched.c
+++ b/Src/Builtins/sched.c
@@ -61,13 +61,13 @@ bin_sched(UNUSED(char *nam), char **argv, UNUSED(Options ops), UNUSED(int func))
 	sn = atoi(s + 1);
 
 	if (!sn) {
-	    zwarnnam("sched", "usage for delete: sched -<item#>.", NULL, 0);
+	    zwarnnam("sched", "usage for delete: sched -<item#>.");
 	    return 1;
 	}
 	for (schl = (struct schedcmd *)&schedcmds, sch = schedcmds, sn--;
 	     sch && sn; sch = (schl = sch)->next, sn--);
 	if (!sch) {
-	    zwarnnam("sched", "not that many entries", NULL, 0);
+	    zwarnnam("sched", "not that many entries");
 	    return 1;
 	}
 	schl->next = sch->next;
@@ -91,7 +91,7 @@ bin_sched(UNUSED(char *nam), char **argv, UNUSED(Options ops), UNUSED(int func))
     } else if (!*argv) {
 	/* other than the two cases above, sched *
 	 *requires at least two arguments        */
-	zwarnnam("sched", "not enough arguments", NULL, 0);
+	zwarnnam("sched", "not enough arguments");
 	return 1;
     }
 
@@ -104,12 +104,12 @@ bin_sched(UNUSED(char *nam), char **argv, UNUSED(Options ops), UNUSED(int func))
 	offset is simply added to the current time. */
 	h = zstrtol(s + 1, &s, 10);
 	if (*s != ':') {
-	    zwarnnam("sched", "bad time specifier", NULL, 0);
+	    zwarnnam("sched", "bad time specifier");
 	    return 1;
 	}
 	m = zstrtol(s + 1, &s, 10);
 	if (*s) {
-	    zwarnnam("sched", "bad time specifier", NULL, 0);
+	    zwarnnam("sched", "bad time specifier");
 	    return 1;
 	}
 	t = time(NULL) + h * 3600 + m * 60;
@@ -120,12 +120,12 @@ bin_sched(UNUSED(char *nam), char **argv, UNUSED(Options ops), UNUSED(int func))
 	are ignored. */
 	h = zstrtol(s, &s, 10);
 	if (*s != ':') {
-	    zwarnnam("sched", "bad time specifier", NULL, 0);
+	    zwarnnam("sched", "bad time specifier");
 	    return 1;
 	}
 	m = zstrtol(s + 1, &s, 10);
 	if (*s && *s != 'a' && *s != 'A' && *s != 'p' && *s != 'P') {
-	    zwarnnam("sched", "bad time specifier", NULL, 0);
+	    zwarnnam("sched", "bad time specifier");
 	    return 1;
 	}
 	t = time(NULL);
diff --git a/Src/Modules/cap.c b/Src/Modules/cap.c
index a84e4d246..875b8c4e5 100644
--- a/Src/Modules/cap.c
+++ b/Src/Modules/cap.c
@@ -40,11 +40,11 @@ bin_cap(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
     if(*argv) {
 	caps = cap_from_text(*argv);
 	if(!caps) {
-	    zwarnnam(nam, "invalid capability string", NULL, 0);
+	    zwarnnam(nam, "invalid capability string");
 	    return 1;
 	}
 	if(cap_set_proc(caps)) {
-	    zwarnnam(nam, "can't change capabilites: %e", NULL, errno);
+	    zwarnnam(nam, "can't change capabilites: %e", errno);
 	    ret = 1;
 	}
     } else {
@@ -54,7 +54,7 @@ bin_cap(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
 	if(caps)
 	    result = cap_to_text(caps, &length);
 	if(!caps || !result) {
-	    zwarnnam(nam, "can't get capabilites: %e", NULL, errno);
+	    zwarnnam(nam, "can't get capabilites: %e", errno);
 	    ret = 1;
 	} else
 	    puts(result);
@@ -92,7 +92,7 @@ bin_setcap(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
 
     caps = cap_from_text(*argv++);
     if(!caps) {
-	zwarnnam(nam, "invalid capability string", NULL, 0);
+	zwarnnam(nam, "invalid capability string");
 	return 1;
     }
 
diff --git a/Src/Modules/clone.c b/Src/Modules/clone.c
index 60a21182b..cc303d063 100644
--- a/Src/Modules/clone.c
+++ b/Src/Modules/clone.c
@@ -58,10 +58,10 @@ bin_clone(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	mypid = getpid();
 #ifdef HAVE_SETSID
 	if (setsid() != mypid)
-	    zwarnnam(nam, "failed to create new session: %e", NULL, errno);
+	    zwarnnam(nam, "failed to create new session: %e", errno);
 #elif defined(TIOCNOTTY)
 	    if (ioctl(SHTTY, TIOCNOTTY, 0))
-	    zwarnnam(*args, "%e", NULL, errno);
+	    zwarnnam(*args, "%e", errno);
 	    setpgrp(0L, mypid);
 #endif
 	dup2(ttyfd,0);
@@ -75,7 +75,7 @@ bin_clone(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	/* Acquire a controlling terminal */
 	cttyfd = open(*args, O_RDWR);
 	if (cttyfd == -1)
-	    zwarnnam(nam, "%e", NULL, errno);
+	    zwarnnam(nam, "%e", errno);
 	else {
 #ifdef TIOCSCTTY
 	    ioctl(cttyfd, TIOCSCTTY, 0);
@@ -86,7 +86,7 @@ bin_clone(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	cttyfd = open("/dev/tty", O_RDWR);
 	if (cttyfd == -1)
 	    zwarnnam(nam, "could not make %s my controlling tty, job control "
-		     "disabled", *args, 0);
+		     "disabled", *args);
 	else
 	    close(cttyfd);
 
@@ -98,7 +98,7 @@ bin_clone(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     }
     close(ttyfd);
     if (pid < 0) {
-	zerrnam(nam, "fork failed: %e", NULL, errno);
+	zerrnam(nam, "fork failed: %e", errno);
 	return 1;
     }
     lastpid = pid;
diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c
index 80090a65b..8b5ff5d68 100644
--- a/Src/Modules/datetime.c
+++ b/Src/Modules/datetime.c
@@ -42,7 +42,7 @@ bin_strftime(char *nam, char **argv, Options ops, UNUSED(int func))
     if (OPT_ISSET(ops,'s')) {
 	scalar = OPT_ARG(ops, 's');
 	if (!isident(scalar)) {
-	    zwarnnam(nam, "not an identifier: %s", scalar, 0);
+	    zwarnnam(nam, "not an identifier: %s", scalar);
 	    return 1;
 	}
     }
@@ -52,7 +52,7 @@ bin_strftime(char *nam, char **argv, Options ops, UNUSED(int func))
 	zwarnnam(nam, "%s: %e", argv[1], errno);
 	return 1;
     } else if (*endptr != '\0') {
-	zwarnnam(nam, "%s: invalid decimal number", argv[1], 0);
+	zwarnnam(nam, "%s: invalid decimal number", argv[1]);
 	return 1;
     }
 
diff --git a/Src/Modules/files.c b/Src/Modules/files.c
index 331507c64..079aeac4d 100644
--- a/Src/Modules/files.c
+++ b/Src/Modules/files.c
@@ -78,7 +78,7 @@ bin_mkdir(char *nam, char **args, Options ops, UNUSED(int func))
 
 	mode = zstrtol(str, &ptr, 8);
 	if(!*str || *ptr) {
-	    zwarnnam(nam, "invalid mode `%s'", str, 0);
+	    zwarnnam(nam, "invalid mode `%s'", str);
 	    return 1;
 	}
     }
@@ -214,7 +214,7 @@ bin_ln(char *nam, char **args, Options ops, int func)
 	    goto havedir;
     }
     if(a > args+1) {
-	zwarnnam(nam, "last of many arguments must be a directory", NULL, 0);
+	zwarnnam(nam, "last of many arguments must be a directory");
 	return 1;
     }
     if(!args[1]) {
@@ -266,7 +266,7 @@ domove(char *nam, MoveFunc move, char *p, char *q, int flags)
     if(!lstat(qbuf, &st)) {
 	int doit = flags & MV_FORCE;
 	if(S_ISDIR(st.st_mode)) {
-	    zwarnnam(nam, "%s: cannot overwrite directory", q, 0);
+	    zwarnnam(nam, "%s: cannot overwrite directory", q);
 	    zsfree(pbuf);
 	    return 1;
 	} else if(flags & MV_INTER) {
@@ -469,7 +469,7 @@ recursivecmd_dorec(struct recursivecmd const *reccmd,
     if (restoredir(ds)) {
 	if(!reccmd->opt_noerr)
 	    zwarnnam(reccmd->nam, "failed to return to previous directory: %e",
-		     NULL, errno);
+		     errno);
 	return 2;
     }
     return err | reccmd->dirpost_func(arg, rp, sp, reccmd->magic);
@@ -647,7 +647,7 @@ bin_chown(char *nam, char **args, Options ops, int func)
 	    int err;
 	    chm.uid = getnumeric(p, &err);
 	    if(err) {
-		zwarnnam(nam, "%s: no such user", p, 0);
+		zwarnnam(nam, "%s: no such user", p);
 		free(uspec);
 		return 1;
 	    }
@@ -656,7 +656,7 @@ bin_chown(char *nam, char **args, Options ops, int func)
 	    p = end+1;
 	    if(!*p) {
 		if(!pwd && !(pwd = getpwuid(chm.uid))) {
-		    zwarnnam(nam, "%s: no such user", uspec, 0);
+		    zwarnnam(nam, "%s: no such user", uspec);
 		    free(uspec);
 		    return 1;
 		}
@@ -673,7 +673,7 @@ bin_chown(char *nam, char **args, Options ops, int func)
 		    int err;
 		    chm.gid = getnumeric(p, &err);
 		    if(err) {
-			zwarnnam(nam, "%s: no such group", p, 0);
+			zwarnnam(nam, "%s: no such group", p);
 			free(uspec);
 			return 1;
 		    }
diff --git a/Src/Modules/langinfo.c b/Src/Modules/langinfo.c
index d927358ed..a09c1a0bb 100644
--- a/Src/Modules/langinfo.c
+++ b/Src/Modules/langinfo.c
@@ -460,7 +460,7 @@ getlanginfo(UNUSED(HashTable ht), char *name)
     }
     else
     {
-	/* zwarn("no such lang info: %s", name, 0); */
+	/* zwarn("no such lang info: %s", name); */
 	pm->u.str = dupstring("");
 	pm->node.flags |= PM_UNSET;
     }
diff --git a/Src/Modules/mathfunc.c b/Src/Modules/mathfunc.c
index 7b9b10fab..4d58745e8 100644
--- a/Src/Modules/mathfunc.c
+++ b/Src/Modules/mathfunc.c
@@ -249,7 +249,7 @@ math_func(char *name, int argc, mnumber *argv, int id)
       }
 
       if (rtst) {
-	  zerr("math: argument to %s out of range", name, 0);
+	  zerr("math: argument to %s out of range", name);
 	  return ret;
       }
   }
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 2f9f574e0..c3ec441f8 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -183,7 +183,7 @@ static void
 setpmcommand(Param pm, char *value)
 {
     if (isset(RESTRICTED)) {
-	zwarn("restricted: %s", value, 0);
+	zwarn("restricted: %s", value);
 	zsfree(value);
     } else {
 	Cmdnam cn = zshcalloc(sizeof(*cn));
@@ -322,7 +322,7 @@ setfunction(char *name, char *val, int dis)
     prog = parse_string(val);
 
     if (!prog || prog == &dummy_eprog) {
-	zwarn("invalid function definition", value, 0);
+	zwarn("invalid function definition", value);
 	zsfree(val);
 	return;
     }
@@ -679,11 +679,11 @@ setpmoption(Param pm, char *value)
     int n;
 
     if (!value || (strcmp(value, "on") && strcmp(value, "off")))
-	zwarn("invalid value: %s", value, 0);
+	zwarn("invalid value: %s", value);
     else if (!(n = optlookup(pm->node.nam)))
-	zwarn("no such option: %s", pm->node.nam, 0);
+	zwarn("no such option: %s", pm->node.nam);
     else if (dosetopt(n, (value && strcmp(value, "off")), 0))
-	zwarn("can't change option: %s", pm->node.nam, 0);
+	zwarn("can't change option: %s", pm->node.nam);
     zsfree(value);
 }
 
@@ -694,9 +694,9 @@ unsetpmoption(Param pm, UNUSED(int exp))
     int n;
 
     if (!(n = optlookup(pm->node.nam)))
-	zwarn("no such option: %s", pm->node.nam, 0);
+	zwarn("no such option: %s", pm->node.nam);
     else if (dosetopt(n, 0, 0))
-	zwarn("can't change option: %s", pm->node.nam, 0);
+	zwarn("can't change option: %s", pm->node.nam);
 }
 
 /**/
@@ -721,10 +721,10 @@ setpmoptions(UNUSED(Param pm), HashTable ht)
 
 	    val = getstrvalue(&v);
 	    if (!val || (strcmp(val, "on") && strcmp(val, "off")))
-		zwarn("invalid value: %s", val, 0);
+		zwarn("invalid value: %s", val);
 	    else if (dosetopt(optlookup(hn->nam),
 			      (val && strcmp(val, "off")), 0))
-		zwarn("can't change option: %s", hn->nam, 0);
+		zwarn("can't change option: %s", hn->nam);
 	}
     deleteparamtable(ht);
 }
@@ -1295,7 +1295,7 @@ static void
 setpmnameddir(Param pm, char *value)
 {
     if (!value)
-	zwarn("invalid value: ''", NULL, 0);
+	zwarn("invalid value: ''");
     else {
 	Nameddir nd = (Nameddir) zshcalloc(sizeof(*nd));
 
@@ -1344,7 +1344,7 @@ setpmnameddirs(UNUSED(Param pm), HashTable ht)
 	    v.pm = (Param) hn;
 
 	    if (!(val = getstrvalue(&v)))
-		zwarn("invalid value: ''", NULL, 0);
+		zwarn("invalid value: ''");
 	    else {
 		Nameddir nd = (Nameddir) zshcalloc(sizeof(*nd));
 
diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c
index 2336b27d7..3ed536671 100644
--- a/Src/Modules/pcre.c
+++ b/Src/Modules/pcre.c
@@ -58,7 +58,7 @@ bin_pcre_compile(char *nam, char **args, Options ops, UNUSED(int func))
     
     if (pcre_pattern == NULL)
     {
-	zwarnnam(nam, "error in regex: %s", pcre_error, 0);
+	zwarnnam(nam, "error in regex: %s", pcre_error);
 	return 1;
     }
     
@@ -76,15 +76,14 @@ bin_pcre_study(char *nam, UNUSED(char **args), UNUSED(Options ops), UNUSED(int f
 
     if (pcre_pattern == NULL)
     {
-	zwarnnam(nam, "no pattern has been compiled for study",
-		 NULL, 0);
+	zwarnnam(nam, "no pattern has been compiled for study");
 	return 1;
     }
     
     pcre_hints = pcre_study(pcre_pattern, 0, &pcre_error);
     if (pcre_error != NULL)
     {
-	zwarnnam(nam, "error while studying regex: %s", pcre_error, 0);
+	zwarnnam(nam, "error while studying regex: %s", pcre_error);
 	return 1;
     }
     
@@ -129,14 +128,14 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func))
     if(OPT_ISSET(ops,'a')) {
 	receptacle = *args++;
 	if(!*args) {
-	    zwarnnam(nam, "not enough arguments", NULL, 0);
+	    zwarnnam(nam, "not enough arguments");
 	    return 1;
 	}
     }
     
     if ((ret = pcre_fullinfo(pcre_pattern, pcre_hints, PCRE_INFO_CAPTURECOUNT, &capcount)))
     {
-	zwarnnam(nam, "error %d in fullinfo", NULL, ret);
+	zwarnnam(nam, "error %d in fullinfo", ret);
 	return 1;
     }
     
@@ -152,7 +151,7 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func))
 	return 0;
     }
     else {
-	zwarnnam(nam, "error in pcre_exec", NULL, 0);
+	zwarnnam(nam, "error in pcre_exec");
 	return 1;
     }
     
diff --git a/Src/Modules/socket.c b/Src/Modules/socket.c
index 2f95a84d5..7ca56b4e7 100644
--- a/Src/Modules/socket.c
+++ b/Src/Modules/socket.c
@@ -75,12 +75,12 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
 	targetfd = atoi(OPT_ARG(ops,'d'));
 	if (!targetfd) {
 	    zwarnnam(nam, "%s is an invalid argument to -d",
-		     OPT_ARG(ops, 'd'), 0);
+		     OPT_ARG(ops, 'd'));
 	    return 1;
 	}
 	if (targetfd <= max_zsh_fd && fdtable[targetfd] != FDT_UNUSED) {
 	    zwarnnam(nam, "file descriptor %d is in use by the shell",
-		     NULL, targetfd);
+		     targetfd);
 	    return 1;
 	}
     }
@@ -89,7 +89,7 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
 	char *localfn;
 
 	if (!args[0]) {
-	    zwarnnam(nam, "-l requires an argument", NULL, 0);
+	    zwarnnam(nam, "-l requires an argument");
 	    return 1;
 	}
 
@@ -98,7 +98,7 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
 	sfd = socket(PF_UNIX, SOCK_STREAM, 0);
 
 	if (sfd == -1) {
-	    zwarnnam(nam, "socket error: %e ", NULL, errno);
+	    zwarnnam(nam, "socket error: %e ", errno);
 	    return 1;
 	}
 
@@ -114,7 +114,7 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
 
 	if (listen(sfd, 1))
 	{
-	    zwarnnam(nam, "could not listen on socket: %e", NULL, errno);
+	    zwarnnam(nam, "could not listen on socket: %e", errno);
 	    close(sfd);
 	    return 1;
 	}
@@ -141,14 +141,14 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
 	int lfd, rfd;
 
 	if (!args[0]) {
-	    zwarnnam(nam, "-a requires an argument", NULL, 0);
+	    zwarnnam(nam, "-a requires an argument");
 	    return 1;
 	}
 
 	lfd = atoi(args[0]);
 
 	if (!lfd) {
-	    zwarnnam(nam, "invalid numerical argument", NULL, 0);
+	    zwarnnam(nam, "invalid numerical argument");
 	    return 1;
 	}
 
@@ -163,7 +163,7 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
 	    if ((ret = poll(&pfd, 1, 0)) == 0) return 1;
 	    else if (ret == -1)
 	    {
-		zwarnnam(nam, "poll error: %e", NULL, errno);
+		zwarnnam(nam, "poll error: %e", errno);
 		return 1;
 	    }
 # else
@@ -179,14 +179,14 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
 	    if ((ret = select(lfd+1, &rfds, NULL, NULL, &tv))) return 1;
 	    else if (ret == -1)
 	    {
-		zwarnnam(nam, "select error: %e", NULL, errno);
+		zwarnnam(nam, "select error: %e", errno);
 		return 1;
 	    }
 	    
 # endif
 	    
 #else
-	    zwarnnam(nam, "not currently supported", NULL, 0);
+	    zwarnnam(nam, "not currently supported");
 	    return 1;
 #endif
 	}
@@ -194,7 +194,7 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
 	len = sizeof(soun);
 	if ((rfd = accept(lfd, (struct sockaddr *)&soun, &len)) == -1)
 	{
-	    zwarnnam(nam, "could not accept connection: %e", NULL, errno);
+	    zwarnnam(nam, "could not accept connection: %e", errno);
 	    return 1;
 	}
 
@@ -214,14 +214,14 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
     else
     {
 	if (!args[0]) {
-	    zwarnnam(nam, "zsocket requires an argument", NULL, 0);
+	    zwarnnam(nam, "zsocket requires an argument");
 	    return 1;
 	}
 
 	sfd = socket(PF_UNIX, SOCK_STREAM, 0);
 
 	if (sfd == -1) {
-	    zwarnnam(nam, "socket creation failed: %e", NULL, errno);
+	    zwarnnam(nam, "socket creation failed: %e", errno);
 	    return 1;
 	}
 
@@ -229,7 +229,7 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
 	strncpy(soun.sun_path, args[0], UNIX_PATH_MAX);
 	
 	if ((err = connect(sfd, (struct sockaddr *)&soun, sizeof(struct sockaddr_un)))) {
-	    zwarnnam(nam, "connection failed: %e", NULL, errno);
+	    zwarnnam(nam, "connection failed: %e", errno);
 	    close(sfd);
 	    return 1;
 	}
diff --git a/Src/Modules/stat.c b/Src/Modules/stat.c
index 20a09e671..3ffaf9d4d 100644
--- a/Src/Modules/stat.c
+++ b/Src/Modules/stat.c
@@ -380,10 +380,10 @@ bin_stat(char *name, char **args, Options ops, UNUSED(int func))
 		    iwhich = aptr - statelts;
 		}
 	    if (found > 1) {
-		zwarnnam(name, "%s: ambiguous stat element", arg, 0);
+		zwarnnam(name, "%s: ambiguous stat element", arg);
 		return 1;
 	    } else if (found == 0) {
-		zwarnnam(name, "%s: no such stat element", arg, 0);
+		zwarnnam(name, "%s: no such stat element", arg);
 		return 1;
 	    }
 	    /* if name of link requested, turn on lstat */
@@ -398,8 +398,7 @@ bin_stat(char *name, char **args, Options ops, UNUSED(int func))
 		    if (arg[1]) {
 			arrnam = arg+1;
 		    } else if (!(arrnam = *++args)) {
-			zwarnnam(name, "missing parameter name",
-				NULL, 0);
+			zwarnnam(name, "missing parameter name");
 			return 1;
 		    }
 		    flags |= STF_ARRAY;
@@ -408,8 +407,7 @@ bin_stat(char *name, char **args, Options ops, UNUSED(int func))
 		    if (arg[1]) {
 			hashnam = arg+1;
 		    } else if (!(hashnam = *++args)) {
-			zwarnnam(name, "missing parameter name",
-				NULL, 0);
+			zwarnnam(name, "missing parameter name");
 			return 1;
 		    }
 		    flags |= STF_HASH;
@@ -420,12 +418,12 @@ bin_stat(char *name, char **args, Options ops, UNUSED(int func))
 		    if (arg[1]) {
 			sfd = arg+1;
 		    } else if (!(sfd = *++args)) {
-			zwarnnam(name, "missing file descriptor", NULL, 0);
+			zwarnnam(name, "missing file descriptor");
 			return 1;
 		    }
 		    fd = zstrtol(sfd, &sfd, 10);
 		    if (*sfd) {
-			zwarnnam(name, "bad file descriptor", NULL, 0);
+			zwarnnam(name, "bad file descriptor");
 			return 1;
 		    }
 		    break;
@@ -433,14 +431,14 @@ bin_stat(char *name, char **args, Options ops, UNUSED(int func))
 		    if (arg[1]) {
 			timefmt = arg+1;
 		    } else if (!(timefmt = *++args)) {
-			zwarnnam(name, "missing time format", NULL, 0);
+			zwarnnam(name, "missing time format");
 			return 1;
 		    }
 		    /* force string format in order to use time format */
 		    ops->ind['s'] = 1;
 		    break;
 		} else {
-		    zwarnnam(name, "bad option: -%c", NULL, *arg);
+		    zwarnnam(name, "bad option: -%c", *arg);
 		    return 1;
 		}
 	    }
@@ -449,7 +447,7 @@ bin_stat(char *name, char **args, Options ops, UNUSED(int func))
 
     if ((flags & STF_ARRAY) && (flags & STF_HASH)) {
     	/* We don't implement setting multiple variables at once */
-	zwarnnam(name, "both array and hash requested", NULL, 0);
+	zwarnnam(name, "both array and hash requested");
 	return 1;
 	/* Alternate method would be to make -H blank arrnam etc etc *
 	 * and so get 'silent loss' of earlier choice, which would   *
@@ -481,10 +479,10 @@ bin_stat(char *name, char **args, Options ops, UNUSED(int func))
     }
 
     if (!*args && !OPT_ISSET(ops,'f')) {
-	zwarnnam(name, "no files given", NULL, 0);
+	zwarnnam(name, "no files given");
 	return 1;
     } else if (*args && OPT_ISSET(ops,'f')) {
-	zwarnnam(name, "no files allowed with -f", NULL, 0);
+	zwarnnam(name, "no files allowed with -f");
 	return 1;
     }
 
@@ -524,7 +522,7 @@ bin_stat(char *name, char **args, Options ops, UNUSED(int func))
 
     if (hashnam) {
     	if (nargs > 1) {
-	    zwarnnam(name, "only one file allowed with -H", NULL, 0);
+	    zwarnnam(name, "only one file allowed with -H");
 	    return 1;
 	}
 	arrsize = (flags & STF_PICK) ? 1 : ST_COUNT;
diff --git a/Src/Modules/system.c b/Src/Modules/system.c
index 7b1c08a95..dfdf094b9 100644
--- a/Src/Modules/system.c
+++ b/Src/Modules/system.c
@@ -48,7 +48,7 @@ getposint(char *instr, char *nam)
 
     ret = (int)zstrtol(instr, &eptr, 10);
     if (*eptr || ret < 0) {
-	zwarnnam(nam, "integer expected: %s", instr, 0);
+	zwarnnam(nam, "integer expected: %s", instr);
 	return -1;
     }
 
@@ -83,7 +83,7 @@ bin_sysread(char *nam, char **args, Options ops, UNUSED(int func))
     /* -o: output file descriptor, else store in REPLY */
     if (OPT_ISSET(ops, 'o')) {
 	if (*args) {
-	    zwarnnam(nam, "no argument allowed with -o", NULL, 0);
+	    zwarnnam(nam, "no argument allowed with -o");
 	    return 1;
 	}
 	outfd = getposint(OPT_ARG(ops, 'o'), nam);
@@ -102,7 +102,7 @@ bin_sysread(char *nam, char **args, Options ops, UNUSED(int func))
     if (OPT_ISSET(ops, 'c')) {
 	countvar = OPT_ARG(ops, 'c');
 	if (!isident(countvar)) {
-	    zwarnnam(nam, "not an identifier: %s", countvar, 0);
+	    zwarnnam(nam, "not an identifier: %s", countvar);
 	    return 1;
 	}
     }
@@ -116,7 +116,7 @@ bin_sysread(char *nam, char **args, Options ops, UNUSED(int func))
 	 */
 	outvar = *args;
 	if (!isident(outvar)) {
-	    zwarnnam(nam, "not an identifier: %s", outvar, 0);
+	    zwarnnam(nam, "not an identifier: %s", outvar);
 	    return 1;
 	}
     }
@@ -252,7 +252,7 @@ bin_syswrite(char *nam, char **args, Options ops, UNUSED(int func))
     if (OPT_ISSET(ops, 'c')) {
 	countvar = OPT_ARG(ops, 'c');
 	if (!isident(countvar)) {
-	    zwarnnam(nam, "not an identifier: %s", countvar, 0);
+	    zwarnnam(nam, "not an identifier: %s", countvar);
 	    return 1;
 	}
     }
@@ -299,7 +299,7 @@ bin_syserror(char *nam, char **args, Options ops, UNUSED(int func))
     if (OPT_ISSET(ops, 'e')) {
 	errvar = OPT_ARG(ops, 'e');
 	if (!isident(errvar)) {
-	    zwarnnam(nam, "not an identifier: %s", errvar, 0);
+	    zwarnnam(nam, "not an identifier: %s", errvar);
 	    return 1;
 	}
     }
diff --git a/Src/Modules/tcp.c b/Src/Modules/tcp.c
index 2120ba833..232cc31bc 100644
--- a/Src/Modules/tcp.c
+++ b/Src/Modules/tcp.c
@@ -300,7 +300,7 @@ tcp_close(Tcp_session sess)
 	{
 	    err = close(sess->fd);
 	    if (err)
-		zwarn("connection close failed: %e", NULL, errno);
+		zwarn("connection close failed: %e", errno);
 	}
 	zts_delete(sess);
 	return 0;
@@ -358,8 +358,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
     if (OPT_ISSET(ops,'d')) {
 	targetfd = atoi(OPT_ARG(ops,'d'));
 	if (!targetfd) {
-	    zwarnnam(nam, "%s is an invalid argument to -d",
-		     OPT_ARG(ops,'d'), 0);
+	    zwarnnam(nam, "%s is an invalid argument to -d", OPT_ARG(ops,'d'));
 	    return 1;
 	}
     }
@@ -373,7 +372,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	    targetfd = atoi(args[0]);
 	    sess = zts_byfd(targetfd);
 	    if(!targetfd) {
-		zwarnnam(nam, "%s is an invalid argument to -c", args[0], 0);
+		zwarnnam(nam, "%s is an invalid argument to -c", args[0]);
 		return 1;
 	    }
 
@@ -381,7 +380,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	    {
 		if ((sess->flags & ZTCP_ZFTP) && !force)
 		{
-		    zwarnnam(nam, "use -f to force closure of a zftp control connection", NULL, 0);
+		    zwarnnam(nam, "use -f to force closure of a zftp control connection");
 		    return 1;
 		}
 		tcp_close(sess);
@@ -389,7 +388,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	    }
 	    else
 	    {
-		zwarnnam(nam, "fd %s not found in tcp table", args[0], 0);
+		zwarnnam(nam, "fd %s not found in tcp table", args[0]);
 		return 1;
 	    }
 	}
@@ -398,7 +397,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	int lport = 0;
 
 	if (!args[0]) {
-	    zwarnnam(nam, "-l requires an argument", NULL, 0);
+	    zwarnnam(nam, "-l requires an argument");
 	    return 1;
 	}
 
@@ -407,13 +406,13 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	    lport = srv->s_port;
 	else
 	    lport = htons(atoi(args[0]));
-	if (!lport) { zwarnnam(nam, "bad service name or port number", NULL, 0);
+	if (!lport) { zwarnnam(nam, "bad service name or port number");
 	return 1;
 	}
 	sess = tcp_socket(PF_INET, SOCK_STREAM, 0, ZTCP_LISTEN);
 
 	if (!sess) {
-	    zwarnnam(nam, "unable to allocate a TCP session slot", NULL, 0);
+	    zwarnnam(nam, "unable to allocate a TCP session slot");
 	    return 1;
 	}
 #ifdef SO_OOBINLINE
@@ -422,7 +421,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 #endif
 	if (!zsh_inet_aton("0.0.0.0", &(sess->sock.in.sin_addr)))
 	{
-	    zwarnnam(nam, "bad address: %s", "0.0.0.0", 0);
+	    zwarnnam(nam, "bad address: %s", "0.0.0.0");
 	    return 1;
 	}
 
@@ -441,7 +440,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 
 	if (listen(sess->fd, 1))
 	{
-	    zwarnnam(nam, "could not listen on socket: %e", NULL, errno);
+	    zwarnnam(nam, "could not listen on socket: %e", errno);
 	    tcp_close(sess);
 	    return 1;
 	}
@@ -468,26 +467,26 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	int lfd, rfd;
 
 	if (!args[0]) {
-	    zwarnnam(nam, "-a requires an argument", NULL, 0);
+	    zwarnnam(nam, "-a requires an argument");
 	    return 1;
 	}
 
 	lfd = atoi(args[0]);
 
 	if (!lfd) {
-	    zwarnnam(nam, "invalid numerical argument", NULL, 0);
+	    zwarnnam(nam, "invalid numerical argument");
 	    return 1;
 	}
 
 	sess = zts_byfd(lfd);
 	if (!sess) {
-	    zwarnnam(nam, "fd %s is not registered as a tcp connection", args[0], 0);
+	    zwarnnam(nam, "fd %s is not registered as a tcp connection", args[0]);
 	    return 1;
 	}
 
 	if (!(sess->flags & ZTCP_LISTEN))
 	{
-	    zwarnnam(nam, "tcp connection not a listener", NULL, 0);
+	    zwarnnam(nam, "tcp connection not a listener");
 	    return 1;
 	}
 
@@ -502,7 +501,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	    if ((ret = poll(&pfd, 1, 0)) == 0) return 1;
 	    else if (ret == -1)
 	    {
-		zwarnnam(nam, "poll error: %e", NULL, errno);
+		zwarnnam(nam, "poll error: %e", errno);
 		return 1;
 	    }
 # else
@@ -518,14 +517,14 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	    if ((ret = select(lfd+1, &rfds, NULL, NULL, &tv))) return 1;
 	    else if (ret == -1)
 	    {
-		zwarnnam(nam, "select error: %e", NULL, errno);
+		zwarnnam(nam, "select error: %e", errno);
 		return 1;
 	    }
 	    
 # endif
 	    
 #else
-	    zwarnnam(nam, "not currently supported", NULL, 0);
+	    zwarnnam(nam, "not currently supported");
 	    return 1;
 #endif
 	}
@@ -534,7 +533,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	len = sizeof(sess->peer.in);
 	if ((rfd = accept(lfd, (struct sockaddr *)&sess->peer.in, &len)) == -1)
 	{
-	    zwarnnam(nam, "could not accept connection: %e", NULL, errno);
+	    zwarnnam(nam, "could not accept connection: %e", errno);
 	    tcp_close(sess);
 	    return 1;
 	}
@@ -615,14 +614,14 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	
 	zthost = zsh_getipnodebyname(desthost, AF_INET, 0, &herrno);
 	if (!zthost || errflag) {
-	    zwarnnam(nam, "host resolution failure: %s", desthost, 0);
+	    zwarnnam(nam, "host resolution failure: %s", desthost);
 	    return 1;
 	}
 	
 	sess = tcp_socket(PF_INET, SOCK_STREAM, 0, 0);
 
 	if (!sess) {
-	    zwarnnam(nam, "unable to allocate a TCP session slot", NULL, 0);
+	    zwarnnam(nam, "unable to allocate a TCP session slot");
 	    return 1;
 	}
 
@@ -632,7 +631,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 #endif
 
 	if (sess->fd < 0) {
-	    zwarnnam(nam, "socket creation failed: %e", NULL, errno);
+	    zwarnnam(nam, "socket creation failed: %e", errno);
 	    zsfree(desthost);
 	    zts_delete(sess);
 	    return 1;
@@ -640,14 +639,14 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	
 	for (addrp = zthost->h_addr_list; err && *addrp; addrp++) {
 	    if (zthost->h_length != 4)
-		zwarnnam(nam, "address length mismatch", NULL, 0);
+		zwarnnam(nam, "address length mismatch");
 	    do {
 		err = tcp_connect(sess, *addrp, zthost, destport);
 	    } while (err && errno == EINTR && !errflag);
 	}
 	
 	if (err) {
-	    zwarnnam(nam, "connection failed: %e", NULL, errno);
+	    zwarnnam(nam, "connection failed: %e", errno);
 	    tcp_close(sess);
 	    zsfree(desthost);
 	    return 1;
diff --git a/Src/Modules/termcap.c b/Src/Modules/termcap.c
index 9e7ee57ae..e29b2bf74 100644
--- a/Src/Modules/termcap.c
+++ b/Src/Modules/termcap.c
@@ -134,7 +134,7 @@ bin_echotc(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
     t = tgetstr(s, &u);
     if (t == (char *)-1 || !t || !*t) {
 	/* capability doesn't exist, or (if boolean) is off */
-	zwarnnam(name, "no such capability: %s", s, 0);
+	zwarnnam(name, "no such capability: %s", s);
 	return 1;
     }
     /* count the number of arguments required */
@@ -147,7 +147,7 @@ bin_echotc(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
     /* check that the number of arguments provided is correct */
     if (arrlen(argv) != argct) {
 	zwarnnam(name, (arrlen(argv) < argct) ? "not enough arguments" :
-		 "too many arguments", NULL, 0);
+		 "too many arguments");
 	return 1;
     }
     /* output string, through the proper termcap functions */
@@ -263,7 +263,7 @@ gettermcap(UNUSED(HashTable ht), char *name)
 	pm->u.str = dupstring(tcstr);
 	pm->node.flags |= PM_SCALAR;
     } else {
-	/* zwarn("no such capability: %s", name, 0); */
+	/* zwarn("no such capability: %s", name); */
 	pm->u.str = dupstring("");
 	pm->node.flags |= PM_UNSET;
     }
diff --git a/Src/Modules/terminfo.c b/Src/Modules/terminfo.c
index 4c8dce3ce..b4a1c599b 100644
--- a/Src/Modules/terminfo.c
+++ b/Src/Modules/terminfo.c
@@ -95,12 +95,12 @@ bin_echoti(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
     t = (char *)tigetstr(s);
     if (!t || t == (char *)-1 || !*t) {
 	/* capability doesn't exist, or (if boolean) is off */
-	zwarnnam(name, "no such terminfo capability: %s", s, 0);
+	zwarnnam(name, "no such terminfo capability: %s", s);
 	return 1;
     }
     /* check that the number of arguments provided is not too high */
     if (arrlen(argv) > 9) {
-        zwarnnam(name, "too many arguments", NULL, 0);
+        zwarnnam(name, "too many arguments");
         return 1;
     }
 
@@ -216,7 +216,7 @@ getterminfo(UNUSED(HashTable ht), char *name)
 	pm->node.flags |= PM_SCALAR;
 	pm->gsu.s = &nullsetscalar_gsu;
     } else {
-	/* zwarn("no such capability: %s", name, 0); */
+	/* zwarn("no such capability: %s", name); */
 	pm->u.str = dupstring("");
 	pm->node.flags |= PM_UNSET;
 	pm->gsu.s = &nullsetscalar_gsu;
diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c
index 45e04d4f8..c150f8b62 100644
--- a/Src/Modules/zftp.c
+++ b/Src/Modules/zftp.c
@@ -582,7 +582,7 @@ zfgetline(char *ln, int lnsize, int tmout)
 
     if (setjmp(zfalrmbuf)) {
 	alarm(0);
-	zwarnnam("zftp", "timeout getting response", NULL, 0);
+	zwarnnam("zftp", "timeout getting response");
 	return 6;
     }
     zfalarm(tmout);
@@ -792,7 +792,7 @@ zfgetmsg(void)
 	zcfinish = 2;		/* don't need to tell server */
 	zfclose(0);
 	/* unexpected, so tell user */
-	zwarnnam("zftp", "remote server has closed connection", NULL, 0);
+	zwarnnam("zftp", "remote server has closed connection");
 	return 6;
     }
     if (lastcode == 530) {
@@ -805,7 +805,7 @@ zfgetmsg(void)
      * It means we just hang around waiting for another reply.
      */
     if (lastcode == 120) {
-	zwarnnam("zftp", "delay expected, waiting: %s", lastmsg, 0);
+	zwarnnam("zftp", "delay expected, waiting: %s", lastmsg);
 	return zfgetmsg();
     }
 
@@ -836,7 +836,7 @@ zfsendcmd(char *cmd)
     tmout = getiparam("ZFTP_TMOUT");
     if (setjmp(zfalrmbuf)) {
 	alarm(0);
-	zwarnnam("zftp", "timeout sending message", NULL, 0);
+	zwarnnam("zftp", "timeout sending message");
 	return 6;
     }
     zfalarm(tmout);
@@ -844,8 +844,7 @@ zfsendcmd(char *cmd)
     alarm(0);
 
     if (ret <= 0) {
-	zwarnnam("zftp send", "failure sending control message: %e",
-		 NULL, errno);
+	zwarnnam("zftp send", "failure sending control message: %e", errno);
 	return 6;
     }
 
@@ -860,12 +859,12 @@ static int
 zfopendata(char *name, union tcp_sockaddr *zdsockp, int *is_passivep)
 {
     if (!(zfprefs & (ZFPF_SNDP|ZFPF_PASV))) {
-	zwarnnam(name, "Must set preference S or P to transfer data", NULL, 0);
+	zwarnnam(name, "Must set preference S or P to transfer data");
 	return 1;
     }
     zfsess->dfd = socket(zfsess->control->peer.a.sa_family, SOCK_STREAM, 0);
     if (zfsess->dfd < 0) {
-	zwarnnam(name, "can't get data socket: %e", NULL, errno);
+	zwarnnam(name, "can't get data socket: %e", errno);
 	return 1;
     }
 
@@ -900,7 +899,7 @@ zfopendata(char *name, union tcp_sockaddr *zdsockp, int *is_passivep)
 	    ptr = strchr(lastmsg, '(');
 	    if(!ptr) {
 	    bad_epsv:
-		zwarnnam(name, "bad response to EPSV: %s", lastmsg, 0);
+		zwarnnam(name, "bad response to EPSV: %s", lastmsg);
 		zfclosedata();
 		return 1;
 	    }
@@ -940,7 +939,7 @@ zfopendata(char *name, union tcp_sockaddr *zdsockp, int *is_passivep)
 		    break;
 	    if (sscanf(ptr, "%d,%d,%d,%d,%d,%d",
 		       nums, nums+1, nums+2, nums+3, nums+4, nums+5) != 6) {
-		zwarnnam(name, "bad response to PASV: %s", lastmsg, 0);
+		zwarnnam(name, "bad response to PASV: %s", lastmsg);
 		zfclosedata();
 		return 1;
 	    }
@@ -960,7 +959,7 @@ zfopendata(char *name, union tcp_sockaddr *zdsockp, int *is_passivep)
 	} while (err && errno == EINTR && !errflag);
 
 	if (err) {
-	    zwarnnam(name, "connect failed: %e", NULL, errno);
+	    zwarnnam(name, "connect failed: %e", errno);
 	    zfclosedata();
 	    return 1;
 	}
@@ -976,7 +975,7 @@ zfopendata(char *name, union tcp_sockaddr *zdsockp, int *is_passivep)
 	int ret;
 
 	if (!(zfprefs & ZFPF_SNDP)) {
-	    zwarnnam(name, "only sendport mode available for data", NULL, 0);
+	    zwarnnam(name, "only sendport mode available for data");
 	    return 1;
 	}
 
@@ -1027,7 +1026,7 @@ zfopendata(char *name, union tcp_sockaddr *zdsockp, int *is_passivep)
 		    addr[0],addr[1],addr[2],addr[3],port[0],port[1]);
 	}
 	if (zfsendcmd(portcmd) >= 5) {
-	    zwarnnam(name, "port command failed", NULL, 0);
+	    zwarnnam(name, "port command failed");
 	    zfclosedata();
 	    return 1;
 	}
@@ -1129,7 +1128,7 @@ zfgetdata(char *name, char *rest, char *cmd, int getsize)
 	newfd = zfmovefd(accept(zfsess->dfd, (struct sockaddr *)&zdsock, 
 				&len));
 	if (newfd < 0)
-	    zwarnnam(name, "unable to accept data: %e", NULL, errno);
+	    zwarnnam(name, "unable to accept data: %e", errno);
 	zfclosedata();
 	if (newfd < 0)
 	    return 1;
@@ -1320,7 +1319,7 @@ zfread(int fd, char *bf, off_t sz, int tmout)
 
     if (setjmp(zfalrmbuf)) {
 	alarm(0);
-	zwarnnam("zftp", "timeout on network read", NULL, 0);
+	zwarnnam("zftp", "timeout on network read");
 	return -1;
     }
     zfalarm(tmout);
@@ -1345,7 +1344,7 @@ zfwrite(int fd, char *bf, off_t sz, int tmout)
 
     if (setjmp(zfalrmbuf)) {
 	alarm(0);
-	zwarnnam("zftp", "timeout on network write", NULL, 0);
+	zwarnnam("zftp", "timeout on network write");
 	return -1;
     }
     zfalarm(tmout);
@@ -1375,7 +1374,7 @@ zfread_block(int fd, char *bf, off_t sz, int tmout)
 	    n = zfread(fd, (char *)&hdr, sizeof(hdr), tmout);
 	} while (n < 0 && errno == EINTR);
 	if (n != 3 && !zfdrrrring) {
-	    zwarnnam("zftp", "failure reading FTP block header", NULL, 0);
+	    zwarnnam("zftp", "failure reading FTP block header");
 	    return n;
 	}
 	/* size is stored in network byte order */
@@ -1386,7 +1385,7 @@ zfread_block(int fd, char *bf, off_t sz, int tmout)
 	    /*
 	     * See comments in file headers
 	     */
-	    zwarnnam("zftp", "block too large to handle", NULL, 0);
+	    zwarnnam("zftp", "block too large to handle");
 	    errno = EIO;
 	    return -1;
 	}
@@ -1403,7 +1402,7 @@ zfread_block(int fd, char *bf, off_t sz, int tmout)
 		break;
 	}
 	if (cnt) {
-	    zwarnnam("zftp", "short data block", NULL, 0);
+	    zwarnnam("zftp", "short data block");
 	    errno = EIO;
 	    return -1;
 	}
@@ -1429,7 +1428,7 @@ zfwrite_block(int fd, char *bf, off_t sz, int tmout)
 	n = zfwrite(fd, (char *)&hdr, sizeof(hdr), tmout);
     } while (n < 0 && errno == EINTR);
     if (n != 3 && !zfdrrrring) {
-	zwarnnam("zftp", "failure writing FTP block header", NULL, 0);
+	zwarnnam("zftp", "failure writing FTP block header");
 	return n;
     }
     bfptr = bf;
@@ -1586,7 +1585,7 @@ zfsenddata(char *name, int recv, int progress, off_t startat)
 			if (!zfdrrrring &&
 			    (!interact || (!errflag && errno != EPIPE))) {
 			    ret = recv ? 2 : 1;
-			    zwarnnam(name, "write failed: %e", NULL, errno);
+			    zwarnnam(name, "write failed: %e", errno);
 			} else
 			    ret = recv ? 3 : 1;
 			break;
@@ -1601,7 +1600,7 @@ zfsenddata(char *name, int recv, int progress, off_t startat)
 		if (!zfdrrrring &&
 		    (!interact || (!errflag && errno != EPIPE))) {
 		    ret = recv ? 1 : 2;
-		    zwarnnam(name, "read failed: %e", NULL, errno);
+		    zwarnnam(name, "read failed: %e", errno);
 		} else
 		    ret = recv ? 1 : 3;
 		break;
@@ -1649,7 +1648,7 @@ zfsenddata(char *name, int recv, int progress, off_t startat)
 	unsigned char msg[4] = { IAC, IP, IAC, SYNCH };
 
 	if (ret == 2)
-	    zwarnnam(name, "aborting data transfer...", NULL, 0);
+	    zwarnnam(name, "aborting data transfer...");
 
 	holdintr();
 
@@ -1709,7 +1708,7 @@ zftp_open(char *name, char **args, int flags)
 	if (zfsess->userparams)
 	    args = zfsess->userparams;
 	else {
-	    zwarnnam(name, "no host specified", NULL, 0);
+	    zwarnnam(name, "no host specified");
 	    return 1;
 	}
     }
@@ -1731,7 +1730,7 @@ zftp_open(char *name, char **args, int flags)
 	hostnam++;
 	hostsuffix = strchr(hostnam, ']');
 	if (!hostsuffix || (hostsuffix[1] && hostsuffix[1] != ':')) {
-	    zwarnnam(name, "Invalid host format: %s", hostnam, 0);
+	    zwarnnam(name, "Invalid host format: %s", hostnam);
 	    return 1;
 	}
 	*hostsuffix++ = '\0';
@@ -1761,8 +1760,7 @@ zftp_open(char *name, char **args, int flags)
     /* this is going to give 0.  why bother? */
     zprotop = getprotobyname("tcp");
     if (!zprotop) {
-	zwarnnam(name, "Can't find protocol TCP (is your network functional)?",
-		 NULL, 0);
+	zwarnnam(name, "Can't find protocol TCP (is your network functional)?");
 	return 1;
     }
     if (port < 0)
@@ -1771,7 +1769,7 @@ zftp_open(char *name, char **args, int flags)
 	zservp = getservbyport(port, "tcp");
 
     if (!zprotop || !zservp) {
-	zwarnnam(name, "Can't find port for service `%s'", portnam, 0);
+	zwarnnam(name, "Can't find port for service `%s'", portnam);
 	return 1;
     }
 
@@ -1788,9 +1786,9 @@ zftp_open(char *name, char **args, int flags)
 	alarm(0);
 	queue_signals();
 	if ((hname = getsparam("ZFTP_HOST")) && *hname) 
-	    zwarnnam(name, "timeout connecting to %s", hname, 0);
+	    zwarnnam(name, "timeout connecting to %s", hname);
 	else
-	    zwarnnam(name, "timeout on host name lookup", NULL, 0);
+	    zwarnnam(name, "timeout on host name lookup");
 	unqueue_signals();
 	zfclose(0);
 	return 1;
@@ -1818,7 +1816,7 @@ zftp_open(char *name, char **args, int flags)
 	     * on the other hand, herror() is obsolete
 	     */
 	    FAILED();
-	    zwarnnam(name, "host not found: %s", hostnam, 0);
+	    zwarnnam(name, "host not found: %s", hostnam);
 	    alarm(0);
 	    return 1;
 	}
@@ -1851,7 +1849,7 @@ zftp_open(char *name, char **args, int flags)
 	    zfunsetparam("ZFTP_HOST");
 	    zfunsetparam("ZFTP_PORT");
 	    FAILED();
-	    zwarnnam(name, "socket failed: %e", NULL, errno);
+	    zwarnnam(name, "socket failed: %e", errno);
 	    alarm(0);
 	    return 1;
 	}
@@ -1868,7 +1866,7 @@ zftp_open(char *name, char **args, int flags)
 	/* try all possible IP's */
 	for (addrp = zhostp->h_addr_list; err && *addrp; addrp++) {
 	    if(hlen != zhostp->h_length)
-		zwarnnam(name, "address length mismatch", NULL, 0);
+		zwarnnam(name, "address length mismatch");
 	    do {
 		err = tcp_connect(zfsess->control, *addrp, zhostp, zservp->s_port);
 	    } while (err && errno == EINTR && !errflag);
@@ -1879,7 +1877,7 @@ zftp_open(char *name, char **args, int flags)
 	    freehostent(zhostp);
 	    zfclose(0);
 	    FAILED();
-	    zwarnnam(name, "connect failed: %e", NULL, errno);
+	    zwarnnam(name, "connect failed: %e", errno);
 	    alarm(0);
 	    return 1;
 	}
@@ -1914,7 +1912,7 @@ zftp_open(char *name, char **args, int flags)
 
     len = sizeof(zfsess->control->sock);
     if (getsockname(zfsess->control->fd, (struct sockaddr *)&zfsess->control->sock, &len) < 0) {
-	zwarnnam(name, "getsockname failed: %e", NULL, errno);
+	zwarnnam(name, "getsockname failed: %e", errno);
 	zfclose(0);
 	return 1;
     }
@@ -1941,7 +1939,7 @@ zftp_open(char *name, char **args, int flags)
     zfsess->cin = fdopen(zfsess->control->fd, "r");
 
     if (!zfsess->cin) {
-	zwarnnam(name, "file handling error", NULL, 0);
+	zwarnnam(name, "file handling error");
 	zfclose(0);
 	return 1;
     }
@@ -2190,7 +2188,7 @@ zftp_login(char *name, char **args, UNUSED(int flags))
     if (!zfsess->control)
 	return 1;
     if (stopit == 2 || (lastcode != 230 && lastcode != 202)) {
-	zwarnnam(name, "login failed", NULL, 0);
+	zwarnnam(name, "login failed");
 	return 1;
     }
 
@@ -2198,7 +2196,7 @@ zftp_login(char *name, char **args, UNUSED(int flags))
 	int cnt;
 	for (cnt = 0; *args; args++)
 	    cnt++;
-	zwarnnam(name, "warning: %d comand arguments not used\n", NULL, cnt);
+	zwarnnam(name, "warning: %d comand arguments not used\n", cnt);
     }
     zfstatusp[zfsessno] |= ZFST_LOGI;
     zfsetparam("ZFTP_USER", ztrdup(user), ZFPM_READONLY);
@@ -2299,7 +2297,7 @@ zftp_test(UNUSED(char *name), UNUSED(char **args), UNUSED(int flags))
     /* if we have no zfsess->control, then we've just been dumped out. */
     return zfsess->control ? 0 : 2;
 #else
-    zfwarnnam(name, "not supported on this system.", NULL, 0);
+    zfwarnnam(name, "not supported on this system.");
     return 3;
 #endif /* defined(HAVE_POLL) || defined(HAVE_SELECT) */
 }
@@ -2451,7 +2449,7 @@ zftp_type(char *name, char **args, int flags)
 	 * ones we know what to do with.
 	 */
 	if (str[1] || (nt != 'A' && nt != 'B' && nt != 'I')) {
-	    zwarnnam(name, "transfer type %s not recognised", str, 0);
+	    zwarnnam(name, "transfer type %s not recognised", str);
 	    return 1;
 	}
 	
@@ -2481,7 +2479,7 @@ zftp_mode(char *name, char **args, UNUSED(int flags))
     }
     nt = str[0] = toupper(STOUC(*str));
     if (str[1] || (nt != 'S' && nt != 'B')) {
-	zwarnnam(name, "transfer mode %s not recognised", str, 0);
+	zwarnnam(name, "transfer mode %s not recognised", str);
 	return 1;
     }
     cmd[5] = (char) nt;
@@ -3017,7 +3015,7 @@ bin_zftp(char *name, char **args, UNUSED(Options ops), UNUSED(int func))
 	    break;
 
     if (!zptr->nam) {
-	zwarnnam(name, "no such subcommand: %s", cnam, 0);
+	zwarnnam(name, "no such subcommand: %s", cnam);
 	return 1;
     }
 
@@ -3025,7 +3023,7 @@ bin_zftp(char *name, char **args, UNUSED(Options ops), UNUSED(int func))
     for (n = 0; args[n]; n++)
 	;
     if (n < zptr->min || (zptr->max != -1 && n > zptr->max)) {
-	zwarnnam(name, "wrong no. of arguments for %s", cnam, 0);
+	zwarnnam(name, "wrong no. of arguments for %s", cnam);
 	return 1;
     }
 
@@ -3072,7 +3070,7 @@ bin_zftp(char *name, char **args, UNUSED(Options ops), UNUSED(int func))
 	     * with ret == 2, we just got dumped out in the test,
 	     * so enough messages already.
 	     */	       
-	    zwarnnam(fullname, "not connected.", NULL, 0);
+	    zwarnnam(fullname, "not connected.");
 	}
 	return 1;
     }
@@ -3103,7 +3101,7 @@ bin_zftp(char *name, char **args, UNUSED(Options ops), UNUSED(int func))
 		break;
 
 	    default:
-		zwarnnam(name, "preference %c not recognized", NULL, *ptr);
+		zwarnnam(name, "preference %c not recognized", *ptr);
 		break;
 	    }
 	}
diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c
index 637d3e62f..744548f50 100644
--- a/Src/Modules/zpty.c
+++ b/Src/Modules/zpty.c
@@ -128,7 +128,7 @@ ptysettyinfo(int fd, struct ttyinfo *ti)
 	ioctl(fd, TCSETS, &ti->tio);
     /* if (ioctl(SHTTY, TCSETS, &ti->tio) == -1) */
 # endif
-	/*	zerr("settyinfo: %e",NULL,errno)*/ ;
+	/*	zerr("settyinfo: %e",errno)*/ ;
 #else
 # ifdef HAVE_TERMIO_H
 	ioctl(fd, TCSETA, &ti->tio);
@@ -300,7 +300,7 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
     }
 
     if (get_pty(1, &master)) {
-	zwarnnam(nam, "can't open pseudo terminal: %e", NULL, errno);
+	zwarnnam(nam, "can't open pseudo terminal: %e", errno);
 	return 1;
     }
     if ((pid = fork()) == -1) {
@@ -316,11 +316,11 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
 	mypid = getpid();
 #ifdef HAVE_SETSID
 	if (setsid() != mypid) {
-	    zwarnnam(nam, "failed to create new session: %e", NULL, errno);
+	    zwarnnam(nam, "failed to create new session: %e", errno);
 #endif
 #ifdef TIOCNOTTY
 	    if (ioctl(SHTTY, TIOCNOTTY, 0))
-		zwarnnam(nam, "%e", NULL, errno);
+		zwarnnam(nam, "%e", errno);
 	    setpgrp(0L, mypid);
 #endif
 #ifdef HAVE_SETSID
@@ -478,14 +478,14 @@ ptyread(char *nam, Ptycmd cmd, char **args)
 	char *p;
 
 	if (args[2]) {
-	    zwarnnam(nam, "too many arguments", NULL, 0);
+	    zwarnnam(nam, "too many arguments");
 	    return 1;
 	}
 	p = dupstring(args[1]);
 	tokenize(p);
 	remnulargs(p);
 	if (!(prog = patcompile(p, PAT_STATIC, NULL))) {
-	    zwarnnam(nam, "bad pattern: %s", args[1], 0);
+	    zwarnnam(nam, "bad pattern: %s", args[1]);
 	    return 1;
 	}
     } else
@@ -633,17 +633,17 @@ bin_zpty(char *nam, char **args, Options ops, UNUSED(int func))
 	(OPT_ISSET(ops,'d') && (OPT_ISSET(ops,'b') || OPT_ISSET(ops,'e') ||
 				OPT_ISSET(ops,'L') || OPT_ISSET(ops,'t'))) ||
 	(OPT_ISSET(ops,'L') && (OPT_ISSET(ops,'b') || OPT_ISSET(ops,'e')))) {
-	zwarnnam(nam, "illegal option combination", NULL, 0);
+	zwarnnam(nam, "illegal option combination");
 	return 1;
     }
     if (OPT_ISSET(ops,'r') || OPT_ISSET(ops,'w')) {
 	Ptycmd p;
 
 	if (!*args) {
-	    zwarnnam(nam, "missing pty command name", NULL, 0);
+	    zwarnnam(nam, "missing pty command name");
 	    return 1;
 	} else if (!(p = getptycmd(*args))) {
-	    zwarnnam(nam, "no such pty command: %s", *args, 0);
+	    zwarnnam(nam, "no such pty command: %s", *args);
 	    return 1;
 	}
 	if (p->fin)
@@ -664,7 +664,7 @@ bin_zpty(char *nam, char **args, Options ops, UNUSED(int func))
 		if ((p = getptycmd(*args++)))
 		    deleteptycmd(p);
 		else {
-		    zwarnnam(nam, "no such pty command: %s", args[-1], 0);
+		    zwarnnam(nam, "no such pty command: %s", args[-1]);
 		    ret = 1;
 		}
 	} else
@@ -675,21 +675,21 @@ bin_zpty(char *nam, char **args, Options ops, UNUSED(int func))
 	Ptycmd p;
 
 	if (!*args) {
-	    zwarnnam(nam, "missing pty command name", NULL, 0);
+	    zwarnnam(nam, "missing pty command name");
 	    return 1;
 	} else if (!(p = getptycmd(*args))) {
-	    zwarnnam(nam, "no such pty command: %s", *args, 0);
+	    zwarnnam(nam, "no such pty command: %s", *args);
 	    return 1;
 	}
 	checkptycmd(p);
 	return p->fin;
     } else if (*args) {
 	if (!args[1]) {
-	    zwarnnam(nam, "missing command", NULL, 0);
+	    zwarnnam(nam, "missing command");
 	    return 1;
 	}
 	if (getptycmd(*args)) {
-	    zwarnnam(nam, "pty command name already used: %s", *args, 0);
+	    zwarnnam(nam, "pty command name already used: %s", *args);
 	    return 1;
 	}
 	return newptycmd(nam, *args, args + 1, OPT_ISSET(ops,'e'), 
diff --git a/Src/Modules/zselect.c b/Src/Modules/zselect.c
index 71a0d7e76..4e547a47e 100644
--- a/Src/Modules/zselect.c
+++ b/Src/Modules/zselect.c
@@ -43,12 +43,12 @@ handle_digits(char *nam, char *argptr, fd_set *fdset, int *fdmax)
     char *endptr;
 
     if (!idigit(*argptr)) {
-	zwarnnam(nam, "expecting file descriptor: %s", argptr, 0);
+	zwarnnam(nam, "expecting file descriptor: %s", argptr);
 	return 1;
     }
     fd = (int)zstrtol(argptr, &endptr, 10);
     if (*endptr) {
-	zwarnnam(nam, "garbage after file descriptor: %s", endptr, 0);
+	zwarnnam(nam, "garbage after file descriptor: %s", endptr);
 	return 1;
     }
 
@@ -95,12 +95,11 @@ bin_zselect(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		    else if (args[1]) {
 			argptr = *++args;
 		    } else {
-			zwarnnam(nam, "argument expected after -%c", NULL,
-				 *argptr);
+			zwarnnam(nam, "argument expected after -%c", *argptr);
 			return 1;
 		    }
 		    if (idigit(*argptr) || !isident(argptr)) {
-			zwarnnam(nam, "invalid array name: %s", argptr, 0);
+			zwarnnam(nam, "invalid array name: %s", argptr);
 			return 1;
 		    }
 		    if (i == 'a')
@@ -138,18 +137,17 @@ bin_zselect(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		    else if (args[1]) {
 			argptr = *++args;
 		    } else {
-			zwarnnam(nam, "argument expected after -%c", NULL, 
-				 *argptr);
+			zwarnnam(nam, "argument expected after -%c", *argptr);
 			return 1;
 		    }
 		    if (!idigit(*argptr)) {
-			zwarnnam(nam, "number expected after -t", NULL, 0);
+			zwarnnam(nam, "number expected after -t");
 			return 1;
 		    }
 		    tempnum = zstrtol(argptr, &endptr, 10);
 		    if (*endptr) {
 			zwarnnam(nam, "garbage after -t argument: %s",
-				 endptr, 0);
+				 endptr);
 			return 1;
 		    }
 		    /* timevalue now active */
@@ -180,7 +178,7 @@ bin_zselect(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 
     if (i <= 0) {
 	if (i < 0)
-	    zwarnnam(nam, "error on select: %e", NULL, errno);
+	    zwarnnam(nam, "error on select: %e", errno);
 	/* else no fd's set.  Presumably a timeout. */
 	return 1;
     }
@@ -264,8 +262,7 @@ bin_zselect(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     return 0;
 #else
     /* TODO: use poll */
-    zerrnam(nam, "your system does not implement the select system call.",
-	    NULL, 0);
+    zerrnam(nam, "your system does not implement the select system call.");
     return 2;
 #endif
 }
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index c88e66288..c2298a782 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -265,7 +265,7 @@ bin_zstyle(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 
 	if ((oc = args[0][1]) && oc != '-') {
 	    if (args[0][2]) {
-		zwarnnam(nam, "invalid argument: %s", args[0], 0);
+		zwarnnam(nam, "invalid argument: %s", args[0]);
 		return 1;
 	    }
 	    if (oc == 'L')
@@ -287,14 +287,14 @@ bin_zstyle(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	char *pat;
 
 	if (arrlen(args) < 2) {
-	    zwarnnam(nam, "not enough arguments", NULL, 0);
+	    zwarnnam(nam, "not enough arguments");
 	    return 1;
 	}
 	pat = dupstring(args[0]);
 	tokenize(pat);
 
 	if (!(prog = patcompile(pat, PAT_ZDUP, NULL))) {
-	    zwarnnam(nam, "invalid pattern: %s", args[0], 0);
+	    zwarnnam(nam, "invalid pattern: %s", args[0]);
 	    return 1;
 	}
 	if (!(s = getstyle(args[1])))
@@ -338,15 +338,15 @@ bin_zstyle(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     case 'm': min = 3; max =  3; break;
     case 'g': min = 1; max =  3; break;
     default:
-	zwarnnam(nam, "invalid option: %s", args[0], 0);
+	zwarnnam(nam, "invalid option: %s", args[0]);
 	return 1;
     }
     n = arrlen(args) - 1;
     if (n < min) {
-	zwarnnam(nam, "not enough arguments", NULL, 0);
+	zwarnnam(nam, "not enough arguments");
 	return 1;
     } else if (max >= 0 && n > max) {
-	zwarnnam(nam, "too many arguments", NULL, 0);
+	zwarnnam(nam, "too many arguments");
 	return 1;
     }
     switch (args[0][1]) {
@@ -697,7 +697,7 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     char opt;
 
     if (args[0][0] != '-' || !(opt = args[0][1]) || args[0][2]) {
-	zwarnnam(nam, "invalid argument: %s", args[0], 0);
+	zwarnnam(nam, "invalid argument: %s", args[0]);
 	return 1;
     }
     args++;
@@ -715,7 +715,7 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	    for (ap = args + 2; *ap; ap++) {
 		if (!ap[0][0] || ap[0][0] == '-' || ap[0][0] == '.' ||
 		    idigit(ap[0][0]) || ap[0][1] != ':') {
-		    zwarnnam(nam, "invalid argument: %s", *ap, 0);
+		    zwarnnam(nam, "invalid argument: %s", *ap);
 		    return 1;
 		}
 		specs[STOUC(ap[0][0])] = ap[0] + 2;
@@ -784,7 +784,7 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	}
 	break;
     }
-    zwarnnam(nam, "invalid option: -%c", 0, opt);
+    zwarnnam(nam, "invalid option: -%c", opt);
     return 1;
 }
 
@@ -1249,9 +1249,9 @@ bin_zregexparse(char *nam, char **args, Options ops, UNUSED(int func))
     rparsestates = newlinklist();
     if (setjmp(rparseerr) || rparsealt(&result, &rparseerr) || *rparseargs) {
 	if (*rparseargs)
-	    zwarnnam(nam, "invalid regex : %s", *rparseargs, 0);
+	    zwarnnam(nam, "invalid regex : %s", *rparseargs);
 	else
-	    zwarnnam(nam, "not enough regex arguments", NULL, 0);
+	    zwarnnam(nam, "not enough regex arguments");
 	ret = 3;
     } else
 	ret = 0;
@@ -1434,7 +1434,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		break;
 	    case 'a':
 		if (defarr) {
-		    zwarnnam(nam, "default array given more than once", NULL, 0);
+		    zwarnnam(nam, "default array given more than once");
 		    return 1;
 		}
 		if (o[2])
@@ -1442,7 +1442,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		else if (*args)
 		    n = *args++;
 		else {
-		    zwarnnam(nam, "missing array name", NULL, 0);
+		    zwarnnam(nam, "missing array name");
 		    return 1;
 		}
 		defarr = (Zoptarr) zhalloc(sizeof(*defarr));
@@ -1458,7 +1458,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		else if (*args)
 		    assoc = *args++;
 		else {
-		    zwarnnam(nam, "missing array name", NULL, 0);
+		    zwarnnam(nam, "missing array name");
 		    return 1;
 		}
 		break;
@@ -1473,12 +1473,12 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	}
     }
     if (!o) {
-	zwarnnam(nam, "missing option descriptions", NULL, 0);
+	zwarnnam(nam, "missing option descriptions");
 	return 1;
     }
     while ((o = dupstring(*args++))) {
 	if (!*o) {
-	    zwarnnam(nam, "invalid option description: %s", o, 0);
+	    zwarnnam(nam, "invalid option description: %s", o);
 	    return 1;
 	}
 	f = 0;
@@ -1517,10 +1517,10 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		opt_arrs = a;
 	    }
 	} else if (*p) {
-	    zwarnnam(nam, "invalid option description: %s", args[-1], 0);
+	    zwarnnam(nam, "invalid option description: %s", args[-1]);
 	    return 1;
 	} else if (!(a = defarr) && !assoc) {
-	    zwarnnam(nam, "no default array defined: %s", args[-1], 0);
+	    zwarnnam(nam, "no default array defined: %s", args[-1]);
 	    return 1;
 	}
 	for (p = n = o; *p; p++) {
@@ -1529,7 +1529,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	    *n++ = *p;
 	}
 	if (get_opt_desc(o)) {
-	    zwarnnam(nam, "option defined more than once: %s", o, 0);
+	    zwarnnam(nam, "option defined more than once: %s", o);
 	    return 1;
 	}
 	d = (Zoptdesc) zhalloc(sizeof(*d));
@@ -1571,7 +1571,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		    } else if (!(d->flags & ZOF_OPT)) {
 			if (!pp[1]) {
 			    zwarnnam(nam, "missing argument for option: %s",
-				    d->name, 0);
+				    d->name);
 			    return 1;
 			}
 			add_opt_val(d, *++pp);
@@ -1597,7 +1597,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		else if (!(d->flags & ZOF_OPT)) {
 		    if (!pp[1]) {
 			zwarnnam(nam, "missing argument for option: %s",
-				d->name, 0);
+				d->name);
 			return 1;
 		    }
 		    add_opt_val(d, *++pp);
diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c
index 1c994ef64..4389c434b 100644
--- a/Src/Zle/compctl.c
+++ b/Src/Zle/compctl.c
@@ -193,8 +193,7 @@ compctlread(char *name, char **args, Options ops, char *reply)
 
     /* only allowed to be called for completion */
     if (!incompctlfunc) {
-	zwarnnam(name, "option valid only in functions called for completion",
-		NULL, 0);
+	zwarnnam(name, "option valid only in functions called for completion");
 	return 1;
     }
 
@@ -513,14 +512,14 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    char *p;
 
 		    if (cl) {
-			zwarnnam(name, "illegal option -%c", NULL, **argv);
+			zwarnnam(name, "illegal option -%c", **argv);
 			return 1;
 		    }
 		    if ((*argv)[1]) {
 			p = (*argv) + 1;
 			*argv = "" - 1;
 		    } else if (!argv[1]) {
-			zwarnnam(name, "retry specification expected after -%c", NULL,
+			zwarnnam(name, "retry specification expected after -%c",
 				 **argv);
 			return 1;
 		    } else {
@@ -542,12 +541,12 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 			break;
 		    default:
 			zwarnnam(name, "invalid retry specification character `%c'",
-				 NULL, *p);
+				 *p);
 			return 1;
 		    }
 		    if (p[1]) {
 			zwarnnam(name, "too many retry specification characters: `%s'",
-				 p + 1, 0);
+				 p + 1);
 			return 1;
 		    }
 		}
@@ -557,8 +556,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    cct.keyvar = (*argv) + 1;
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
-		    zwarnnam(name, "variable name expected after -%c", NULL,
-			    **argv);
+		    zwarnnam(name, "variable name expected after -%c", **argv);
 		    return 1;
 		} else {
 		    cct.keyvar = *++argv;
@@ -570,8 +568,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    cct.func = (*argv) + 1;
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
-		    zwarnnam(name, "function name expected after -%c", NULL,
-			    **argv);
+		    zwarnnam(name, "function name expected after -%c", **argv);
 		    return 1;
 		} else {
 		    cct.func = *++argv;
@@ -588,7 +585,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    cct.explain = (*argv) + 1;
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
-		    zwarnnam(name, "string expected after -%c", NULL, **argv);
+		    zwarnnam(name, "string expected after -%c", **argv);
 		    return 1;
 		} else {
 		    cct.explain = *++argv;
@@ -601,7 +598,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
 		    zwarnnam(name, "function/variable expected after -%c",
-			     NULL, **argv);
+			     **argv);
 		} else {
 		    cct.ylist = *++argv;
 		    *argv = "" - 1;
@@ -612,7 +609,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    cct.prefix = (*argv) + 1;
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
-		    zwarnnam(name, "string expected after -%c", NULL, **argv);
+		    zwarnnam(name, "string expected after -%c", **argv);
 		    return 1;
 		} else {
 		    cct.prefix = *++argv;
@@ -624,7 +621,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    cct.suffix = (*argv) + 1;
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
-		    zwarnnam(name, "string expected after -%c", NULL, **argv);
+		    zwarnnam(name, "string expected after -%c", **argv);
 		    return 1;
 		} else {
 		    cct.suffix = *++argv;
@@ -636,8 +633,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    cct.glob = (*argv) + 1;
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
-		    zwarnnam(name, "glob pattern expected after -%c", NULL,
-			    **argv);
+		    zwarnnam(name, "glob pattern expected after -%c", **argv);
 		    return 1;
 		} else {
 		    cct.glob = *++argv;
@@ -649,8 +645,8 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    cct.str = (*argv) + 1;
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
-		    zwarnnam(name, "command string expected after -%c", NULL,
-			    **argv);
+		    zwarnnam(name, "command string expected after -%c",
+			     **argv);
 		    return 1;
 		} else {
 		    cct.str = *++argv;
@@ -659,14 +655,13 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		break;
 	    case 'l':
 		if (cl) {
-		    zwarnnam(name, "illegal option -%c", NULL, **argv);
+		    zwarnnam(name, "illegal option -%c", **argv);
 		    return 1;
 		} else if ((*argv)[1]) {
 		    cct.subcmd = (*argv) + 1;
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
-		    zwarnnam(name, "command name expected after -%c", NULL,
-			    **argv);
+		    zwarnnam(name, "command name expected after -%c", **argv);
 		    return 1;
 		} else {
 		    cct.subcmd = *++argv;
@@ -675,14 +670,13 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		break;
 	    case 'h':
 		if (cl) {
-		    zwarnnam(name, "illegal option -%c", NULL, **argv);
+		    zwarnnam(name, "illegal option -%c", **argv);
 		    return 1;
 		} else if ((*argv)[1]) {
 		    cct.substr = (*argv) + 1;
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
-		    zwarnnam(name, "command name expected after -%c", NULL,
-			    **argv);
+		    zwarnnam(name, "command name expected after -%c", **argv);
 		    return 1;
 		} else {
 		    cct.substr = *++argv;
@@ -694,8 +688,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    cct.withd = (*argv) + 1;
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
-		    zwarnnam(name, "path expected after -%c", NULL,
-			    **argv);
+		    zwarnnam(name, "path expected after -%c", **argv);
 		    return 1;
 		} else {
 		    cct.withd = *++argv;
@@ -707,8 +700,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    cct.gname = (*argv) + 1;
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
-		    zwarnnam(name, "group name expected after -%c", NULL,
-			    **argv);
+		    zwarnnam(name, "group name expected after -%c", **argv);
 		    return 1;
 		} else {
 		    cct.gname = *++argv;
@@ -720,8 +712,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    cct.gname = (*argv) + 1;
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
-		    zwarnnam(name, "group name expected after -%c", NULL,
-			    **argv);
+		    zwarnnam(name, "group name expected after -%c", **argv);
 		    return 1;
 		} else {
 		    cct.gname = *++argv;
@@ -750,8 +741,8 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    }
 		    *argv = "" - 1;
 		} else if (!argv[1]) {
-		    zwarnnam(name, "matching specification expected after -%c", NULL,
-			    **argv);
+		    zwarnnam(name, "matching specification expected after -%c",
+			     **argv);
 		    return 1;
 		} else {
 		    if ((cct.matcher =
@@ -770,13 +761,11 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		else if (argv[1])
 		    cct.hnum = atoi(*++argv);
 		else {
-		    zwarnnam(name, "number expected after -%c", NULL,
-			    **argv);
+		    zwarnnam(name, "number expected after -%c", **argv);
 		    return 1;
 		}
 		if (!argv[1]) {
-		    zwarnnam(name, "missing pattern after -%c", NULL,
-			    **argv);
+		    zwarnnam(name, "missing pattern after -%c", **argv);
 		    return 1;
 		}
 		cct.hpat = *++argv;
@@ -788,63 +777,59 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		break;
 	    case 'C':
 		if (cl) {
-		    zwarnnam(name, "illegal option -%c", NULL, **argv);
+		    zwarnnam(name, "illegal option -%c", **argv);
 		    return 1;
 		}
 		if (first && !hx) {
 		    cclist |= COMP_COMMAND;
 		} else {
-		    zwarnnam(name, "misplaced command completion (-C) flag",
-			    NULL, 0);
+		    zwarnnam(name, "misplaced command completion (-C) flag");
 		    return 1;
 		}
 		break;
 	    case 'D':
 		if (cl) {
-		    zwarnnam(name, "illegal option -%c", NULL, **argv);
+		    zwarnnam(name, "illegal option -%c", **argv);
 		    return 1;
 		}
 		if (first && !hx) {
 		    isdef = 1;
 		    cclist |= COMP_DEFAULT;
 		} else {
-		    zwarnnam(name, "misplaced default completion (-D) flag",
-			    NULL, 0);
+		    zwarnnam(name, "misplaced default completion (-D) flag");
 		    return 1;
 		}
 		break;
  	    case 'T':
 		if (cl) {
-		    zwarnnam(name, "illegal option -%c", NULL, **argv);
+		    zwarnnam(name, "illegal option -%c", **argv);
 		    return 1;
 		}
 		if (first && !hx) {
  		    cclist |= COMP_FIRST;
  		} else {
- 		    zwarnnam(name, "misplaced first completion (-T) flag",
- 			    NULL, 0);
+ 		    zwarnnam(name, "misplaced first completion (-T) flag");
  		    return 1;
  		}
  		break;
 	    case 'L':
 		if (cl) {
-		    zwarnnam(name, "illegal option -%c", NULL, **argv);
+		    zwarnnam(name, "illegal option -%c", **argv);
 		    return 1;
 		}
 		if (!first || hx) {
-		    zwarnnam(name, "illegal use of -L flag", NULL, 0);
+		    zwarnnam(name, "illegal use of -L flag");
 		    return 1;
 		}
 		cclist |= COMP_LIST;
 		break;
 	    case 'x':
 		if (cl) {
-		    zwarnnam(name, "extended completion not allowed", NULL, 0);
+		    zwarnnam(name, "extended completion not allowed");
 		    return 1;
 		}
 		if (!argv[1]) {
-		    zwarnnam(name, "condition expected after -%c", NULL,
-			    **argv);
+		    zwarnnam(name, "condition expected after -%c", **argv);
 		    return 1;
 		}
 		if (first) {
@@ -856,8 +841,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		    }
 		    ready = 2;
 		} else {
-		    zwarnnam(name, "recursive extended completion not allowed",
-			    NULL, 0);
+		    zwarnnam(name, "recursive extended completion not allowed");
 		    return 1;
 		}
 		break;
@@ -865,7 +849,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		if (!first && (**argv == '-' || **argv == '+') && !argv[0][1])
 		    (*argv)--, argv--, ready = 1;
 		else {
-		    zwarnnam(name, "bad option: -%c", NULL, **argv);
+		    zwarnnam(name, "bad option: -%c", **argv);
 		    return 1;
 		}
 	    }
@@ -874,7 +858,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 	if (*++argv && (!ready || ready == 2) &&
 	    **argv == '+' && !argv[0][1]) {
 	    if (cl) {
-		zwarnnam(name, "xor'ed completion illegal", NULL, 0);
+		zwarnnam(name, "xor'ed completion illegal");
 		return 1;
 	    }
 	    /* There's an alternative (+) completion:  assign
@@ -892,8 +876,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
 		/* No argument to +, which means do default completion */
 		if (isdef)
 		    zwarnnam(name,
-			    "recursive xor'd default completions not allowed",
-			    NULL, 0);
+			    "recursive xor'd default completions not allowed");
 		else
 		    cc->xor = &cc_default;
 	    } else {
@@ -983,7 +966,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
 		break;
 	    default:
 		t[1] = '\0';
-		zwarnnam(name, "unknown condition code: %s", t, 0);
+		zwarnnam(name, "unknown condition code: %s", t);
 		zfree(m, sizeof(struct compcond));
 
 		return 1;
@@ -991,7 +974,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
 	    /* Now get the arguments in square brackets */
 	    if (t[1] != '[') {
 		t[1] = '\0';
-		zwarnnam(name, "expected condition after condition code: %s", t, 0);
+		zwarnnam(name, "expected condition after condition code: %s", t);
 		zfree(m, sizeof(struct compcond));
 
 		return 1;
@@ -1016,7 +999,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
 
 	    if (l) {
 		t[1] = '\0';
-		zwarnnam(name, "error after condition code: %s", t, 0);
+		zwarnnam(name, "error after condition code: %s", t);
 		zfree(m, sizeof(struct compcond));
 
 		return 1;
@@ -1050,7 +1033,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
 		    /* p[...] or m[...]:  one or two numbers expected */
 		    for (; *t && *t != '\201' && *t != '\200'; t++);
 		    if (!(sav = *t)) {
-			zwarnnam(name, "error in condition", NULL, 0);
+			zwarnnam(name, "error in condition");
 			freecompcond(m);
 			return 1;
 		    }
@@ -1064,7 +1047,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
 			tt = ++t;
 			for (; *t && *t != '\200'; t++);
 			if (!*t) {
-			    zwarnnam(name, "error in condition", NULL, 0);
+			    zwarnnam(name, "error in condition");
 			    freecompcond(m);
 			    return 1;
 			}
@@ -1079,7 +1062,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
 			if (*t == '\201')
 			    *t = ',';
 		    if (!*t) {
-			zwarnnam(name, "error in condition", NULL, 0);
+			zwarnnam(name, "error in condition");
 			freecompcond(m);
 			return 1;
 		    }
@@ -1092,7 +1075,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
 		    /* -r[..,..] or -R[..,..]:  two strings expected */
 		    for (; *t && *t != '\201' && *t != '\200'; t++);
 		    if (!*t) {
-			zwarnnam(name, "error in condition", NULL, 0);
+			zwarnnam(name, "error in condition");
 			freecompcond(m);
 			return 1;
 		    }
@@ -1106,7 +1089,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
 			    if (*t == '\201')
 				*t = ',';
 			if (!*t) {
-			    zwarnnam(name, "error in condition", NULL, 0);
+			    zwarnnam(name, "error in condition");
 			    freecompcond(m);
 			    return 1;
 			}
@@ -1119,7 +1102,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
 		    /* remaining patterns are number followed by string */
 		    for (; *t && *t != '\200' && *t != '\201'; t++);
 		    if (!*t || *t == '\200') {
-			zwarnnam(name, "error in condition", NULL, 0);
+			zwarnnam(name, "error in condition");
 			freecompcond(m);
 			return 1;
 		    }
@@ -1130,7 +1113,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
 			if (*t == '\201')
 			    *t = ',';
 		    if (!*t) {
-			zwarnnam(name, "error in condition", NULL, 0);
+			zwarnnam(name, "error in condition");
 			freecompcond(m);
 			return 1;
 		    }
@@ -1167,7 +1150,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
 	     */
 	    if (!argv || !*argv || **argv != '-' ||
 		((!argv[0][1] || argv[0][1] == '+') && !argv[1])) {
-		zwarnnam(name, "missing command names", NULL, 0);
+		zwarnnam(name, "missing command names");
 		return 1;
 	    }
 	    if (!strcmp(*argv, "--"))
@@ -1201,7 +1184,7 @@ cc_assign(char *name, Compctl *ccptr, Compctl cct, int reass)
 	    || cclist == (COMP_COMMAND|COMP_FIRST)
 	    || cclist == (COMP_DEFAULT|COMP_FIRST)
 	    || cclist == COMP_SPECIAL) {
- 	    zwarnnam(name, "can't set -D, -T, and -C simultaneously", NULL, 0);
+ 	    zwarnnam(name, "can't set -D, -T, and -C simultaneously");
 	    /* ... because the following code wouldn't work. */
 	    return 1;
 	}
@@ -1648,7 +1631,7 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 		n = NULL;
 	    }
 	    if (n) {
-		zwarnnam(name, "no compctl defined for %s", n, 0);
+		zwarnnam(name, "no compctl defined for %s", n);
 		ret = 1;
 	    }
 	}
@@ -1669,7 +1652,7 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 	    /* Ideally we'd handle this properly, setting both the *
 	     * special and normal completions.  For the moment,    *
 	     * this is better than silently failing.               */
-	    zwarnnam(name, "extraneous commands ignored", NULL, 0);
+	    zwarnnam(name, "extraneous commands ignored");
 	else
 	    compctl_process_cc(argv, cc);
     }
@@ -1686,7 +1669,7 @@ static int
 bin_compcall(char *name, UNUSED(char **argv), Options ops, UNUSED(int func))
 {
     if (incompfunc != 1) {
-	zwarnnam(name, "can only be called from completion function", NULL, 0);
+	zwarnnam(name, "can only be called from completion function");
 	return 1;
     }
     return makecomplistctl((OPT_ISSET(ops,'T') ? 0 : CFN_FIRST) |
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 1da9c7f19..46e9a06d8 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -213,18 +213,18 @@ parse_cmatcher(char *name, char *s)
 	default:
 	    if (name)
 		zwarnnam(name, "unknown match specification character `%c'",
-			 NULL, *s);
+			 *s);
 	    return pcm_err;
 	}
 	if (s[1] != ':') {
 	    if (name)
-		zwarnnam(name, "missing `:'", NULL, 0);
+		zwarnnam(name, "missing `:'");
 	    return pcm_err;
 	}
 	s += 2;
 	if (!*s) {
 	    if (name)
-		zwarnnam(name, "missing patterns", NULL, 0);
+		zwarnnam(name, "missing patterns");
 	    return pcm_err;
 	}
 	if ((fl & CMF_LEFT) && !fl2) {
@@ -237,7 +237,7 @@ parse_cmatcher(char *name, char *s)
 
 	    if (!*s || !*++s) {
 		if (name)
-		    zwarnnam(name, "missing line pattern", NULL, 0);
+		    zwarnnam(name, "missing line pattern");
 		return pcm_err;
 	    }
 	} else
@@ -256,11 +256,11 @@ parse_cmatcher(char *name, char *s)
 	}
 	if ((fl & CMF_RIGHT) && !fl2 && (!*s || !*++s)) {
 	    if (name)
-		zwarnnam(name, "missing right anchor", NULL, 0);
+		zwarnnam(name, "missing right anchor");
 	} else if (!(fl & CMF_RIGHT) || fl2) {
 	    if (!*s) {
 		if (name)
-		    zwarnnam(name, "missing word pattern", NULL, 0);
+		    zwarnnam(name, "missing word pattern");
 		return pcm_err;
 	    }
 	    s++;
@@ -278,7 +278,7 @@ parse_cmatcher(char *name, char *s)
 		return pcm_err;
 	    if (!*s) {
 		if (name)
-		    zwarnnam(name, "missing word pattern", NULL, 0);
+		    zwarnnam(name, "missing word pattern");
 		return pcm_err;
 	    }
 	    s++;
@@ -288,7 +288,7 @@ parse_cmatcher(char *name, char *s)
 	if (*s == '*') {
 	    if (!(fl & (CMF_LEFT | CMF_RIGHT))) {
 		if (name)
-		    zwarnnam(name, "need anchor for `*'", NULL, 0);
+		    zwarnnam(name, "need anchor for `*'");
 		return pcm_err;
 	    }
 	    word = NULL;
@@ -302,8 +302,7 @@ parse_cmatcher(char *name, char *s)
 
 	    if (!word && !line) {
 		if (name)
-		    zwarnnam(name, "need non-empty word or line pattern",
-			     NULL, 0);
+		    zwarnnam(name, "need non-empty word or line pattern");
 		return pcm_err;
 	    }
 	}
@@ -353,7 +352,7 @@ parse_pattern(char *name, char **sp, int *lp, char e, int *err)
 	    s = parse_class(n, s + 1, ']');
 	    if (!*s) {
 		*err = 1;
-		zwarnnam(name, "unterminated character class", NULL, 0);
+		zwarnnam(name, "unterminated character class");
 		return NULL;
 	    }
 	} else if (*s == '{') {
@@ -361,14 +360,14 @@ parse_pattern(char *name, char **sp, int *lp, char e, int *err)
 	    s = parse_class(n, s + 1, '}');
 	    if (!*s) {
 		*err = 1;
-		zwarnnam(name, "unterminated character class", NULL, 0);
+		zwarnnam(name, "unterminated character class");
 		return NULL;
 	    }
 	} else if (*s == '?') {
 	    memset(n->tab, 1, 256);
 	} else if (*s == '*' || *s == '(' || *s == ')' || *s == '=') {
 	    *err = 1;
-	    zwarnnam(name, "invalid pattern character `%c'", NULL, *s);
+	    zwarnnam(name, "invalid pattern character `%c'", *s);
 	    return NULL;
 	} else {
 	    if (*s == '\\' && s[1])
@@ -429,7 +428,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
     Cmatcher match = NULL;
 
     if (incompfunc != 1) {
-	zwarnnam(name, "can only be called from completion function", NULL, 0);
+	zwarnnam(name, "can only be called from completion function");
 	return 1;
     }
     dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre = dat.mesg =
@@ -581,11 +580,11 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
                     dat.dummies = atoi(*argv);
                     p = "" - 1;
                 } else {
-                    zwarnnam(name, "number expected after -%c", NULL, *p);
+                    zwarnnam(name, "number expected after -%c", *p);
                     return 1;
                 }
                 if (dat.dummies < 0) {
-                    zwarnnam(name, "invalid number: %d", NULL, dat.dummies);
+                    zwarnnam(name, "invalid number: %d", dat.dummies);
                     return 1;
                 }
 		break;
@@ -593,7 +592,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 		argv++;
 		goto ca_args;
 	    default:
-		zwarnnam(name, "bad option: -%c", NULL, *p);
+		zwarnnam(name, "bad option: -%c", *p);
 		return 1;
 	    }
 	    if (sp) {
@@ -607,7 +606,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 			*sp = *argv;
 		    p = "" - 1;
 		} else {
-		    zwarnnam(name, e, NULL, *p);
+		    zwarnnam(name, e, *p);
 		    return 1;
 		}
 		if (dm) {
@@ -904,11 +903,11 @@ bin_compset(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
     char *sa = NULL, *sb = NULL;
 
     if (incompfunc != 1) {
-	zwarnnam(name, "can only be called from completion function", NULL, 0);
+	zwarnnam(name, "can only be called from completion function");
 	return 1;
     }
     if (argv[0][0] != '-') {
-	zwarnnam(name, "missing option", NULL, 0);
+	zwarnnam(name, "missing option");
 	return 1;
     }
     switch (argv[0][1]) {
@@ -920,7 +919,7 @@ bin_compset(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
     case 'S': test = CVT_SUFPAT; break;
     case 'q': return set_comp_sep();
     default:
-	zwarnnam(name, "bad option -%c", NULL, argv[0][1]);
+	zwarnnam(name, "bad option -%c", argv[0][1]);
 	return 1;
     }
     if (argv[0][2]) {
@@ -929,7 +928,7 @@ bin_compset(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 	na = 2;
     } else {
 	if (!(sa = argv[1])) {
-	    zwarnnam(name, "missing string for option -%c", NULL, argv[0][1]);
+	    zwarnnam(name, "missing string for option -%c", argv[0][1]);
 	    return 1;
 	}
 	sb = argv[2];
@@ -937,7 +936,7 @@ bin_compset(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
     }
     if (((test == CVT_PRENUM || test == CVT_SUFNUM) ? !!sb :
 	 (sb && argv[na]))) {
-	zwarnnam(name, "too many arguments", NULL, 0);
+	zwarnnam(name, "too many arguments");
 	return 1;
     }
     switch (test) {
@@ -1390,7 +1389,7 @@ static int
 comp_check(void)
 {
     if (incompfunc != 1) {
-	zerr("condition can only be used in completion function", NULL, 0);
+	zerr("condition can only be used in completion function");
 	return 0;
     }
     return 1;
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index e380f5762..0bea231c5 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -3076,8 +3076,7 @@ boot_(Module m)
     w_menuselect = addzlefunction("menu-select", menuselect,
                                     ZLE_MENUCMP|ZLE_KEEPSUFFIX|ZLE_ISCOMP);
     if (!w_menuselect) {
-	zwarnnam(m->nam, "name clash when adding ZLE function `menu-select'",
-		 NULL, 0);
+	zwarnnam(m->nam, "name clash when adding ZLE function `menu-select'");
 	return -1;
     }
     addhookfunc("comp_list_matches", (Hookfn) complistmatches);
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index af813a376..fab854736 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -465,7 +465,7 @@ cd_init(char *nam, char *hide, char *mlen, char *sep,
         set->strs = NULL;
 
 	if (!(ap = get_user_var(*args))) {
-	    zwarnnam(nam, "invalid argument: %s", *args, 0);
+	    zwarnnam(nam, "invalid argument: %s", *args);
             zsfree(cd_state.sep);
             freecdsets(cd_state.sets);
 	    return 1;
@@ -495,7 +495,7 @@ cd_init(char *nam, char *hide, char *mlen, char *sep,
 
 	if (*++args && **args != '-') {
 	    if (!(ap = get_user_var(*args))) {
-		zwarnnam(nam, "invalid argument: %s", *args, 0);
+		zwarnnam(nam, "invalid argument: %s", *args);
                 zsfree(cd_state.sep);
                 freecdsets(cd_state.sets);
 		return 1;
@@ -722,31 +722,31 @@ bin_compdescribe(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     int n = arrlen(args);
 
     if (incompfunc != 1) {
-	zwarnnam(nam, "can only be called from completion function", NULL, 0);
+	zwarnnam(nam, "can only be called from completion function");
 	return 1;
     }
     if (!args[0][0] || !args[0][1] || args[0][2]) {
-	zwarnnam(nam, "invalid argument: %s", args[0], 0);
+	zwarnnam(nam, "invalid argument: %s", args[0]);
 	return 1;
     }
     switch (args[0][1]) {
     case 'i':
         if (n < 3) {
-            zwarnnam(nam, "not enough arguments", NULL, 0);
+            zwarnnam(nam, "not enough arguments");
 
             return 1;
         }
 	return cd_init(nam, args[1], args[2], "", NULL, args + 3, 0);
     case 'I':
         if (n < 6) {
-            zwarnnam(nam, "not enough arguments", NULL, 0);
+            zwarnnam(nam, "not enough arguments");
 
             return 1;
         } else {
             char **opts;
 
             if (!(opts = getaparam(args[4]))) {
-		zwarnnam(nam, "unknown parameter: %s", args[4], 0);
+		zwarnnam(nam, "unknown parameter: %s", args[4]);
 		return 1;
             }
             return cd_init(nam, args[1], args[2], args[3], opts, args + 5, 1);
@@ -755,16 +755,16 @@ bin_compdescribe(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	if (cd_parsed) {
 	    if (n != 5) {
 		zwarnnam(nam, (n < 5 ? "not enough arguments" :
-			      "too many arguments"), NULL, 0);
+			      "too many arguments"));
 		return 1;
 	    }
 	    return cd_get(args + 1);
 	} else {
-	    zwarnnam(nam, "no parsed state", NULL, 0);
+	    zwarnnam(nam, "no parsed state");
 	    return 1;
 	}
     }
-    zwarnnam(nam, "invalid option: %s", args[0], 0);
+    zwarnnam(nam, "invalid option: %s", args[0]);
     return 1;
 }
 
@@ -1199,7 +1199,7 @@ parse_cadef(char *nam, char **args)
 	    /* Oops, end-of-string. */
 	    if (*p != ')') {
 		freecadef(all);
-		zwarnnam(nam, "invalid argument: %s", *args, 0);
+		zwarnnam(nam, "invalid argument: %s", *args);
 		return NULL;
 	    }
 	    if (doset && axor)
@@ -1252,7 +1252,7 @@ parse_cadef(char *nam, char **args)
 	    }
 	    if (!p[1]) {
 		freecadef(all);
-		zwarnnam(nam, "invalid argument: %s", *args, 0);
+		zwarnnam(nam, "invalid argument: %s", *args);
 		return NULL;
 	    }
 
@@ -1289,7 +1289,7 @@ parse_cadef(char *nam, char **args)
 
 		if (!*p) {
 		    freecadef(all);
-		    zwarnnam(nam, "invalid option definition: %s", *args, 0);
+		    zwarnnam(nam, "invalid option definition: %s", *args);
 		    return NULL;
 		}
 		*p++ = '\0';
@@ -1299,7 +1299,7 @@ parse_cadef(char *nam, char **args)
 
 	    if (c && c != ':') {
 		freecadef(all);
-		zwarnnam(nam, "invalid option definition: %s", *args, 0);
+		zwarnnam(nam, "invalid option definition: %s", *args);
 		return NULL;
 	    }
 	    /* Add the option name to the xor list if not `*-...'. */
@@ -1345,7 +1345,7 @@ parse_cadef(char *nam, char **args)
 			    freecadef(all);
 			    freecaargs(oargs);
 			    zwarnnam(nam, "invalid option definition: %s",
-				    *args, 0);
+				    *args);
 			    return NULL;
 			}
 			if (*++p == ':') {
@@ -1429,12 +1429,12 @@ parse_cadef(char *nam, char **args)
 
 	    if (*++p != ':') {
 		freecadef(all);
-		zwarnnam(nam, "invalid rest argument definition: %s", *args, 0);
+		zwarnnam(nam, "invalid rest argument definition: %s", *args);
 		return NULL;
 	    }
 	    if (ret->rest) {
 		freecadef(all);
-		zwarnnam(nam, "doubled rest argument definition: %s", *args, 0);
+		zwarnnam(nam, "doubled rest argument definition: %s", *args);
 		return NULL;
 	    }
 	    if (*++p == ':') {
@@ -1469,7 +1469,7 @@ parse_cadef(char *nam, char **args)
 
 	    if (*p != ':') {
 		freecadef(all);
-		zwarnnam(nam, "invalid argument: %s", *args, 0);
+		zwarnnam(nam, "invalid argument: %s", *args);
 		return NULL;
 	    }
 	    if (*++p == ':') {
@@ -1490,7 +1490,7 @@ parse_cadef(char *nam, char **args)
 	    if (tmp && tmp->num == anum - 1) {
 		freecadef(all);
 		freecaargs(arg);
-		zwarnnam(nam, "doubled argument definition: %s", *args, 0);
+		zwarnnam(nam, "doubled argument definition: %s", *args);
 		return NULL;
 	    }
 	    arg->next = tmp;
@@ -2265,15 +2265,15 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     Castate lstate = &ca_laststate;
 
     if (incompfunc != 1) {
-	zwarnnam(nam, "can only be called from completion function", NULL, 0);
+	zwarnnam(nam, "can only be called from completion function");
 	return 1;
     }
     if (args[0][0] != '-' || !args[0][1] || args[0][2]) {
-	zwarnnam(nam, "invalid argument: %s", args[0], 0);
+	zwarnnam(nam, "invalid argument: %s", args[0]);
 	return 1;
     }
     if (args[0][1] != 'i' && args[0][1] != 'I' && !ca_parsed) {
-	zwarnnam(nam, "no parsed state", NULL, 0);
+	zwarnnam(nam, "no parsed state");
 	return 1;
     }
     switch (args[0][1]) {
@@ -2286,15 +2286,15 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     case 'a': min = 0; max =  0; break;
     case 'W': min = 2; max =  2; break;
     default:
-	zwarnnam(nam, "invalid option: %s", args[0], 0);
+	zwarnnam(nam, "invalid option: %s", args[0]);
 	return 1;
     }
     n = arrlen(args) - 1;
     if (n < min) {
-	zwarnnam(nam, "not enough arguments", NULL, 0);
+	zwarnnam(nam, "not enough arguments");
 	return 1;
     } else if (max >= 0 && n > max) {
-	zwarnnam(nam, "too many arguments", NULL, 0);
+	zwarnnam(nam, "too many arguments");
 	return 1;
     }
     switch (args[0][1]) {
@@ -2678,7 +2678,7 @@ parse_cvdef(char *nam, char **args)
         }
     }
     if (!args[0] || !args[1]) {
-	zwarnnam(nam, "not enough arguments", NULL, 0);
+	zwarnnam(nam, "not enough arguments");
 	return NULL;
     }
     descr = *args++;
@@ -2724,7 +2724,7 @@ parse_cvdef(char *nam, char **args)
 	    }
 	    if (*p != ')') {
 		freecvdef(ret);
-		zwarnnam(nam, "invalid argument: %s", *args, 0);
+		zwarnnam(nam, "invalid argument: %s", *args);
 		return NULL;
 	    }
 	    xor = (char **) zalloc((xnum + 2) * sizeof(char *));
@@ -2748,7 +2748,7 @@ parse_cvdef(char *nam, char **args)
 
 	if (hassep && !sep && name + bs + 1 < p) {
 	    freecvdef(ret);
-	    zwarnnam(nam, "no multi-letter values with empty separator allowed", NULL, 0);
+	    zwarnnam(nam, "no multi-letter values with empty separator allowed");
 	    return NULL;
 	}
 	/* Optional description? */
@@ -2761,7 +2761,7 @@ parse_cvdef(char *nam, char **args)
 
 	    if (!*p) {
 		freecvdef(ret);
-		zwarnnam(nam, "invalid value definition: %s", *args, 0);
+		zwarnnam(nam, "invalid value definition: %s", *args);
 		return NULL;
 	    }
 	    *p++ = '\0';
@@ -2772,7 +2772,7 @@ parse_cvdef(char *nam, char **args)
 	}
 	if (c && c != ':') {
 	    freecvdef(ret);
-	    zwarnnam(nam, "invalid value definition: %s", *args, 0);
+	    zwarnnam(nam, "invalid value definition: %s", *args);
 	    return NULL;
 	}
 	if (!multi) {
@@ -2787,7 +2787,7 @@ parse_cvdef(char *nam, char **args)
 	if (c == ':') {
 	    if (hassep && !sep) {
 		freecvdef(ret);
-		zwarnnam(nam, "no value with argument with empty separator allowed", NULL, 0);
+		zwarnnam(nam, "no value with argument with empty separator allowed");
 		return NULL;
 	    }
 	    if (*++p == ':') {
@@ -3142,15 +3142,15 @@ bin_compvalues(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     int min, max, n;
 
     if (incompfunc != 1) {
-	zwarnnam(nam, "can only be called from completion function", NULL, 0);
+	zwarnnam(nam, "can only be called from completion function");
 	return 1;
     }
     if (args[0][0] != '-' || !args[0][1] || args[0][2]) {
-	zwarnnam(nam, "invalid argument: %s", args[0], 0);
+	zwarnnam(nam, "invalid argument: %s", args[0]);
 	return 1;
     }
     if (args[0][1] != 'i' && !cv_parsed) {
-	zwarnnam(nam, "no parsed state", NULL, 0);
+	zwarnnam(nam, "no parsed state");
 	return 1;
     }
     switch (args[0][1]) {
@@ -3164,15 +3164,15 @@ bin_compvalues(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     case 'L': min = 3; max =  4; break;
     case 'v': min = 1; max =  1; break;
     default:
-	zwarnnam(nam, "invalid option: %s", args[0], 0);
+	zwarnnam(nam, "invalid option: %s", args[0]);
 	return 1;
     }
     n = arrlen(args) - 1;
     if (n < min) {
-	zwarnnam(nam, "not enough arguments", NULL, 0);
+	zwarnnam(nam, "not enough arguments");
 	return 1;
     } else if (max >= 0 && n > max) {
-	zwarnnam(nam, "too many arguments", NULL, 0);
+	zwarnnam(nam, "too many arguments");
 	return 1;
     }
     switch (args[0][1]) {
@@ -3357,7 +3357,7 @@ bin_compquote(char *nam, char **args, Options ops, UNUSED(int func))
     Value v;
 
     if (incompfunc != 1) {
-	zwarnnam(nam, "can only be called from completion function", NULL, 0);
+	zwarnnam(nam, "can only be called from completion function");
 	return 1;
     }
     /* Anything to do? */
@@ -3391,10 +3391,10 @@ bin_compquote(char *nam, char **args, Options ops, UNUSED(int func))
 		}
 		break;
 	    default:
-		zwarnnam(nam, "invalid parameter type: %s", args[-1], 0);
+		zwarnnam(nam, "invalid parameter type: %s", args[-1]);
 	    }
 	} else
-	    zwarnnam(nam, "unknown parameter: %s", args[-1], 0);
+	    zwarnnam(nam, "unknown parameter: %s", args[-1]);
 	unqueue_signals();
     }
     return 0;
@@ -3506,21 +3506,21 @@ bin_comptags(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     int min, max, n, level;
 
     if (incompfunc != 1) {
-	zwarnnam(nam, "can only be called from completion function", NULL, 0);
+	zwarnnam(nam, "can only be called from completion function");
 	return 1;
     }
     if (args[0][0] != '-' || !args[0][1] ||
 	(args[0][2] && (args[0][2] != '-' || args[0][3]))) {
-	zwarnnam(nam, "invalid argument: %s", args[0], 0);
+	zwarnnam(nam, "invalid argument: %s", args[0]);
 	return 1;
     }
     level = locallevel - (args[0][2] ? 1 : 0);
     if (level >= MAX_TAGS) {
-	zwarnnam(nam, "nesting level too deep", NULL, 0);
+	zwarnnam(nam, "nesting level too deep");
 	return 1;
     }
     if (args[0][1] != 'i' && args[0][1] != 'I' && !comptags[level]) {
-	zwarnnam(nam, "no tags registered", NULL, 0);
+	zwarnnam(nam, "no tags registered");
 	return 1;
     }
     switch (args[0][1]) {
@@ -3532,15 +3532,15 @@ bin_comptags(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     case 'S': min = 1; max =  1; break;
     case 'A': min = 2; max =  3; break;
     default:
-	zwarnnam(nam, "invalid option: %s", args[0], 0);
+	zwarnnam(nam, "invalid option: %s", args[0]);
 	return 1;
     }
     n = arrlen(args) - 1;
     if (n < min) {
-	zwarnnam(nam, "not enough arguments", NULL, 0);
+	zwarnnam(nam, "not enough arguments");
 	return 1;
     } else if (max >= 0 && n > max) {
-	zwarnnam(nam, "too many arguments", NULL, 0);
+	zwarnnam(nam, "too many arguments");
 	return 1;
     }
     switch (args[0][1]) {
@@ -3634,11 +3634,11 @@ static int
 bin_comptry(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 {
     if (incompfunc != 1) {
-	zwarnnam(nam, "can only be called from completion function", NULL, 0);
+	zwarnnam(nam, "can only be called from completion function");
 	return 1;
     }
     if (!lasttaglevel || !comptags[lasttaglevel]) {
-	zwarnnam(nam, "no tags registered", NULL, 0);
+	zwarnnam(nam, "no tags registered");
 	return 1;
     }
     if (*args) {
@@ -4326,18 +4326,18 @@ static int
 bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 {
     if (incompfunc != 1) {
-	zwarnnam(nam, "can only be called from completion function", NULL, 0);
+	zwarnnam(nam, "can only be called from completion function");
 	return 1;
     }
     if (**args != '-') {
-	zwarnnam(nam, "missing option: %s", *args, 0);
+	zwarnnam(nam, "missing option: %s", *args);
 	return 1;
     }
     switch (args[0][1]) {
     case 'p':
     case 'P':
 	if (args[0][2] && (args[0][2] != '-' || args[0][3])) {
-	    zwarnnam(nam, "invalid option: %s", *args, 0);
+	    zwarnnam(nam, "invalid option: %s", *args);
 	    return 1;
 	} else {
 	    char **tmp;
@@ -4345,12 +4345,12 @@ bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 
 	    if (!args[1] || !args[2] || !args[3] || !args[4] || !args[5] ||
 		!args[6] || (args[0][1] == 'p' && !args[7])) {
-		zwarnnam(nam, "too few arguments", NULL, 0);
+		zwarnnam(nam, "too few arguments");
 		return 1;
 	    }
 	    queue_signals();
 	    if (!(tmp = getaparam(args[1]))) {
-		zwarnnam(nam, "unknown parameter: %s", args[1], 0);
+		zwarnnam(nam, "unknown parameter: %s", args[1]);
 		return 0;
 	    }
 	    for (l = newlinklist(); *tmp; tmp++)
@@ -4364,18 +4364,18 @@ bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	}
     case 'i':
 	if (args[0][2]) {
-	    zwarnnam(nam, "invalid option: %s", *args, 0);
+	    zwarnnam(nam, "invalid option: %s", *args);
 	    return 1;
 	} else {
 	    char **tmp;
 	    LinkList l;
 
 	    if (!args[1] || !args[2] || !args[3] || !args[4]) {
-		zwarnnam(nam, "too few arguments", NULL, 0);
+		zwarnnam(nam, "too few arguments");
 		return 1;
 	    }
 	    if (args[5]) {
-		zwarnnam(nam, "too many arguments", NULL, 0);
+		zwarnnam(nam, "too many arguments");
 		return 1;
 	    }
 	    queue_signals();
@@ -4386,7 +4386,7 @@ bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		    addlinknode(l, *tmp);
 	    if (!(tmp = getaparam(args[1]))) {
 		unqueue_signals();
-		zwarnnam(nam, "unknown parameter: %s", args[1], 0);
+		zwarnnam(nam, "unknown parameter: %s", args[1]);
 		return 0;
 	    }
 	    cf_ignore(tmp, l, args[3], args[4]);
@@ -4401,17 +4401,17 @@ bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	    int ret = 0;
 
 	    if (!args[1] || !args[2]) {
-		zwarnnam(nam, "too few arguments", NULL, 0);
+		zwarnnam(nam, "too few arguments");
 		return 1;
 	    }
 	    if (args[3]) {
-		zwarnnam(nam, "too many arguments", NULL, 0);
+		zwarnnam(nam, "too many arguments");
 		return 1;
 	    }
 	    queue_signals();
 	    if (!(tmp = getaparam(args[1]))) {
 		unqueue_signals();
-		zwarnnam(nam, "unknown parameter: %s", args[1], 0);
+		zwarnnam(nam, "unknown parameter: %s", args[1]);
 		return 0;
 	    }
 	    if ((l = cf_remove_other(tmp, args[2], &ret)))
@@ -4420,7 +4420,7 @@ bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	    return ret;
 	}
     }
-    zwarnnam(nam, "invalid option: %s", *args, 0);
+    zwarnnam(nam, "invalid option: %s", *args);
     return 1;
 }
 
@@ -4431,7 +4431,7 @@ bin_compgroups(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     char *n;
 
     if (incompfunc != 1) {
-	zwarnnam(nam, "can only be called from completion function", NULL, 0);
+	zwarnnam(nam, "can only be called from completion function");
 	return 1;
     }
     SWITCHHEAPS(oldheap, compheap) {
diff --git a/Src/Zle/deltochar.c b/Src/Zle/deltochar.c
index 66b4aeccd..e7bfabfd3 100644
--- a/Src/Zle/deltochar.c
+++ b/Src/Zle/deltochar.c
@@ -94,8 +94,7 @@ boot_(Module m)
 	    return 0;
 	deletezlefunction(w_deletetochar);
     }
-    zwarnnam(m->nam, "deltochar: name clash when adding ZLE functions",
-	     NULL, 0);
+    zwarnnam(m->nam, "deltochar: name clash when adding ZLE functions");
     return -1;
 }
 
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index eb47ed7ce..5b6b7f05b 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -659,18 +659,17 @@ bin_bindkey(char *name, char **argv, Options ops, UNUSED(int func))
     if(op->o)
 	for(opp = op; (++opp)->o; )
 	    if(OPT_ISSET(ops,STOUC(opp->o))) {
-		zwarnnam(name, "incompatible operation selection options",
-		    NULL, 0);
+		zwarnnam(name, "incompatible operation selection options");
 		return 1;
 	    }
     n = OPT_ISSET(ops,'e') + OPT_ISSET(ops,'v') + 
 	OPT_ISSET(ops,'a') + OPT_ISSET(ops,'M');
     if(!op->selp && n) {
-	zwarnnam(name, "keymap cannot be selected with -%c", NULL, op->o);
+	zwarnnam(name, "keymap cannot be selected with -%c", op->o);
 	return 1;
     }
     if(n > 1) {
-	zwarnnam(name, "incompatible keymap selection options", NULL, 0);
+	zwarnnam(name, "incompatible keymap selection options");
 	return 1;
     }
 
@@ -688,7 +687,7 @@ bin_bindkey(char *name, char **argv, Options ops, UNUSED(int func))
 	    kmname = "main";
 	km = openkeymap(kmname);
 	if(!km) {
-	    zwarnnam(name, "no such keymap `%s'", kmname, 0);
+	    zwarnnam(name, "no such keymap `%s'", kmname);
 	    return 1;
 	}
 	if(OPT_ISSET(ops,'e') || OPT_ISSET(ops,'v'))
@@ -708,10 +707,10 @@ bin_bindkey(char *name, char **argv, Options ops, UNUSED(int func))
     /* check number of arguments */
     for(n = 0; argv[n]; n++) ;
     if(n < op->min) {
-	zwarnnam(name, "not enough arguments for -%c", NULL, op->o);
+	zwarnnam(name, "not enough arguments for -%c", op->o);
 	return 1;
     } else if(op->max != -1 && n > op->max) {
-	zwarnnam(name, "too many arguments for -%c", NULL, op->o);
+	zwarnnam(name, "too many arguments for -%c", op->o);
 	return 1;
     }
 
@@ -767,9 +766,9 @@ bin_bindkey_del(char *name, UNUSED(char *kmname), UNUSED(Keymap km), char **argv
     do {
 	int r = unlinkkeymap(*argv, 0);
 	if(r == 1)
-	    zwarnnam(name, "keymap name `%s' is protected", *argv, 0);
+	    zwarnnam(name, "keymap name `%s' is protected", *argv);
 	else if(r == 2)
-	    zwarnnam(name, "no such keymap `%s'", *argv, 0);
+	    zwarnnam(name, "no such keymap `%s'", *argv);
 	ret |= !!r;
     } while(*++argv);
     return ret;
@@ -783,10 +782,10 @@ bin_bindkey_link(char *name, UNUSED(char *kmname), Keymap km, char **argv, UNUSE
 {
     km = openkeymap(argv[0]);
     if(!km) {
-	zwarnnam(name, "no such keymap `%s'", argv[0], 0);
+	zwarnnam(name, "no such keymap `%s'", argv[0]);
 	return 1;
     } else if(linkkeymap(km, argv[1], 0)) {
-	zwarnnam(name, "keymap name `%s' is protected", argv[1], 0);
+	zwarnnam(name, "keymap name `%s' is protected", argv[1]);
 	return 1;
     }
     return 0;
@@ -801,13 +800,13 @@ bin_bindkey_new(char *name, UNUSED(char *kmname), Keymap km, char **argv, UNUSED
     KeymapName kmn = (KeymapName) keymapnamtab->getnode(keymapnamtab, argv[0]);
 
     if(kmn && (kmn -> flags & KMN_IMMORTAL)) {
-	zwarnnam(name, "keymap name `%s' is protected", argv[0], 0);
+	zwarnnam(name, "keymap name `%s' is protected", argv[0]);
 	return 1;
     }
     if(argv[1]) {
 	km = openkeymap(argv[1]);
 	if(!km) {
-	    zwarnnam(name, "no such keymap `%s'", argv[0], 0);
+	    zwarnnam(name, "no such keymap `%s'", argv[0]);
 	    return 1;
 	}
     } else
@@ -831,12 +830,11 @@ bin_bindkey_meta(char *name, char *kmname, Keymap km, UNUSED(char **argv), UNUSE
     Thingy fn;
 
     if(km->flags & KM_IMMUTABLE) {
-	zwarnnam(name, "keymap `%s' is protected", kmname, 0);
+	zwarnnam(name, "keymap `%s' is protected", kmname);
 	return 1;
     }
 #ifdef MULTIBYTE_SUPPORT
-    zwarnnam(name, "warning: `bindkey -m' disables multibyte support",
-	     NULL, 0);
+    zwarnnam(name, "warning: `bindkey -m' disables multibyte support");
 #endif
     for(i = 128; i < 256; i++)
 	if(metabind[i - 128] != z_undefinedkey) {
@@ -867,12 +865,12 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, Options ops,
 
 	for(a = argv+2; *a; a++)
 	    if(!*++a) {
-		zwarnnam(name, "even number of arguments required", NULL, 0);
+		zwarnnam(name, "even number of arguments required");
 		return 1;
 	    }
     }
     if(km->flags & KM_IMMUTABLE) {
-	zwarnnam(name, "keymap `%s' is protected", kmname, 0);
+	zwarnnam(name, "keymap `%s' is protected", kmname);
 	return 1;
     }
     if (func == 'r' && OPT_ISSET(ops,'p')) {
@@ -912,7 +910,7 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, Options ops,
 
 	    if(len < 2 || len > 2 + (bseq[1] == '-') ||
 	       (first = STOUC(bseq[0])) > (last = STOUC(bseq[len - 1]))) {
-		zwarnnam(name, "malformed key range `%s'", useq, 0);
+		zwarnnam(name, "malformed key range `%s'", useq);
 		ret = 1;
 	    } else {
 		for(; first <= last; first++) {
@@ -924,7 +922,7 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, Options ops,
 	    }
 	} else {
 	    if(bindkey(km, seq, fn, str)) {
-		zwarnnam(name, "cannot bind to an empty key sequence", NULL, 0);
+		zwarnnam(name, "cannot bind to an empty key sequence");
 		ret = 1;
 	    }
 	}
@@ -974,7 +972,7 @@ bin_bindkey_list(char *name, char *kmname, Keymap km, char **argv, Options ops,
 	/* empty prefix is equivalent to no prefix */
 	if (OPT_ISSET(ops,'p') && (!argv[0] || argv[0][0])) {
 	    if (!argv[0]) {
-		zwarnnam(name, "option -p requires a prefix string", NULL, 0);
+		zwarnnam(name, "option -p requires a prefix string");
 		return 1;
 	    }
 	    bs.prefix = getkeystring(argv[0], &bs.prefixlen, 2, NULL);
@@ -1408,7 +1406,7 @@ getkeycmd(void)
 	char *pb;
 
 	if (++hops == 20) {
-	    zerr("string inserting another one too many times", NULL, 0);
+	    zerr("string inserting another one too many times");
 	    hops = 0;
 	    return NULL;
 	}
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 6ba1fbab6..1c82611c2 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -701,7 +701,7 @@ getbyte(int keytmout, int *timeout)
 		opts[MONITOR] = ret;
 		die = 1;
 	    } else if (errno != 0) {
-		zerr("error on TTY read: %e", NULL, errno);
+		zerr("error on TTY read: %e", errno);
 		stopmsg = 1;
 		zexit(1, 0);
 	    }
@@ -1205,7 +1205,7 @@ savekeymap(char *cmdname, char *oldname, char *newname, Keymap *savemapptr)
 	}
 	return 0;
     } else {
-	zwarnnam(cmdname, "no such keymap: %s", newname, 0);
+	zwarnnam(cmdname, "no such keymap: %s", newname);
 	return 1;
     }
 }
@@ -1221,7 +1221,7 @@ restorekeymap(char *cmdname, char *oldname, char *newname, Keymap savemap)
     } else if (newname) {
 	/* urr... can this happen? */
 	zwarnnam(cmdname,
-		 "keymap %s was not defined, not restored", oldname, 0);
+		 "keymap %s was not defined, not restored", oldname);
     }
 }
 
@@ -1247,11 +1247,11 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func))
     FILE *oshout = NULL;
 
     if ((interact && unset(USEZLE)) || !strcmp(term, "emacs")) {
-	zwarnnam(name, "ZLE not enabled", NULL, 0);
+	zwarnnam(name, "ZLE not enabled");
 	return 1;
     }
     if (zleactive) {
-	zwarnnam(name, "ZLE cannot be used recursively (yet)", NULL, 0);
+	zwarnnam(name, "ZLE cannot be used recursively (yet)");
 	return 1;
     }
 
@@ -1259,7 +1259,7 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func))
     {
 	if (OPT_ISSET(ops, 'a'))
 	{
-	    zwarnnam(name, "specify only one of -a and -A", NULL, 0);
+	    zwarnnam(name, "specify only one of -a and -A");
 	    return 1;
 	}
 	type = PM_HASHED;
@@ -1272,7 +1272,7 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func))
     vicmd_keymapname = OPT_ARG_SAFE(ops,'m');
 
     if (type != PM_SCALAR && !OPT_ISSET(ops,'c')) {
-	zwarnnam(name, "-%s ignored", type == PM_ARRAY ? "a" : "A", 0);
+	zwarnnam(name, "-%s ignored", type == PM_ARRAY ? "a" : "A");
     }
 
     /* handle non-existent parameter */
@@ -1282,7 +1282,7 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func))
 		   SCANPM_WANTKEYS|SCANPM_WANTVALS|SCANPM_MATCHMANY);
     if (!v && !OPT_ISSET(ops,'c')) {
 	unqueue_signals();
-	zwarnnam(name, "no such variable: %s", args[0], 0);
+	zwarnnam(name, "no such variable: %s", args[0]);
 	return 1;
     } else if (v) {
 	if (v->isarr) {
@@ -1331,7 +1331,7 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func))
 	unqueue_signals();
     } else if (*s) {
 	unqueue_signals();
-	zwarnnam(name, "invalid parameter name: %s", args[0], 0);
+	zwarnnam(name, "invalid parameter name: %s", args[0]);
 	return 1;
     } else {
 	unqueue_signals();
@@ -1341,7 +1341,7 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func))
     if (SHTTY == -1) {
 	/* need to open /dev/tty specially */
 	if ((SHTTY = open("/dev/tty", O_RDWR|O_NOCTTY)) == -1) {
-	    zwarnnam(name, "can't access terminal", NULL, 0);
+	    zwarnnam(name, "can't access terminal");
 	    return 1;
 	}
 	oshout = shout;
@@ -1667,8 +1667,7 @@ int
 cleanup_(Module m)
 {
     if(zleactive) {
-	zerrnam(m->nam, "can't unload the zle module while zle is active",
-	    NULL, 0);
+	zerrnam(m->nam, "can't unload the zle module while zle is active");
 	return 1;
     }
     deletehookfunc("before_trap", (Hookfn) zlebeforetrap);
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index 140aeb06a..72d3314ff 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -363,18 +363,17 @@ bin_zle(char *name, char **args, Options ops, UNUSED(int func))
     if(op->o)
 	for(opp = op; (++opp)->o; )
 	    if(OPT_ISSET(ops,STOUC(opp->o))) {
-		zwarnnam(name, "incompatible operation selection options",
-		    NULL, 0);
+		zwarnnam(name, "incompatible operation selection options");
 		return 1;
 	    }
 
     /* check number of arguments */
     for(n = 0; args[n]; n++) ;
     if(n < op->min) {
-	zwarnnam(name, "not enough arguments for -%c", NULL, op->o);
+	zwarnnam(name, "not enough arguments for -%c", op->o);
 	return 1;
     } else if(op->max != -1 && n > op->max) {
-	zwarnnam(name, "too many arguments for -%c", NULL, op->o);
+	zwarnnam(name, "too many arguments for -%c", op->o);
 	return 1;
     }
 
@@ -454,7 +453,7 @@ static int
 bin_zle_mesg(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 {
     if (!zleactive) {
-	zwarnnam(name, "can only be called from widget function", NULL, 0);
+	zwarnnam(name, "can only be called from widget function");
 	return 1;
     }
     showmsg(*args);
@@ -470,7 +469,7 @@ bin_zle_unget(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
     char *b = *args, *p = b + strlen(b);
 
     if (!zleactive) {
-	zwarnnam(name, "can only be called from widget function", NULL, 0);
+	zwarnnam(name, "can only be called from widget function");
 	return 1;
     }
     while (p > b)
@@ -483,7 +482,7 @@ static int
 bin_zle_keymap(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 {
     if (!zleactive) {
-	zwarnnam(name, "can only be called from widget function", NULL, 0);
+	zwarnnam(name, "can only be called from widget function");
 	return 1;
     }
     return selectkeymap(*args, 0);
@@ -541,10 +540,10 @@ bin_zle_del(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
     do {
 	Thingy t = (Thingy) thingytab->getnode(thingytab, *args);
 	if(!t) {
-	    zwarnnam(name, "no such widget `%s'", *args, 0);
+	    zwarnnam(name, "no such widget `%s'", *args);
 	    ret = 1;
 	} else if(unbindwidget(t, 0)) {
-	    zwarnnam(name, "widget name `%s' is protected", *args, 0);
+	    zwarnnam(name, "widget name `%s' is protected", *args);
 	    ret = 1;
 	}
     } while(*++args);
@@ -558,10 +557,10 @@ bin_zle_link(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
     Thingy t = (Thingy) thingytab->getnode(thingytab, args[0]);
 
     if(!t) {
-	zwarnnam(name, "no such widget `%s'", args[0], 0);
+	zwarnnam(name, "no such widget `%s'", args[0]);
 	return 1;
     } else if(bindwidget(t->widget, rthingy(args[1]))) {
-	zwarnnam(name, "widget name `%s' is protected", args[1], 0);
+	zwarnnam(name, "widget name `%s' is protected", args[1]);
 	return 1;
     }
     return 0;
@@ -580,7 +579,7 @@ bin_zle_new(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
     if(!bindwidget(w, rthingy(args[0])))
 	return 0;
     freewidget(w);
-    zwarnnam(name, "widget name `%s' is protected", args[0], 0);
+    zwarnnam(name, "widget name `%s' is protected", args[0]);
     return 1;
 }
 
@@ -592,14 +591,14 @@ bin_zle_complete(char *name, char **args, UNUSED(Options ops), UNUSED(char func)
     Widget w, cw;
 
     if (!require_module(name, "zsh/complete", 0, 0)) {
-	zwarnnam(name, "can't load complete module", NULL, 0);
+	zwarnnam(name, "can't load complete module");
 	return 1;
     }
     t = rthingy((args[1][0] == '.') ? args[1] : dyncat(".", args[1]));
     cw = t->widget;
     unrefthingy(t);
     if (!cw || !(cw->flags & ZLE_ISCOMP)) {
-	zwarnnam(name, "invalid widget `%s'", args[1], 0);
+	zwarnnam(name, "invalid widget `%s'", args[1]);
 	return 1;
     }
     w = zalloc(sizeof(*w));
@@ -610,7 +609,7 @@ bin_zle_complete(char *name, char **args, UNUSED(Options ops), UNUSED(char func)
     w->u.comp.func = ztrdup(args[2]);
     if (bindwidget(w, rthingy(args[0]))) {
 	freewidget(w);
-	zwarnnam(name, "widget name `%s' is protected", args[0], 0);
+	zwarnnam(name, "widget name `%s' is protected", args[0]);
 	return 1;
     }
     hascompwidgets++;
@@ -648,8 +647,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 	return !zle_usable();
 
     if(!zle_usable()) {
-	zwarnnam(name, "widgets can only be called when ZLE is active",
-	    NULL, 0);
+	zwarnnam(name, "widgets can only be called when ZLE is active");
 	return 1;
     }
 
@@ -666,7 +664,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 	    case 'n':
 		num = args[0][1] ? args[0]+1 : args[1];
 		if (!num) {
-		    zwarnnam(name, "number expected after -%c", NULL, **args);
+		    zwarnnam(name, "number expected after -%c", **args);
 		    return 1;
 		}
 		if (!args[0][1])
@@ -683,7 +681,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 	    case 'K':
 		keymap_tmp = args[0][1] ? args[0]+1 : args[1];
 		if (!keymap_tmp) {
-		    zwarnnam(name, "keymap expected after -%c", NULL, **args);
+		    zwarnnam(name, "keymap expected after -%c", **args);
 		    return 1;
 		}
 		if (!args[0][1])
@@ -696,7 +694,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 		setbindk = 1;
 		break;
 	    default:
-		zwarnnam(name, "unknown option: %s", *args, 0);
+		zwarnnam(name, "unknown option: %s", *args);
 		return 1;
 	    }
 	}
@@ -741,7 +739,7 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
 	fd = (int)zstrtol(*args, &endptr, 10);
 
 	if (*endptr || fd < 0) {
-	    zwarnnam(name, "Bad file descriptor number for -F: %s", *args, 0);
+	    zwarnnam(name, "Bad file descriptor number for -F: %s", *args);
 	    return 1;
 	}
     }
@@ -749,7 +747,7 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
     if (OPT_ISSET(ops,'L') || !*args) {
 	/* Listing handlers. */
 	if (*args && args[1]) {
-	    zwarnnam(name, "too many arguments for -FL", NULL, 0);
+	    zwarnnam(name, "too many arguments for -FL");
 	    return 1;
 	}
 	for (i = 0; i < nwatch; i++) {
@@ -824,7 +822,7 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
 	    }
 	}
 	if (!found) {
-	    zwarnnam(name, "No handler installed for fd %d", NULL, fd);
+	    zwarnnam(name, "No handler installed for fd %d", fd);
 	    return 1;
 	}
     }
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index ee4bfbb7f..250804648 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -581,7 +581,7 @@ docomplete(int lst)
     int olst = lst, chl = 0, ne = noerrs, ocs, ret = 0, dat[2];
 
     if (active && !comprecursive) {
-	zwarn("completion cannot be used recursively (yet)", NULL, 0);
+	zwarn("completion cannot be used recursively (yet)");
 	return 1;
     }
     active = 1;
diff --git a/Src/builtin.c b/Src/builtin.c
index 05203d485..ff396fb47 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -250,7 +250,7 @@ execbuiltin(LinkList args, Builtin bn)
     name = (char *) ugetnode(args);
 
     if (!bn->handlerfunc) {
-	zwarnnam(name, "autoload failed", NULL, 0);
+	zwarnnam(name, "autoload failed");
 	deletebuiltin(bn->node.nam);
 	return 1;
     }
@@ -355,15 +355,14 @@ execbuiltin(LinkList args, Builtin bn)
 				    argptr = arg;
 				else {
 				    zwarnnam(name, "argument expected: -%c",
-					     NULL, execop);
+					     execop);
 				    return 1;
 				}
 			    }
 			    if (argptr) {
 				if (new_optarg(&ops)) {
 				    zwarnnam(name, 
-					     "too many option arguments",
-					     NULL, 0);
+					     "too many option arguments");
 				    return 1;
 				}
 				ops.ind[execop] |= ops.argscount << 2;
@@ -380,7 +379,7 @@ execbuiltin(LinkList args, Builtin bn)
 		if (*arg) {
 		    if(*arg == Meta)
 			*++arg ^= 32;
-		    zwarn("bad option: -%c", NULL, *arg);
+		    zwarn("bad option: -%c", *arg);
 		    return 1;
 		}
 		arg = *++argv;
@@ -418,7 +417,7 @@ execbuiltin(LinkList args, Builtin bn)
 	/* check that the argument count lies within the specified bounds */
 	if (argc < bn->minargs || (argc > bn->maxargs && bn->maxargs != -1)) {
 	    zwarnnam(name, (argc < bn->minargs)
-		     ? "not enough arguments" : "too many arguments", NULL, 0);
+		     ? "not enough arguments" : "too many arguments");
 	    return 1;
 	}
 
@@ -499,7 +498,7 @@ bin_enable(char *name, char **argv, Options ops, int func)
 	    }
 	    else {
 		untokenize(*argv);
-		zwarnnam(name, "bad pattern : %s", *argv, 0);
+		zwarnnam(name, "bad pattern : %s", *argv);
 		returnval = 1;
 	    }
 	}
@@ -515,7 +514,7 @@ bin_enable(char *name, char **argv, Options ops, int func)
 	if ((hn = ht->getnode2(ht, *argv))) {
 	    scanfunc(hn, 0);
 	} else {
-	    zwarnnam(name, "no such hash table element: %s", *argv, 0);
+	    zwarnnam(name, "no such hash table element: %s", *argv);
 	    returnval = 1;
 	}
     }
@@ -568,9 +567,9 @@ bin_set(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		    return 0;
 		}
 		if(!(optno = optlookup(*args)))
-		    zwarnnam(nam, "no such option: %s", *args, 0);
+		    zwarnnam(nam, "no such option: %s", *args);
 		else if(dosetopt(optno, action, 0))
-		    zwarnnam(nam, "can't change option: %s", *args, 0);
+		    zwarnnam(nam, "can't change option: %s", *args);
 		break;
 	    } else if(**args == 'A') {
 		if(!*++*args)
@@ -589,9 +588,9 @@ bin_set(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		sort = action ? 1 : -1;
 	    else {
 	    	if (!(optno = optlookupc(**args)))
-		    zwarnnam(nam, "bad option: -%c", NULL, **args);
+		    zwarnnam(nam, "bad option: -%c", **args);
 		else if(dosetopt(optno, action, 0))
-		    zwarnnam(nam, "can't change option: -%c", NULL, **args);
+		    zwarnnam(nam, "can't change option: -%c", **args);
 	    }
 	}
 	args++;
@@ -774,7 +773,7 @@ bin_cd(char *nam, char **argv, Options ops, int func)
     struct stat st1, st2;
 
     if (isset(RESTRICTED)) {
-	zwarnnam(nam, "restricted", NULL, 0);
+	zwarnnam(nam, "restricted");
 	return 1;
     }
     doprintdir = (doprintdir == -1);
@@ -821,7 +820,7 @@ cd_get_dest(char *nam, char **argv, int hard, int func)
 
     if (!argv[0]) {
 	if (func == BIN_POPD && !nextnode(firstnode(dirstack))) {
-	    zwarnnam(nam, "directory stack empty", NULL, 0);
+	    zwarnnam(nam, "directory stack empty");
 	    return NULL;
 	}
 	if (func == BIN_PUSHD && unset(PUSHDTOHOME))
@@ -844,7 +843,7 @@ cd_get_dest(char *nam, char **argv, int hard, int func)
 		    for (dir = lastnode(dirstack); dir != (LinkNode) dirstack && dd;
 			 dd--, dir = prevnode(dir)); 
 		if (!dir || dir == (LinkNode) dirstack) {
-		    zwarnnam(nam, "no such entry in dir stack", NULL, 0);
+		    zwarnnam(nam, "no such entry in dir stack");
 		    return NULL;
 		}
 	    }
@@ -857,7 +856,7 @@ cd_get_dest(char *nam, char **argv, int hard, int func)
 	int len1, len2, len3;
 
 	if (!(u = strstr(pwd, argv[0]))) {
-	    zwarnnam(nam, "string not in pwd: %s", argv[0], 0);
+	    zwarnnam(nam, "string not in pwd: %s", argv[0]);
 	    return NULL;
 	}
 	len1 = strlen(argv[0]);
@@ -939,7 +938,7 @@ cd_do_chdir(char *cnam, char *dest, int hard)
     if (*dest == '/') {
 	if ((ret = cd_try_chdir(NULL, dest, hard)))
 	    return ret;
-	zwarnnam(cnam, "%e: %s", dest, errno);
+	zwarnnam(cnam, "%e: %s", errno, dest);
 	return NULL;
     }
 
@@ -983,7 +982,7 @@ cd_do_chdir(char *cnam, char *dest, int hard)
     /* If we got here, it means that we couldn't chdir to any of the
        multitudinous possible paths allowed by zsh.  We've run out of options!
        Add more here! */
-    zwarnnam(cnam, "%e: %s", dest, eno);
+    zwarnnam(cnam, "%e: %s", eno, dest);
     return NULL;
 }
 
@@ -1301,7 +1300,7 @@ bin_fc(char *nam, char **argv, Options ops, int func)
 
     /* fc is only permitted in interactive shells */
     if (!interact) {
-	zwarnnam(nam, "not interactive shell", NULL, 0);
+	zwarnnam(nam, "not interactive shell");
 	return 1;
     }
     if (OPT_ISSET(ops,'p')) {
@@ -1318,7 +1317,7 @@ bin_fc(char *nam, char **argv, Options ops, int func)
 		else
 		    shs = hs;
 		if (*argv) {
-		    zwarnnam("fc", "too many arguments", NULL, 0);
+		    zwarnnam("fc", "too many arguments");
 		    return 1;
 		}
 	    } else {
@@ -1337,7 +1336,7 @@ bin_fc(char *nam, char **argv, Options ops, int func)
     }
     if (OPT_ISSET(ops,'P')) {
 	if (*argv) {
-	    zwarnnam("fc", "too many arguments", NULL, 0);
+	    zwarnnam("fc", "too many arguments");
 	    return 1;
 	}
 	return !saveandpophiststack(-1, HFILE_USE_OPTIONS);
@@ -1347,7 +1346,7 @@ bin_fc(char *nam, char **argv, Options ops, int func)
     if (*argv && OPT_ISSET(ops,'m')) {
 	tokenize(*argv);
 	if (!(pprog = patcompile(*argv++, 0, NULL))) {
-	    zwarnnam(nam, "invalid match pattern", NULL, 0);
+	    zwarnnam(nam, "invalid match pattern");
 	    return 1;
 	}
     }
@@ -1376,7 +1375,7 @@ bin_fc(char *nam, char **argv, Options ops, int func)
 	Asgment a = (Asgment) zhalloc(sizeof *a);
 
 	if (!**argv) {
-	    zwarnnam(nam, "invalid replacement pattern: =%s", s, 0);
+	    zwarnnam(nam, "invalid replacement pattern: =%s", s);
 	    return 1;
 	}
 	if (!asgf)
@@ -1412,7 +1411,7 @@ bin_fc(char *nam, char **argv, Options ops, int func)
      * will be as long as the history list is one-dimensional.        */
     if (*argv) {
 	unqueue_signals();
-	zwarnnam("fc", "too many arguments", NULL, 0);
+	zwarnnam("fc", "too many arguments");
 	return 1;
     }
     /* default values of first and last, and range checking */
@@ -1448,7 +1447,7 @@ bin_fc(char *nam, char **argv, Options ops, int func)
 	if ((tempfd = gettempfile(NULL, 1, &fil)) < 0
 	 || ((out = fdopen(tempfd, "w")) == NULL)) {
 	    unqueue_signals();
-	    zwarnnam("fc", "can't open temp file: %e", NULL, errno);
+	    zwarnnam("fc", "can't open temp file: %e", errno);
 	} else {
 	    ops->ind['n'] = 1;	/* No line numbers here. */
 	    if (!fclist(out, ops, first, last, asgf, pprog)) {
@@ -1468,7 +1467,7 @@ bin_fc(char *nam, char **argv, Options ops, int func)
 		unqueue_signals();
 		if (fcedit(editor, fil)) {
 		    if (stuff(fil))
-			zwarnnam("fc", "%e: %s", s, errno);
+			zwarnnam("fc", "%e: %s", errno, s);
 		    else {
 			loop(0,1);
 			retval = lastval;
@@ -1508,7 +1507,7 @@ fcgetcomm(char *s)
     /* not a number, so search by string */
     cmd = hcomsearch(s);
     if (cmd == -1)
-	zwarnnam("fc", "event not found: %s", s, 0);
+	zwarnnam("fc", "event not found: %s", s);
     return cmd;
 }
 
@@ -1582,9 +1581,9 @@ fclist(FILE *f, Options ops, zlong first, zlong last,
 	if (first == last) {
 	    char buf[DIGBUFSIZE];
 	    convbase(buf, first, 10);
-	    zwarnnam("fc", "no such event: %s", buf, 0);
+	    zwarnnam("fc", "no such event: %s", buf);
 	} else
-	    zwarnnam("fc", "no events in that range", NULL, 0);
+	    zwarnnam("fc", "no events in that range");
 	return 1;
     }
 
@@ -1652,7 +1651,7 @@ fclist(FILE *f, Options ops, zlong first, zlong last,
     if (f != stdout)
 	fclose(f);
     if (!fclistdone) {
-	zwarnnam("fc", "no substitutions performed", NULL, 0);
+	zwarnnam("fc", "no substitutions performed");
 	return 1;
     }
     return 0;
@@ -1695,7 +1694,7 @@ getasg(char *s)
 
     /* check if name is empty */
     if (*s == '=') {
-	zerr("bad assignment", NULL, 0);
+	zerr("bad assignment");
 	return NULL;
     }
     asg.name = s;
@@ -1743,9 +1742,9 @@ typeset_setbase(const char *name, Param pm, Options ops, int on, int always)
 	pm->base = (int)zstrtol(arg, &eptr, 10);
 	if (*eptr) {
 	    if (on & PM_INTEGER)
-		zwarnnam(name, "bad base value: %s", arg, 0);
+		zwarnnam(name, "bad base value: %s", arg);
 	    else
-		zwarnnam(name, "bad precision value: %s", arg, 0);
+		zwarnnam(name, "bad precision value: %s", arg);
 	    return 1;
 	}
     } else if (always)
@@ -1772,7 +1771,7 @@ typeset_setwidth(const char * name, Param pm, Options ops, int on, int always)
 	char *eptr;
 	pm->width = (int)zstrtol(arg, &eptr, 10);
 	if (*eptr) {
-	    zwarnnam(name, "bad width value: %s", arg, 0);
+	    zwarnnam(name, "bad width value: %s", arg);
 	    return 1;
 	}
     } else if (always)
@@ -1886,12 +1885,12 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
 	    if (err)
 	    {
 		zerrnam(cname, "%s: can't change type of a special parameter",
-			pname, 0);
+			pname);
 		return NULL;
 	    }
 	} else if (pm->node.flags & PM_AUTOLOAD) {
 	    zerrnam(cname, "%s: can't change type of autoloaded parameter",
-		    pname, 0);
+		    pname);
 	    return NULL;
 	}
     }
@@ -1917,7 +1916,7 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
 	    return pm;
 	}
 	if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	    zerrnam(cname, "%s: restricted", pname, 0);
+	    zerrnam(cname, "%s: restricted", pname);
 	    return pm;
 	}
 	if ((on & PM_UNIQUE) && !(pm->node.flags & PM_READONLY & ~off)) {
@@ -1959,7 +1958,7 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
 	    if (value && !(pm = setsparam(pname, ztrdup(value))))
 		return NULL;
 	} else if (value) {
-	    zwarnnam(cname, "can't assign new value for array %s", pname, 0);
+	    zwarnnam(cname, "can't assign new value for array %s", pname);
 	    return NULL;
 	}
 	pm->node.flags |= (on & PM_READONLY);
@@ -1998,7 +1997,7 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
     if (newspecial != NS_NONE) {
 	Param tpm, pm2;
 	if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	    zerrnam(cname, "%s: restricted", pname, 0);
+	    zerrnam(cname, "%s: restricted", pname);
 	    return pm;
 	}
 	/*
@@ -2062,7 +2061,7 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
     } else if ((subscript = strchr(pname, '['))) {
 	if (on & PM_READONLY) {
 	    zerrnam(cname,
-		    "%s: can't create readonly array elements", pname, 0);
+		    "%s: can't create readonly array elements", pname);
 	    return NULL;
 	} else if (on & PM_LOCAL) {
 	    *subscript = 0;
@@ -2072,7 +2071,7 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
 	    *subscript = '[';
 	    if (!pm || pm->level != locallevel) {
 		zerrnam(cname,
-			"%s: can't create local array elements", pname, 0);
+			"%s: can't create local array elements", pname);
 		return NULL;
 	    }
 	}
@@ -2090,7 +2089,7 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
 	    on = pm->node.flags;
 	} else {
 	    zerrnam(cname,
-		    "%s: array elements must be scalar", pname, 0);
+		    "%s: array elements must be scalar", pname);
 	    return NULL;
 	}
     } else if (isident(pname) && !idigit(*pname)) {
@@ -2110,9 +2109,9 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
 	}
     } else {
 	if (isident(pname))
-	    zerrnam(cname, "not valid in this context: %s", pname, 0);
+	    zerrnam(cname, "not valid in this context: %s", pname);
 	else
-	    zerrnam(cname, "not an identifier: %s", pname, 0);
+	    zerrnam(cname, "not an identifier: %s", pname);
 	return NULL;
     }
 
@@ -2172,7 +2171,7 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
     }
     pm->node.flags |= (on & PM_READONLY);
     if (value && (pm->node.flags & (PM_ARRAY|PM_HASHED))) {
-	zerrnam(cname, "%s: can't assign initial value for array", pname, 0);
+	zerrnam(cname, "%s: can't assign initial value for array", pname);
 	/* the only safe thing to do here seems to be unset the param */
 	unsetparam_pm(pm, 0, 1);
 	return NULL;
@@ -2273,13 +2272,13 @@ bin_typeset(char *name, char **argv, Options ops, int func)
 	int joinchar;
 
 	if (OPT_ISSET(ops,'m')) {
-	    zwarnnam(name, "incompatible options for -T", NULL, 0);
+	    zwarnnam(name, "incompatible options for -T");
 	    unqueue_signals();
 	    return 1;
 	}
 	on &= ~off;
 	if (!argv[1] || (argv[2] && argv[3])) {
-	    zwarnnam(name, "-T requires names of scalar and array", NULL, 0);
+	    zwarnnam(name, "-T requires names of scalar and array");
 	    unqueue_signals();
 	    return 1;
 	}
@@ -2308,12 +2307,12 @@ bin_typeset(char *name, char **argv, Options ops, int func)
 	}
 	if (!strcmp(asg0.name, asg->name)) {
 	    unqueue_signals();
-	    zerrnam(name, "can't tie a variable to itself", NULL, 0);
+	    zerrnam(name, "can't tie a variable to itself");
 	    return 1;
 	}
 	if (strchr(asg0.name, '[') || strchr(asg->name, '[')) {
 	    unqueue_signals();
-	    zerrnam(name, "can't tie array elements", NULL, 0);
+	    zerrnam(name, "can't tie array elements");
 	    return 1;
 	}
 	/*
@@ -2378,7 +2377,7 @@ bin_typeset(char *name, char **argv, Options ops, int func)
 	return 0;
     }
     if (off & PM_TIED) {
-	zerrnam(name, "use unset to remove tied variables", NULL, 0);
+	zerrnam(name, "use unset to remove tied variables");
 	return 1;
     }
 
@@ -2398,7 +2397,7 @@ bin_typeset(char *name, char **argv, Options ops, int func)
 	    tokenize(asg->name);   /* expand argument */
 	    if (!(pprog = patcompile(asg->name, 0, NULL))) {
 		untokenize(asg->name);
-		zwarnnam(name, "bad pattern : %s", argv[-1], 0);
+		zwarnnam(name, "bad pattern : %s", argv[-1]);
 		returnval = 1;
 		continue;
 	    }
@@ -2552,7 +2551,7 @@ bin_functions(char *name, char **argv, Options ops, int func)
 
     if ((off & PM_UNDEFINED) || (OPT_ISSET(ops,'k') && OPT_ISSET(ops,'z')) ||
 	(OPT_MINUS(ops,'X') && (OPT_ISSET(ops,'m') || *argv || !scriptname))) {
-	zwarnnam(name, "invalid option(s)", NULL, 0);
+	zwarnnam(name, "invalid option(s)");
 	return 1;
     }
 
@@ -2566,7 +2565,7 @@ bin_functions(char *name, char **argv, Options ops, int func)
 	 */
 	if (on || off || pflags || OPT_ISSET(ops,'X') || OPT_ISSET(ops,'u')
 	    || OPT_ISSET(ops,'U') || OPT_ISSET(ops,'w')) {
-	    zwarnnam(name, "invalid option(s)", NULL, 0);
+	    zwarnnam(name, "invalid option(s)");
 	    return 1;
 	}
 	if (!*argv) {
@@ -2601,7 +2600,7 @@ bin_functions(char *name, char **argv, Options ops, int func)
 		    unqueue_signals();
 		} else {
 		    untokenize(*argv);
-		    zwarnnam(name, "bad pattern : %s", *argv, 0);
+		    zwarnnam(name, "bad pattern : %s", *argv);
 		    returnval = 1;
 		}
 	    }
@@ -2613,7 +2612,7 @@ bin_functions(char *name, char **argv, Options ops, int func)
 		    if (!strcmp(p->name, *argv)) {
 			if (!(p->flags & MFF_USERFUNC)) {
 			    zwarnnam(name, "+M %s: is a library function",
-				     *argv, 0);
+				     *argv);
 			    returnval = 1;
 			    break;
 			}
@@ -2634,7 +2633,7 @@ bin_functions(char *name, char **argv, Options ops, int func)
 		if (!iident(*ptr))
 		    break;
 	    if (idigit(*funcname) || funcname == ptr || *ptr) {
-		zwarnnam(name, "-M %s: bad math function name", funcname, 0);
+		zwarnnam(name, "-M %s: bad math function name", funcname);
 		return 1;
 	    }
 
@@ -2642,7 +2641,7 @@ bin_functions(char *name, char **argv, Options ops, int func)
 		minargs = (int)zstrtol(*argv, &ptr, 0);
 		if (minargs < 0 || *ptr) {
 		    zwarnnam(name, "-M: invalid min number of arguments: %s",
-			     *argv, 0);
+			     *argv);
 		    return 1;
 		}
 		maxargs = minargs;
@@ -2655,7 +2654,7 @@ bin_functions(char *name, char **argv, Options ops, int func)
 		    *ptr) {
 		    zwarnnam(name,
 			     "-M: invalid max number of arguments: %s",
-			     *argv, 0);
+			     *argv);
 		    return 1;
 		}
 		argv++;
@@ -2663,7 +2662,7 @@ bin_functions(char *name, char **argv, Options ops, int func)
 	    if (*argv)
 		modname = *argv++;
 	    if (*argv) {
-		zwarnnam(name, "-M: too many arguments", NULL, 0);
+		zwarnnam(name, "-M: too many arguments");
 		return 1;
 	    }
 
@@ -2678,7 +2677,7 @@ bin_functions(char *name, char **argv, Options ops, int func)
 	    for (q = mathfuncs; q; q = q->next) {
 		if (!strcmp(q->name, funcname)) {
 		    zwarnnam(name, "-M %s: function already exists",
-			     funcname, 0);
+			     funcname);
 		    zsfree(p->name);
 		    zsfree(p->module);
 		    zfree(p, sizeof(struct mathfunc));
@@ -2752,7 +2751,7 @@ bin_functions(char *name, char **argv, Options ops, int func)
 		unqueue_signals();
 	    } else {
 		untokenize(*argv);
-		zwarnnam(name, "bad pattern : %s", *argv, 0);
+		zwarnnam(name, "bad pattern : %s", *argv);
 		returnval = 1;
 	    }
 	}
@@ -2878,7 +2877,7 @@ bin_unset(char *name, char **argv, Options ops, int func)
 		unqueue_signals();
 	    } else {
 		untokenize(s);
-		zwarnnam(name, "bad pattern : %s", s, 0);
+		zwarnnam(name, "bad pattern : %s", s);
 		returnval = 1;
 	    }
 	}
@@ -2895,7 +2894,7 @@ bin_unset(char *name, char **argv, Options ops, int func)
 	char *sse = ss;
 	if (ss) {
 	    if (skipparens('[', ']', &sse) || *sse) {
-		zerrnam(name, "%s: invalid parameter name", s, 0);
+		zerrnam(name, "%s: invalid parameter name", s);
 		returnval = 1;
 		continue;
 	    }
@@ -2911,7 +2910,7 @@ bin_unset(char *name, char **argv, Options ops, int func)
 	if (!pm)
 	    continue;
 	else if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	    zerrnam(name, "%s: restricted", pm->node.nam, 0);
+	    zerrnam(name, "%s: restricted", pm->node.nam);
 	    returnval = 1;
 	} else if (ss) {
 	    if (PM_TYPE(pm->node.flags) == PM_HASHED) {
@@ -2923,7 +2922,7 @@ bin_unset(char *name, char **argv, Options ops, int func)
 		}
 		paramtab = tht;
 	    } else {
-		zerrnam(name, "%s: invalid element for unset", s, 0);
+		zerrnam(name, "%s: invalid element for unset", s);
 		returnval = 1;
 	    }
 	} else {
@@ -2988,7 +2987,7 @@ bin_whence(char *nam, char **argv, Options ops, int func)
 	    tokenize(*argv);
 	    if (!(pprog = patcompile(*argv, PAT_STATIC, NULL))) {
 		untokenize(*argv);
-		zwarnnam(nam, "bad pattern : %s", *argv, 0);
+		zwarnnam(nam, "bad pattern : %s", *argv);
 		returnval = 1;
 		continue;
 	    }
@@ -3171,7 +3170,7 @@ bin_hash(char *name, char **argv, Options ops, UNUSED(int func))
     if (OPT_ISSET(ops,'r') || OPT_ISSET(ops,'f')) {
 	/* -f and -r can't be used with any arguments */
 	if (*argv) {
-	    zwarnnam("hash", "too many arguments", NULL, 0);
+	    zwarnnam("hash", "too many arguments");
 	    return 1;
 	}
 
@@ -3207,12 +3206,12 @@ bin_hash(char *name, char **argv, Options ops, UNUSED(int func))
 		scanmatchtable(ht, pprog, 0, 0, ht->printnode, printflags);
 	    } else {
 		untokenize(*argv);
-		zwarnnam(name, "bad pattern : %s", *argv, 0);
+		zwarnnam(name, "bad pattern : %s", *argv);
 		returnval = 1;
 	    }
 	} else if ((asg = getasg(*argv)) && asg->value) {
 	    if(isset(RESTRICTED)) {
-		zwarnnam(name, "restricted: %s", asg->value, 0);
+		zwarnnam(name, "restricted: %s", asg->value);
 		returnval = 1;
 	    } else {
 		/* The argument is of the form foo=bar, *
@@ -3235,12 +3234,12 @@ bin_hash(char *name, char **argv, Options ops, UNUSED(int func))
 	     * work out what it ought to be.          */
 	    if(OPT_ISSET(ops,'d')) {
 		if(!getnameddir(asg->name)) {
-		    zwarnnam(name, "no such directory name: %s", asg->name, 0);
+		    zwarnnam(name, "no such directory name: %s", asg->name);
 		    returnval = 1;
 		}
 	    } else {
 		if (!hashcmd(asg->name, path)) {
-		    zwarnnam(name, "no such command: %s", asg->name, 0);
+		    zwarnnam(name, "no such command: %s", asg->name);
 		    returnval = 1;
 		}
 	    }
@@ -3300,7 +3299,7 @@ bin_unhash(char *name, char **argv, Options ops, UNUSED(int func))
 		unqueue_signals();
 	    } else {
 		untokenize(*argv);
-		zwarnnam(name, "bad pattern : %s", *argv, 0);
+		zwarnnam(name, "bad pattern : %s", *argv);
 		returnval = 1;
 	    }
 	}
@@ -3316,7 +3315,7 @@ bin_unhash(char *name, char **argv, Options ops, UNUSED(int func))
 	if ((hn = ht->removenode(ht, *argv))) {
 	    ht->freenode(hn);
 	} else {
-	    zwarnnam(name, "no such hash table element: %s", *argv, 0);
+	    zwarnnam(name, "no such hash table element: %s", *argv);
 	    returnval = 1;
 	}
     }
@@ -3346,7 +3345,7 @@ bin_alias(char *name, char **argv, Options ops, UNUSED(int func))
 	OPT_ISSET(ops, 's');
     if (type_opts) {
 	if (type_opts > 1) {
-	    zwarnnam(name, "illegal combination of options", NULL, 0);
+	    zwarnnam(name, "illegal combination of options");
 	    return 1;
 	}
 	if (OPT_ISSET(ops,'g'))
@@ -3394,7 +3393,7 @@ bin_alias(char *name, char **argv, Options ops, UNUSED(int func))
 		unqueue_signals();
 	    } else {
 		untokenize(*argv);
-		zwarnnam(name, "bad pattern : %s", *argv, 0);
+		zwarnnam(name, "bad pattern : %s", *argv);
 		returnval = 1;
 	    }
 	}
@@ -3482,7 +3481,7 @@ bin_print(char *name, char **args, Options ops, int func)
     
     if (func == BIN_PRINTF) {
         if (!strcmp(*args, "--") && !*++args) {
-            zwarnnam(name, "not enough arguments", NULL, 0);
+            zwarnnam(name, "not enough arguments");
 	    return 1;
         }
   	fmt = *args++;
@@ -3502,13 +3501,13 @@ bin_print(char *name, char **args, Options ops, int func)
 	char **t, **p;
 
 	if (!*args) {
-	    zwarnnam(name, "no pattern specified", NULL, 0);
+	    zwarnnam(name, "no pattern specified");
 	    return 1;
 	}
 	tokenize(*args);
 	if (!(pprog = patcompile(*args, PAT_STATIC, NULL))) {
 	    untokenize(*args);
-	    zwarnnam(name, "bad pattern: %s", *args, 0);
+	    zwarnnam(name, "bad pattern: %s", *args);
 	    return 1;
 	}
 	for (t = p = ++args; *p; p++)
@@ -3580,20 +3579,20 @@ bin_print(char *name, char **args, Options ops, int func)
 	    } else {
 		fd = (int)zstrtol(argptr, &eptr, 10);
 		if (*eptr) {
-		    zwarnnam(name, "number expected after -%c: %s", argptr,
-			     'u');
+		    zwarnnam(name, "number expected after -%c: %s", 'u',
+			     argptr);
 		    return 1;
 		}
 	    }
 	}
 
 	if ((fd = dup(fd)) < 0) {
-	    zwarnnam(name, "bad file number: %d", NULL, fd);
+	    zwarnnam(name, "bad file number: %d", fd);
 	    return 1;
 	}
 	if ((fout = fdopen(fd, "w")) == 0) {
 	    close(fd);
-	    zwarnnam(name, "bad mode on fd %d", NULL, fd);
+	    zwarnnam(name, "bad mode on fd %d", fd);
 	    return 1;
 	}
     }
@@ -3626,11 +3625,11 @@ bin_print(char *name, char **args, Options ops, int func)
 	    char *eptr, *argptr = OPT_ARG(ops,'C');
 	    nc = (int)zstrtol(argptr, &eptr, 10);
 	    if (*eptr) {
-		zwarnnam(name, "number expected after -%c: %s", argptr, 'C');
+		zwarnnam(name, "number expected after -%c: %s", 'C', argptr);
 		return 1;
 	    }
 	    if (nc <= 0) {
-		zwarnnam(name, "invalid number of columns: %s", argptr, 0);
+		zwarnnam(name, "invalid number of columns: %s", argptr);
 		return 1;
 	    }
 	    /*
@@ -3716,7 +3715,7 @@ bin_print(char *name, char **args, Options ops, int func)
 	/* Testing EBADF special-cases >&- redirections */
 	if ((fout != stdout) ? (fclose(fout) != 0) :
 	    (fflush(fout) != 0 && errno != EBADF)) {
-            zwarnnam(name, "write error: %e", NULL, errno);
+            zwarnnam(name, "write error: %e", errno);
             ret = 1;
 	}
 	return ret;
@@ -3770,7 +3769,7 @@ bin_print(char *name, char **args, Options ops, int func)
 	/* Testing EBADF special-cases >&- redirections */
 	if ((fout != stdout) ? (fclose(fout) != 0) :
 	    (fflush(fout) != 0 && errno != EBADF)) {
-            zwarnnam(name, "write error: %e", NULL, errno);
+            zwarnnam(name, "write error: %e", errno);
             ret = 1;
 	}
 	return ret;
@@ -3779,13 +3778,13 @@ bin_print(char *name, char **args, Options ops, int func)
     if (OPT_ISSET(ops,'z') || OPT_ISSET(ops,'s')) {
 #ifdef HAVE_OPEN_MEMSTREAM
     	if ((fout = open_memstream(&buf, &mcount)) == NULL)
-	    zwarnnam(name, "open_memstream failed", NULL, 0);
+	    zwarnnam(name, "open_memstream failed");
 #else
 	int tempfd;
 	char *tmpf;
 	if ((tempfd = gettempfile(NULL, 1, &tmpf)) < 0
 	 || (fout = fdopen(tempfd, "w+")) == NULL)
-	    zwarnnam(name, "can't open temp file: %e", NULL, errno);
+	    zwarnnam(name, "can't open temp file: %e", errno);
 	unlink(tmpf);
 #endif
     } 
@@ -3826,7 +3825,7 @@ bin_print(char *name, char **args, Options ops, int func)
 		    DPUTS(narg <= 0, "specified zero or negative arg");
 		    if (narg > argc) {
 		    	zwarnnam(name, "%d: argument specifier out of range",
-				 0, narg);
+				 narg);
 			if (fout != stdout)
 			    fclose(fout);
 			return 1;
@@ -3859,7 +3858,7 @@ bin_print(char *name, char **args, Options ops, int func)
 			if (narg > argc || narg <= 0) {
 		    	    zwarnnam(name,
 				     "%d: argument specifier out of range",
-				     0, narg);
+				     narg);
 			    if (fout != stdout)
 				fclose(fout);
 			    return 1;
@@ -3888,7 +3887,7 @@ bin_print(char *name, char **args, Options ops, int func)
 			    if (narg > argc || narg <= 0) {
 		    		zwarnnam(name,
 					 "%d: argument specifier out of range",
-					 0, narg);
+					 narg);
 				if (fout != stdout)
 				    fclose(fout);
 				return 1;
@@ -3988,12 +3987,12 @@ bin_print(char *name, char **args, Options ops, int func)
 		    save = c[1];
 	            c[1] = '\0';
 		}
-		zwarnnam(name, "%s: invalid directive", start, 0);
+		zwarnnam(name, "%s: invalid directive", start);
 		if (*c) c[1] = save;
 		/* Testing EBADF special-cases >&- redirections */
 		if ((fout != stdout) ? (fclose(fout) != 0) :
 		    (fflush(fout) != 0 && errno != EBADF)) {
-		    zwarnnam(name, "write error: %e", NULL, errno);
+		    zwarnnam(name, "write error: %e", errno);
 		}
 		return 1;
 	    }
@@ -4085,7 +4084,7 @@ bin_print(char *name, char **args, Options ops, int func)
     /* Testing EBADF special-cases >&- redirections */
     if ((fout != stdout) ? (fclose(fout) != 0) :
 	(fflush(fout) != 0 && errno != EBADF)) {
-	zwarnnam(name, "write error: %e", NULL, errno);
+	zwarnnam(name, "write error: %e", errno);
 	ret = 1;
     }
     return ret;
@@ -4107,7 +4106,7 @@ bin_shift(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
  
     if (num < 0) {
 	unqueue_signals();
-        zwarnnam(name, "argument to shift must be non-negative", NULL, 0);
+        zwarnnam(name, "argument to shift must be non-negative");
         return 1;
     }
 
@@ -4115,7 +4114,7 @@ bin_shift(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
         for (; *argv; argv++)
             if ((s = getaparam(*argv))) {
                 if (num > arrlen(s)) {
-		    zwarnnam(name, "shift count must be <= $#", NULL, 0);
+		    zwarnnam(name, "shift count must be <= $#");
 		    ret++;
 		    continue;
 		}
@@ -4124,7 +4123,7 @@ bin_shift(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
             }
     } else {
         if (num > (l = arrlen(pparams))) {
-	    zwarnnam(name, "shift count must be <= $#", NULL, 0);
+	    zwarnnam(name, "shift count must be <= $#");
 	    ret = 1;
 	} else {
 	    s = zalloc((l - num + 1) * sizeof(char *));
@@ -4206,7 +4205,7 @@ bin_getopts(UNUSED(char *name), char **argv, UNUSED(Options ops), UNUSED(int fun
 	    zoptarg = metafy(optbuf, lenoptbuf, META_DUP);
 	} else {
 	    zwarn(*p == '?' ? "bad option: -%c" :
-		  "argument expected after -%c option", NULL, opch);
+		  "argument expected after -%c option", opch);
 	    zoptarg=ztrdup("");
 	}
 	return 0;
@@ -4266,13 +4265,13 @@ bin_break(char *name, char **argv, UNUSED(Options ops), int func)
     switch (func) {
     case BIN_CONTINUE:
 	if (!loops) {   /* continue is only permitted in loops */
-	    zerrnam(name, "not in while, until, select, or repeat loop", NULL, 0);
+	    zerrnam(name, "not in while, until, select, or repeat loop");
 	    return 1;
 	}
 	contflag = 1;   /* ARE WE SUPPOSED TO FALL THROUGH HERE? */
     case BIN_BREAK:
 	if (!loops) {   /* break is only permitted in loops */
-	    zerrnam(name, "not in while, until, select, or repeat loop", NULL, 0);
+	    zerrnam(name, "not in while, until, select, or repeat loop");
 	    return 1;
 	}
 	breaks = nump ? minimum(num,loops) : 1;
@@ -4290,7 +4289,7 @@ bin_break(char *name, char **argv, UNUSED(Options ops), int func)
 	break;
     case BIN_LOGOUT:
 	if (unset(LOGINSHELL)) {
-	    zerrnam(name, "not login shell", NULL, 0);
+	    zerrnam(name, "not login shell");
 	    return 1;
 	}
 	/*FALLTHROUGH*/
@@ -4338,13 +4337,13 @@ checkjobs(void)
 	if (jobtab[i].stat & STAT_STOPPED) {
 
 #ifdef USE_SUSPENDED
-	    zerr("you have suspended jobs.", NULL, 0);
+	    zerr("you have suspended jobs.");
 #else
-	    zerr("you have stopped jobs.", NULL, 0);
+	    zerr("you have stopped jobs.");
 #endif
 
 	} else
-	    zerr("you have running jobs.", NULL, 0);
+	    zerr("you have running jobs.");
 	stopmsg = 1;
     }
 }
@@ -4479,7 +4478,7 @@ bin_dot(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 	pparams = old;
     }
     if (ret)
-	zwarnnam(name, "%e: %s", enam, errno);
+	zwarnnam(name, "%e: %s", errno, enam);
     zsfree(arg0);
     if (old0)
 	argzero = old0;
@@ -4569,7 +4568,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
 	char *eptr, *optarg = OPT_ARG(ops,c);
 	nchars = (int)zstrtol(optarg, &eptr, 10);
 	if (*eptr) {
-	    zwarnnam(name, "number expected after -%c: %s", optarg, c);
+	    zwarnnam(name, "number expected after -%c: %s", c, optarg);
 	    return 1;
 	}
     }
@@ -4579,7 +4578,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
     reply = *args ? *args++ : OPT_ISSET(ops,'A') ? "reply" : "REPLY";
 
     if (OPT_ISSET(ops,'A') && *args) {
-	zwarnnam(name, "only one array argument allowed", NULL, 0);
+	zwarnnam(name, "only one array argument allowed");
 	return 1;
     }
 
@@ -4626,7 +4625,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
 	} else {
 	    readfd = (int)zstrtol(argptr, &eptr, 10);
 	    if (*eptr) {
-		zwarnnam(name, "number expected after -%c: %s", argptr, 'u');
+		zwarnnam(name, "number expected after -%c: %s", 'u', argptr);
 		return 1;
 	    }
 	}
@@ -5096,7 +5095,7 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func)
     if (func == BIN_BRACKET) {
 	for (s = argv; *s; s++);
 	if (s == argv || strcmp(s[-1], "]")) {
-	    zwarnnam(name, "']' expected", NULL, 0);
+	    zwarnnam(name, "']' expected");
 	    return 1;
 	}
 	s[-1] = NULL;
@@ -5118,7 +5117,7 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func)
     }
 
     if (!prog || tok == LEXERR) {
-	zwarnnam(name, tokstr ? "parse error" : "argument expected", NULL, 0);
+	zwarnnam(name, tokstr ? "parse error" : "argument expected");
 	return 1;
     }
 
@@ -5208,7 +5207,7 @@ bin_trap(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 	    for (; *argv; argv++) {
 		sig = getsignum(*argv);
 		if (sig == -1) {
-		    zwarnnam(name, "undefined signal: %s", *argv, 0);
+		    zwarnnam(name, "undefined signal: %s", *argv);
 		    break;
 		}
 		unsettrap(sig);
@@ -5222,7 +5221,7 @@ bin_trap(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
     if (!*arg)
 	prog = &dummy_eprog;
     else if (!(prog = parse_string(arg))) {
-	zwarnnam(name, "couldn't parse trap command", NULL, 0);
+	zwarnnam(name, "couldn't parse trap command");
 	return 1;
     }
 
@@ -5233,7 +5232,7 @@ bin_trap(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 
 	sig = getsignum(*argv);
 	if (sig == -1) {
-	    zwarnnam(name, "undefined signal: %s", *argv, 0);
+	    zwarnnam(name, "undefined signal: %s", *argv);
 	    break;
 	}
 	if (!strcmp(sigs[sig], *argv))
@@ -5325,7 +5324,7 @@ bin_umask(char *nam, char **args, Options ops, UNUSED(int func))
 	/* Simple digital umask. */
 	um = zstrtol(s, &s, 8);
 	if (*s) {
-	    zwarnnam(nam, "bad umask", NULL, 0);
+	    zwarnnam(nam, "bad umask");
 	    return 1;
 	}
     } else {
@@ -5354,9 +5353,9 @@ bin_umask(char *nam, char **args, Options ops, UNUSED(int func))
 	    umaskop = (int)*s;
 	    if (!(umaskop == '+' || umaskop == '-' || umaskop == '=')) {
 		if (umaskop)
-		    zwarnnam(nam, "bad symbolic mode operator: %c", NULL, umaskop);
+		    zwarnnam(nam, "bad symbolic mode operator: %c", umaskop);
 		else
-		    zwarnnam(nam, "bad umask", NULL, 0);
+		    zwarnnam(nam, "bad umask");
 		return 1;
 	    }
 	    /* Permissions mask -- r=read, w=write, x=execute. */
@@ -5369,8 +5368,7 @@ bin_umask(char *nam, char **args, Options ops, UNUSED(int func))
 		else if (*s == 'x')
 		    mask |= 0111 & whomask;
 		else {
-		    zwarnnam(nam, "bad symbolic mode permission: %c",
-			     NULL, *s);
+		    zwarnnam(nam, "bad symbolic mode permission: %c", *s);
 		    return 1;
 		}
 	    /* Apply parsed argument to um. */
@@ -5386,7 +5384,7 @@ bin_umask(char *nam, char **args, Options ops, UNUSED(int func))
 		break;
 	}
 	if (*s) {
-	    zwarnnam(nam, "bad character in symbolic mode: %c", NULL, *s);
+	    zwarnnam(nam, "bad character in symbolic mode: %c", *s);
 	    return 1;
 	}
     }
@@ -5402,6 +5400,6 @@ bin_umask(char *nam, char **args, Options ops, UNUSED(int func))
 mod_export int
 bin_notavail(char *nam, UNUSED(char **argv), UNUSED(Options ops), UNUSED(int func))
 {
-    zwarnnam(nam, "not available on this system", NULL, 0);
+    zwarnnam(nam, "not available on this system");
     return 1;
 }
diff --git a/Src/cond.c b/Src/cond.c
index aa808715f..daf176909 100644
--- a/Src/cond.c
+++ b/Src/cond.c
@@ -114,8 +114,7 @@ evalcond(Estate state, char *fromtest)
 	    if ((cd = getconddef((ctype == COND_MODI), name + 1, 1))) {
 		if (ctype == COND_MOD &&
 		    (l < cd->min || (cd->max >= 0 && l > cd->max))) {
-		    zwarnnam(fromtest, "unrecognized condition: `%s'",
-			     name, 0);
+		    zwarnnam(fromtest, "unrecognized condition: `%s'", name);
 		    return 2;
 		}
 		if (tracingcond)
@@ -132,7 +131,7 @@ evalcond(Estate state, char *fromtest)
 		    (cd = getconddef(0, name + 1, 1))) {
 		    if (l < cd->min || (cd->max >= 0 && l > cd->max)) {
 			zwarnnam(fromtest, "unrecognized condition: `%s'",
-				 name, 0);
+				 name);
 			return 2;
 		    }
 		    if (tracingcond)
@@ -140,7 +139,7 @@ evalcond(Estate state, char *fromtest)
 		    return !cd->handler(strs, cd->condid);
 		} else {
 		    zwarnnam(fromtest,
-			     "unrecognized condition: `%s'", name, 0);
+			     "unrecognized condition: `%s'", name);
 		}
 	    }
 	    /* module not found, error */
@@ -197,8 +196,7 @@ evalcond(Estate state, char *fromtest)
 
 	    if (*eptr)
 	    {
-		zwarnnam(fromtest, "integer expression expected: %s",
-			 err, 0);
+		zwarnnam(fromtest, "integer expression expected: %s", err);
 		return 2;
 	    }
 
@@ -262,7 +260,7 @@ evalcond(Estate state, char *fromtest)
 
 		if (!(pprog = patcompile(right, (save ? PAT_ZDUP : PAT_STATIC),
 					 NULL))) {
-		    zwarnnam(fromtest, "bad pattern: %s", right, 0);
+		    zwarnnam(fromtest, "bad pattern: %s", right);
 		    return 2;
 		}
 		else if (save)
@@ -353,7 +351,7 @@ evalcond(Estate state, char *fromtest)
 	    return !(d == st->st_dev && i == st->st_ino);
 	}
     default:
-	zwarnnam(fromtest, "bad cond code", NULL, 0);
+	zwarnnam(fromtest, "bad cond code");
 	return 2;
     }
     return 1;
@@ -435,7 +433,7 @@ optison(char *name, char *s)
     else
 	i = optlookup(s);
     if (!i) {
-	zwarnnam(name, "no such option: %s", s, 0);
+	zwarnnam(name, "no such option: %s", s);
 	return 2;
     } else if(i < 0)
 	return !unset(-i);
diff --git a/Src/exec.c b/Src/exec.c
index cbbc744d7..784c9df56 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -196,7 +196,7 @@ zsetlimit(int limnum, char *nam)
 	limits[limnum].rlim_cur != current_limits[limnum].rlim_cur) {
 	if (setrlimit(limnum, limits + limnum)) {
 	    if (nam)
-		zwarnnam(nam, "setrlimit failed: %e", NULL, errno);
+		zwarnnam(nam, "setrlimit failed: %e", errno);
 	    return -1;
 	}
 	current_limits[limnum] = limits[limnum];
@@ -233,14 +233,14 @@ zfork(struct timeval *tv)
      * Is anybody willing to explain this test?
      */
     if (thisjob != -1 && thisjob >= jobtabsize - 1 && !expandjobtab()) {
-	zerr("job table full", NULL, 0);
+	zerr("job table full");
 	return -1;
     }
     if (tv)
 	gettimeofday(tv, &dummy_tz);
     pid = fork();
     if (pid == -1) {
-	zerr("fork failed: %e", NULL, errno);
+	zerr("fork failed: %e", errno);
 	return -1;
     }
 #ifdef HAVE_GETRLIMIT
@@ -406,15 +406,14 @@ zexecve(char *pth, char **argv)
 			for (ptr = execvebuf + 2; *ptr && *ptr == ' '; ptr++);
 			for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++);
 			if (eno == ENOENT) {
-			    char *buf;
 			    if (*ptr)
 				*ptr = '\0';
 			    /*
 			     * TODO: needs variable argument handling
 			     * in zerrmsg() etc. to do this properly.
 			     */
-			    buf = dyncat(pth, ": bad interpreter: %s: %e");
-			    zerr(buf, ptr2, eno);
+			    zerr("%s: bad interpreter: %s: %e", pth, ptr2,
+				 eno);
 			} else if (*ptr) {
 			    *ptr = '\0';
 			    argv[-2] = ptr2;
@@ -483,7 +482,7 @@ execute(LinkList args, int dash, int defpath)
 
     arg0 = (char *) peekfirst(args);
     if (isset(RESTRICTED) && (strchr(arg0, '/') || defpath)) {
-	zerr("%s: restricted", arg0, 0);
+	zerr("%s: restricted", arg0);
 	_exit(1);
     }
 
@@ -522,7 +521,7 @@ execute(LinkList args, int dash, int defpath)
     closem(FDT_XTRACE);
     child_unblock();
     if ((int) strlen(arg0) >= PATH_MAX) {
-	zerr("command too long: %s", arg0, 0);
+	zerr("command too long: %s", arg0);
 	_exit(1);
     }
     for (s = arg0; *s; s++)
@@ -531,7 +530,7 @@ execute(LinkList args, int dash, int defpath)
 	    if (arg0 == s || unset(PATHDIRS) ||
 		(arg0[0] == '.' && (arg0 + 1 == s ||
 				    (arg0[1] == '.' && arg0 + 2 == s)))) {
-		zerr("%e: %s", arg0, errno);
+		zerr("%e: %s", errno, arg0);
 		_exit((errno == EACCES || errno == ENOEXEC) ? 126 : 127);
 	    }
 	    break;
@@ -560,7 +559,7 @@ execute(LinkList args, int dash, int defpath)
 	}
 
 	if (!ps) {
-	    zerr("command not found: %s", arg0, 0);
+	    zerr("command not found: %s", arg0);
 	    _exit(127);
 	}
 
@@ -621,9 +620,9 @@ execute(LinkList args, int dash, int defpath)
     }
 
     if (eno)
-	zerr("%e: %s", arg0, eno);
+	zerr("%e: %s", eno, arg0);
     else
-	zerr("command not found: %s", arg0, 0);
+	zerr("command not found: %s", arg0);
     _exit((eno == EACCES || eno == ENOEXEC) ? 126 : 127);
 }
 
@@ -1440,7 +1439,7 @@ checkclobberparam(struct redir *f)
 
     if (v->pm->node.flags & PM_READONLY) {
 	zwarn("can't allocate file descriptor to readonly parameter %s",
-	      f->varid, 0);
+	      f->varid);
 	/* don't flag a system error for this */
 	errno = 0;
 	return 0;
@@ -1636,7 +1635,7 @@ addfd(int forked, int *save, struct multio **mfds, int fd1, int fd2, int rflag,
 	mfds[fd1]->rflag = rflag;
     } else {
 	if (mfds[fd1]->rflag != rflag) {
-	    zerr("file mode mismatch on fd %d", NULL, fd1);
+	    zerr("file mode mismatch on fd %d", fd1);
 	    return;
 	}
 	if (mfds[fd1]->ct == 1) {	/* split the stream */
@@ -1736,7 +1735,7 @@ addvars(Estate state, Wordcode pc, int addflags)
 		if ((addflags & ADDVAR_RESTRICT) && isset(RESTRICTED) &&
 		    (pm = (Param) paramtab->removenode(paramtab, name)) &&
 		    (pm->node.flags & PM_RESTRICTED)) {
-		    zerr("%s: restricted", pm->node.nam, 0);
+		    zerr("%s: restricted", pm->node.nam);
 		    zsfree(val);
 		    state->pc = opc;
 		    return;
@@ -1998,7 +1997,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
 			break;
 		    } else if (!nullcmd || !*nullcmd || opts[CSHNULLCMD] ||
 			       (cflags & BINF_PREFIX)) {
-			zerr("redirection with no command", NULL, 0);
+			zerr("redirection with no command");
 			errflag = lastval = 1;
 			return;
 		    } else if (!nullcmd || !*nullcmd || opts[SHNULLCMD]) {
@@ -2035,7 +2034,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
 		}
 	    } else if (isset(RESTRICTED) && (cflags & BINF_EXEC) && do_exec) {
 		zerrnam("exec", "%s: restricted",
-			(char *) getdata(firstnode(args)), 0);
+			(char *) getdata(firstnode(args)));
 		lastval = 1;
 		return;
 	    }
@@ -2063,7 +2062,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
 	    }
 	    if (!(hn = builtintab->getnode(builtintab, cmdarg))) {
 		if (cflags & BINF_BUILTIN) {
-		    zwarn("no such builtin: %s", cmdarg, 0);
+		    zwarn("no such builtin: %s", cmdarg);
 		    lastval = 1;
                     opts[AUTOCONTINUE] = oautocont;
 		    return;
@@ -2334,7 +2333,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
 		execerr();
 	    }
 	    if (isset(RESTRICTED) && IS_WRITE_FILE(fn->type)) {
-		zwarn("writing redirection not allowed in restricted mode", NULL, 0);
+		zwarn("writing redirection not allowed in restricted mode");
 		execerr();
 	    }
 	    if (unset(EXECOPT))
@@ -2349,7 +2348,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
 		    closemnodes(mfds);
 		    fixfds(save);
 		    if (errno && errno != EINTR)
-			zwarn("%e", NULL, errno);
+			zwarn("%e", errno);
 		    execerr();
 		}
 		addfd(forked, save, mfds, fn->fd1, fil, 0, fn->varid);
@@ -2367,7 +2366,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
 		    closemnodes(mfds);
 		    fixfds(save);
 		    if (errno != EINTR)
-			zwarn("%e: %s", fn->name, errno);
+			zwarn("%e: %s", errno, fn->name);
 		    execerr();
 		}
 		addfd(forked, save, mfds, fn->fd1, fil, 0, fn->varid);
@@ -2405,7 +2404,10 @@ execcmd(Estate state, int input, int output, int how, int last1)
 			    "file descriptor %d out of range, not closed",
 			    "file descriptor %d used by shell, not closed"
 			};
-			zwarn(bad_msg[bad-1], fn->varid, fn->fd1);
+			if (bad > 2)
+			    zwarn(bad_msg[bad-1], fn->fd1);
+			else
+			    zwarn(bad_msg[bad-1], fn->varid);
 			execerr();
 		    }
 		}
@@ -2469,7 +2471,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
 		    closemnodes(mfds);
 		    fixfds(save);
 		    if (errno && errno != EINTR)
-			zwarn("%e: %s", fn->name, errno);
+			zwarn("%e: %s", errno, fn->name);
 		    execerr();
 		}
 		addfd(forked, save, mfds, fn->fd1, fil, 1, fn->varid);
@@ -2593,7 +2595,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
 		fflush(stdout);
 		if (save[1] == -2) {
 		    if (ferror(stdout)) {
-			zwarn("write error: %e", NULL, errno);
+			zwarn("write error: %e", errno);
 			clearerr(stdout);
 		    }
 		} else
@@ -2809,7 +2811,7 @@ entersubsh(int how, int cl, int fake, int revertpgrp)
 	    if (isatty(0)) {
 		close(0);
 		if (open("/dev/null", O_RDWR | O_NOCTTY)) {
-		    zerr("can't open /dev/null: %e", NULL, errno);
+		    zerr("can't open /dev/null: %e", errno);
 		    _exit(1);
 		}
 	    }
@@ -3022,7 +3024,7 @@ getoutput(char *cmd, int qt)
 	    return NULL;
 	untokenize(s);
 	if ((stream = open(unmeta(s), O_RDONLY | O_NOCTTY)) == -1) {
-	    zerr("%e: %s", s, errno);
+	    zerr("%e: %s", errno, s);
 	    return NULL;
 	}
 	return readoutput(stream, qt);
@@ -3059,7 +3061,7 @@ getoutput(char *cmd, int qt)
     cmdpop();
     close(1);
     _exit(lastval);
-    zerr("exit returned in child!!", NULL, 0);
+    zerr("exit returned in child!!");
     kill(getpid(), SIGKILL);
     return NULL;
 }
@@ -3128,12 +3130,12 @@ parsecmd(char *cmd)
 
     for (str = cmd + 2; *str && *str != Outpar; str++);
     if (!*str || cmd[1] != Inpar) {
-	zerr("oops.", NULL, 0);
+	zerr("oops.");
 	return NULL;
     }
     *str = '\0';
     if (str[1] || !(prog = parse_string(cmd + 2))) {
-	zerr("parse error in process substitution", NULL, 0);
+	zerr("parse error in process substitution");
 	return NULL;
     }
     return prog;
@@ -3212,7 +3214,7 @@ getoutputfile(char *cmd)
     cmdpop();
     close(1);
     _exit(lastval);
-    zerr("exit returned in child!!", NULL, 0);
+    zerr("exit returned in child!!");
     kill(getpid(), SIGKILL);
     return NULL;
 }
@@ -3242,7 +3244,7 @@ char *
 getproc(char *cmd)
 {
 #if !defined(HAVE_FIFOS) && !defined(PATH_DEV_FD)
-    zerr("doesn't look like your system supports FIFOs.", NULL, 0);
+    zerr("doesn't look like your system supports FIFOs.");
     return NULL;
 #else
     Eprog prog;
@@ -3660,7 +3662,7 @@ loadautofn(Shfunc shf, int fksh, int autol)
     if (prog == &dummy_eprog) {
 	/* We're not actually in the function; decrement locallevel */
 	locallevel--;
-	zwarn("%s: function definition file not found", shf->node.nam, 0);
+	zwarn("%s: function definition file not found", shf->node.nam);
 	locallevel++;
 	popheap();
 	return NULL;
@@ -3685,7 +3687,7 @@ loadautofn(Shfunc shf, int fksh, int autol)
 	    if (!shf || (shf->node.flags & PM_UNDEFINED)) {
 		/* We're not actually in the function; decrement locallevel */
 		locallevel--;
-		zwarn("%s: function not defined by file", n, 0);
+		zwarn("%s: function not defined by file", n);
 		locallevel++;
 		popheap();
 		return NULL;
@@ -3787,7 +3789,7 @@ doshfunc(char *name, Eprog prog, LinkList doshargs, int flags, int noreturnval)
 #ifdef MAX_FUNCTION_DEPTH
     if(++funcdepth > MAX_FUNCTION_DEPTH)
     {
-        zerr("maximum nested function level reached", NULL, 0);
+        zerr("maximum nested function level reached");
 	goto undoshfunc;
     }
 #endif
@@ -3804,7 +3806,7 @@ doshfunc(char *name, Eprog prog, LinkList doshargs, int flags, int noreturnval)
 
 	if (!(shf = (Shfunc) shfunctab->getnode(shfunctab,
 						(name = fname)))) {
-	    zwarn("%s: function not defined by file", name, 0);
+	    zwarn("%s: function not defined by file", name);
 	    if (noreturnval)
 		errflag = 1;
 	    else
diff --git a/Src/glob.c b/Src/glob.c
index 3c05605a5..3a1b28784 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -486,7 +486,7 @@ scanner(Complist q)
 	    if (err == -1)
 		return;
 	    if (err) {
-		zerr("current directory lost during glob", NULL, 0);
+		zerr("current directory lost during glob");
 		return;
 	    }
 	    pathbufcwd = pathpos;
@@ -550,7 +550,7 @@ scanner(Complist q)
 		    if (err == -1)
 			break;
 		    if (err) {
-			zerr("current directory lost during glob", NULL, 0);
+			zerr("current directory lost during glob");
 			break;
 		    }
 		    pathbufcwd = pathpos;
@@ -591,7 +591,7 @@ scanner(Complist q)
 			if (statfullpath(fn, &buf, !q->follow)) {
 			    if (errno != ENOENT && errno != EINTR &&
 				errno != ENOTDIR && !errflag) {
-				zwarn("%e: %s", fn, errno);
+				zwarn("%e: %s", errno, fn);
 			    }
 			    continue;
 			}
@@ -630,7 +630,7 @@ scanner(Complist q)
     }
     if (pbcwdsav < pathbufcwd) {
 	if (restoredir(&ds))
-	    zerr("current directory lost during glob", NULL, 0);
+	    zerr("current directory lost during glob");
 	zsfree(ds.dirname);
 	if (ds.dirfd >= 0)
 	    close(ds.dirfd);
@@ -755,7 +755,7 @@ qgetnum(char **s)
     off_t v = 0;
 
     if (!idigit(**s)) {
-	zerr("number expected", NULL, 0);
+	zerr("number expected");
 	return 0;
     }
     while (idigit(**s))
@@ -814,7 +814,7 @@ qgetmodespec(char **s)
 		    val |= t | (t << 3) | (t << 6);
 		    break;
 		default:
-		    zerr("invalid mode specification", NULL, 0);
+		    zerr("invalid mode specification");
 		    return 0;
 		}
 	    }
@@ -838,7 +838,7 @@ qgetmodespec(char **s)
 		p++;
 	    }
 	    if (end && c != end && c != ',') {
-		zerr("invalid mode specification", NULL, 0);
+		zerr("invalid mode specification");
 		return 0;
 	    }
 	    if (how == '=') {
@@ -849,7 +849,7 @@ qgetmodespec(char **s)
 	    else
 		no |= val;
 	} else {
-	    zerr("invalid mode specification", NULL, 0);
+	    zerr("invalid mode specification");
 	    return 0;
         }
     } while (end && c != end);
@@ -1259,8 +1259,7 @@ zglob(LinkList list, LinkNode np, int nountok)
 			/* Find matching delimiters */
 			tt = get_strarg(s);
 			if (!*tt) {
-			    zerr("missing end of name",
-				 NULL, 0);
+			    zerr("missing end of name");
 			    data = 0;
 			} else {
 #ifdef USE_GETPWNAM
@@ -1271,13 +1270,13 @@ zglob(LinkList list, LinkNode np, int nountok)
 			    if ((pw = getpwnam(s + 1)))
 				data = pw->pw_uid;
 			    else {
-				zerr("unknown user", NULL, 0);
+				zerr("unknown user");
 				data = 0;
 			    }
 			    *tt = sav;
 #else /* !USE_GETPWNAM */
 			    sav = *tt;
-			    zerr("unknown user", NULL, 0);
+			    zerr("unknown user");
 			    data = 0;
 #endif /* !USE_GETPWNAM */
 			    if (sav)
@@ -1299,8 +1298,7 @@ zglob(LinkList list, LinkNode np, int nountok)
 
 			tt = get_strarg(s);
 			if (!*tt) {
-			    zerr("missing end of name",
-				 NULL, 0);
+			    zerr("missing end of name");
 			    data = 0;
 			} else {
 #ifdef USE_GETGRNAM
@@ -1311,13 +1309,13 @@ zglob(LinkList list, LinkNode np, int nountok)
 			    if ((gr = getgrnam(s + 1)))
 				data = gr->gr_gid;
 			    else {
-				zerr("unknown group", NULL, 0);
+				zerr("unknown group");
 				data = 0;
 			    }
 			    *tt = sav;
 #else /* !USE_GETGRNAM */
 			    sav = *tt;
-			    zerr("unknown group", NULL, 0);
+			    zerr("unknown group");
 			    data = 0;
 #endif /* !USE_GETGRNAM */
 			    if (sav)
@@ -1420,14 +1418,14 @@ zglob(LinkList list, LinkNode np, int nountok)
 		    case 'd': t = GS_DEPTH; break;
 		    case 'N': t = GS_NONE; break;
 		    default:
-			zerr("unknown sort specifier", NULL, 0);
+			zerr("unknown sort specifier");
 			restore_globstate(saved);
 			return;
 		    }
 		    if ((sense & 2) && !(t & (GS_NAME|GS_DEPTH)))
 			t <<= GS_SHIFT;
 		    if (gf_sorts & t) {
-			zerr("doubled sort specifier", NULL, 0);
+			zerr("doubled sort specifier");
 			restore_globstate(saved);
 			return;
 		    }
@@ -1450,7 +1448,7 @@ zglob(LinkList list, LinkNode np, int nountok)
 			    tt++;
 			if (tt == s)
 			{
-			    zerr("missing identifier after `+'", NULL, 0);
+			    zerr("missing identifier after `+'");
 			    tt = NULL;
 			}
 		    } else {
@@ -1458,7 +1456,7 @@ zglob(LinkList list, LinkNode np, int nountok)
 			tt = get_strarg(s);
 			if (!*tt)
 			{
-			    zerr("missing end of string", NULL, 0);
+			    zerr("missing end of string");
 			    tt = NULL;
 			}
 		    }
@@ -1490,7 +1488,7 @@ zglob(LinkList list, LinkNode np, int nountok)
 		    v.end = -1;
 		    v.inv = 0;
 		    if (getindex(&s, &v, 0) || s == os) {
-			zerr("invalid subscript", NULL, 0);
+			zerr("invalid subscript");
 			restore_globstate(saved);
 			return;
 		    }
@@ -1499,7 +1497,7 @@ zglob(LinkList list, LinkNode np, int nountok)
 		    break;
 		}
 		default:
-		    zerr("unknown file attribute", NULL, 0);
+		    zerr("unknown file attribute");
 		    restore_globstate(saved);
 		    return;
 		}
@@ -1591,7 +1589,7 @@ zglob(LinkList list, LinkNode np, int nountok)
 	    return;
 	}
 	errflag = 0;
-	zerr("bad pattern: %s", ostr, 0);
+	zerr("bad pattern: %s", ostr);
 	return;
     }
     if (!gf_nsorts) {
@@ -1616,7 +1614,7 @@ zglob(LinkList list, LinkNode np, int nountok)
 	if (isset(CSHNULLGLOB)) {
 	    badcshglob |= 1;	/* at least one cmd. line expansion failed */
 	} else if (isset(NOMATCH)) {
-	    zerr("no matches found: %s", ostr, 0);
+	    zerr("no matches found: %s", ostr);
 	    free(matchbuf);
 	    restore_globstate(saved);
 	    return;
@@ -1818,13 +1816,13 @@ xpandredir(struct redir *fn, LinkList tab)
 		if (!*s && s > fn->name)
 		    fn->fd2 = zstrtol(fn->name, NULL, 10);
 		else if (fn->type == REDIR_MERGEIN)
-		    zerr("file number expected", NULL, 0);
+		    zerr("file number expected");
 		else
 		    fn->type = REDIR_ERRWRITE;
 	    }
 	}
     } else if (fn->type == REDIR_MERGEIN)
-	zerr("file number expected", NULL, 0);
+	zerr("file number expected");
     else {
 	if (fn->type == REDIR_MERGEOUT)
 	    fn->type = REDIR_ERRWRITE;
@@ -2004,7 +2002,7 @@ matchpat(char *a, char *b)
     Patprog p = patcompile(b, PAT_STATIC, NULL);
 
     if (!p) {
-	zerr("bad pattern: %s", b, 0);
+	zerr("bad pattern: %s", b);
 	return 0;
     }
     return pattry(p, a);
@@ -2136,7 +2134,7 @@ compgetmatch(char *pat, int *flp, char **replstrp)
 	patflags &= ~PAT_NOANCH;
     p = patcompile(pat, patflags, NULL);
     if (!p) {
-	zerr("bad pattern: %s", pat, 0);
+	zerr("bad pattern: %s", pat);
 	return NULL;
     }
     if (*replstrp) {
diff --git a/Src/hist.c b/Src/hist.c
index 64c5c4fef..0873ccce5 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -339,7 +339,7 @@ getsubsargs(char *subline, int *gbalp, int *cflagp)
 	inungetc(follow);
     if (hsubl && !strstr(subline, hsubl)) {
 	herrflush();
-	zerr("substitution failed", NULL, 0);
+	zerr("substitution failed");
 	return 1;
     }
     return 0;
@@ -431,7 +431,7 @@ histsubchar(int c)
 	    if (ev == -1) {
 		herrflush();
 		unqueue_signals();
-		zerr("no such event: %s", buf, 0);
+		zerr("no such event: %s", buf);
 		return -1;
 	    }
 	} else {
@@ -485,7 +485,7 @@ histsubchar(int c)
 	    } else if ((ev = hcomsearch(buf)) == -1) {
 		herrflush();
 		unqueue_signals();
-		zerr("event not found: %s", buf, 0);
+		zerr("event not found: %s", buf);
 		return -1;
 	    } else
 		evset = 1;
@@ -510,7 +510,7 @@ histsubchar(int c)
 		} else {
 		    herrflush();
 		    unqueue_signals();
-		    zerr("Ambiguous history reference", NULL, 0);
+		    zerr("Ambiguous history reference");
 		    return -1;
 		}
 
@@ -568,7 +568,7 @@ histsubchar(int c)
 		gbal = 1;
 		c = ingetc();
 		if (c != 's' && c != '&') {
-		    zerr("'s' or '&' modifier expected after 'g'", NULL, 0);
+		    zerr("'s' or '&' modifier expected after 'g'");
 		    return -1;
 		}
 	    }
@@ -579,28 +579,28 @@ histsubchar(int c)
 	    case 'h':
 		if (!remtpath(&sline)) {
 		    herrflush();
-		    zerr("modifier failed: h", NULL, 0);
+		    zerr("modifier failed: h");
 		    return -1;
 		}
 		break;
 	    case 'e':
 		if (!rembutext(&sline)) {
 		    herrflush();
-		    zerr("modifier failed: e", NULL, 0);
+		    zerr("modifier failed: e");
 		    return -1;
 		}
 		break;
 	    case 'r':
 		if (!remtext(&sline)) {
 		    herrflush();
-		    zerr("modifier failed: r", NULL, 0);
+		    zerr("modifier failed: r");
 		    return -1;
 		}
 		break;
 	    case 't':
 		if (!remlpaths(&sline)) {
 		    herrflush();
-		    zerr("modifier failed: t", NULL, 0);
+		    zerr("modifier failed: t");
 		    return -1;
 		}
 		break;
@@ -612,7 +612,7 @@ histsubchar(int c)
 		    subst(&sline, hsubl, hsubr, gbal);
 		else {
 		    herrflush();
-		    zerr("no previous substitution", NULL, 0);
+		    zerr("no previous substitution");
 		    return -1;
 		}
 		break;
@@ -642,14 +642,14 @@ histsubchar(int c)
 		break;
 	    default:
 		herrflush();
-		zerr("illegal modifier: %c", NULL, c);
+		zerr("illegal modifier: %c", c);
 		return -1;
 	    }
 	} else {
 	    if (c != '}' || !bflag)
 		inungetc(c);
 	    if (c != '}' && bflag) {
-		zerr("'}' expected", NULL, 0);
+		zerr("'}' expected");
 		return -1;
 	    }
 	    break;
@@ -1358,12 +1358,12 @@ getargspec(int argc, int marg, int evset)
     else if (c == '%') {
 	if (evset) {
 	    herrflush();
-	    zerr("Ambiguous history reference", NULL, 0);
+	    zerr("Ambiguous history reference");
 	    return -2;
 	}
 	if (marg == -1) {
 	    herrflush();
-	    zerr("%% with no previous word matched", NULL, 0);
+	    zerr("%% with no previous word matched");
 	    return -2;
 	}
 	ret = marg;
@@ -1621,7 +1621,7 @@ gethist(int ev)
     ret = quietgethist(ev);
     if (!ret) {
 	herrflush();
-	zerr("no such event: %d", NULL, ev);
+	zerr("no such event: %d", ev);
     }
     return ret;
 }
@@ -1636,7 +1636,7 @@ getargs(Histent elist, int arg1, int arg2)
     if (arg2 < arg1 || arg1 >= nwords || arg2 >= nwords) {
 	/* remember, argN is indexed from 0, nwords is total no. of words */
 	herrflush();
-	zerr("no such word in event", NULL, 0);
+	zerr("no such word in event");
 	return NULL;
     }
 
@@ -1761,7 +1761,7 @@ hdynread(int stop)
     *ptr = 0;
     if (c == '\n') {
 	inungetc('\n');
-	zerr("delimiter expected", NULL, 0);
+	zerr("delimiter expected");
 	zfree(buf, bsiz);
 	return NULL;
     }
@@ -1927,7 +1927,7 @@ readhistfile(char *fn, int err, int readflags)
 	    char *pt = buf;
 
 	    if (l < 0) {
-		zerr("corrupt history file %s", fn, 0);
+		zerr("corrupt history file %s", fn);
 		break;
 	    }
 	    if (*pt == ':') {
@@ -2023,7 +2023,7 @@ readhistfile(char *fn, int err, int readflags)
 
 	fclose(in);
     } else if (err)
-	zerr("can't read history file %s", fn, 0);
+	zerr("can't read history file %s", fn);
 
     unlockhistfile(fn);
 }
@@ -2146,7 +2146,7 @@ savehistfile(char *fn, int err, int writeflags)
 	fclose(out);
 	if (tmpfile) {
 	    if (rename(tmpfile, unmeta(fn)) < 0)
-		zerr("can't rename %s.new to $HISTFILE", fn, 0);
+		zerr("can't rename %s.new to $HISTFILE", fn);
 	    free(tmpfile);
 	}
 
@@ -2170,10 +2170,10 @@ savehistfile(char *fn, int err, int writeflags)
 	}
     } else if (err) {
 	if (tmpfile) {
-	    zerr("can't write history file %s.new", fn, 0);
+	    zerr("can't write history file %s.new", fn);
 	    free(tmpfile);
 	} else
-	    zerr("can't write history file %s", fn, 0);
+	    zerr("can't write history file %s", fn);
     }
 
     unlockhistfile(fn);
diff --git a/Src/init.c b/Src/init.c
index 2ddef9e0a..7447842ab 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -170,7 +170,7 @@ loop(int toplevel, int justonce)
 		noexitct = 0;
 	}
 	if (ferror(stderr)) {
-	    zerr("write error", NULL, 0);
+	    zerr("write error");
 	    clearerr(stderr);
 	}
 	if (subsh)		/* how'd we get this far in a subshell? */
@@ -264,12 +264,12 @@ parseargs(char **argv)
 		if (!*++*argv)
 		    argv++;
 		if (!*argv) {
-		    zerr("string expected after -o", NULL, 0);
+		    zerr("string expected after -o");
 		    exit(1);
 		}
 	    longoptions:
 		if (!(optno = optlookup(*argv))) {
-		    zerr("no such option: %s", *argv, 0);
+		    zerr("no such option: %s", *argv);
 		    exit(1);
 		} else if (optno == RESTRICTED)
 		    restricted = action;
@@ -281,13 +281,13 @@ parseargs(char **argv)
 		while (*++*argv)
 		    if (!isspace(STOUC(**argv))) {
 		    badoptionstring:
-			zerr("bad option string: `%s'", args, 0);
+			zerr("bad option string: `%s'", args);
 			exit(1);
 		    }
 		break;
 	    } else {
 	    	if (!(optno = optlookupc(**argv))) {
-		    zerr("bad option: -%c", NULL, **argv);
+		    zerr("bad option: -%c", **argv);
 		    exit(1);
 		} else if (optno == RESTRICTED)
 		    restricted = action;
@@ -301,7 +301,7 @@ parseargs(char **argv)
     paramlist = znewlinklist();
     if (cmd) {
 	if (!*argv) {
-	    zerr("string expected after -%s", cmd, 0);
+	    zerr("string expected after -%s", cmd);
 	    exit(1);
 	}
 	cmd = *argv++;
@@ -311,7 +311,7 @@ parseargs(char **argv)
 	    if (!cmd)
 		SHIN = movefd(open(unmeta(*argv), O_RDONLY | O_NOCTTY));
 	    if (SHIN == -1) {
-		zerr("can't open input file: %s", *argv, 0);
+		zerr("can't open input file: %s", *argv);
 		exit(127);
 	    }
 	    opts[INTERACTIVE] &= 1;
@@ -548,7 +548,7 @@ init_term(void)
 #endif
     {
 	if (isset(INTERACTIVE))
-	    zerr("can't find terminal definition for %s", term, 0);
+	    zerr("can't find terminal definition for %s", term);
 	errflag = 0;
 	termflags |= TERM_BAD;
 	return 0;
@@ -1241,8 +1241,7 @@ mod_export CompctlReadFn compctlreadptr = fallback_compctlread;
 mod_export int
 fallback_compctlread(char *name, UNUSED(char **args), UNUSED(Options ops), UNUSED(char *reply))
 {
-    zwarnnam(name, "option valid only in functions called from completion",
-	    NULL, 0);
+    zwarnnam(name, "option valid only in functions called from completion");
     return 1;
 }
 
@@ -1346,6 +1345,6 @@ zsh_main(UNUSED(int argc), char **argv)
 	    zexit(lastval, 0);
 	}
 	zerrnam("zsh", (!islogin) ? "use 'exit' to exit."
-		: "use 'logout' to logout.", NULL, 0);
+		: "use 'logout' to logout.");
     }
 }
diff --git a/Src/input.c b/Src/input.c
index 546ed2f6a..99db53e54 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -419,7 +419,7 @@ stuff(char *fn)
     off_t len;
 
     if (!(in = fopen(unmeta(fn), "r"))) {
-	zerr("can't open %s", fn, 0);
+	zerr("can't open %s", fn);
 	return 1;
     }
     fseek(in, 0, 2);
@@ -427,7 +427,7 @@ stuff(char *fn)
     fseek(in, 0, 0);
     buf = (char *)zalloc(len + 1);
     if (!(fread(buf, len, 1, in))) {
-	zerr("read error on %s", fn, 0);
+	zerr("read error on %s", fn);
 	fclose(in);
 	zfree(buf, len + 1);
 	return 1;
diff --git a/Src/jobs.c b/Src/jobs.c
index f388da7fd..cfc733ecf 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -1303,7 +1303,7 @@ initjob(void)
     if (expandjobtab())
 	return initnewjob(i);
 
-    zerr("job table full or recursion limit exceeded", NULL, 0);
+    zerr("job table full or recursion limit exceeded");
     return -1;
 }
 
@@ -1446,7 +1446,7 @@ getjob(char *s, char *prog)
     /* "%%", "%+" and "%" all represent the current job */
     if (*s == '%' || *s == '+' || !*s) {
 	if (curjob == -1) {
-	    zwarnnam(prog, "no current job", NULL, 0);
+	    zwarnnam(prog, "no current job");
 	    returnval = -1;
 	    goto done;
 	}
@@ -1456,7 +1456,7 @@ getjob(char *s, char *prog)
     /* "%-" represents the previous job */
     if (*s == '-') {
 	if (prevjob == -1) {
-	    zwarnnam(prog, "no previous job", NULL, 0);
+	    zwarnnam(prog, "no previous job");
 	    returnval = -1;
 	    goto done;
 	}
@@ -1471,7 +1471,7 @@ getjob(char *s, char *prog)
 	    returnval = jobnum;
 	    goto done;
 	}
-	zwarnnam(prog, "%%%s: no such job", s, 0);
+	zwarnnam(prog, "%%%s: no such job", s);
 	returnval = -1;
 	goto done;
     }
@@ -1487,7 +1487,7 @@ getjob(char *s, char *prog)
 			returnval = jobnum;
 			goto done;
 		    }
-	zwarnnam(prog, "job not found: %s", s, 0);
+	zwarnnam(prog, "job not found: %s", s);
 	returnval = -1;
 	goto done;
     }
@@ -1500,7 +1500,7 @@ getjob(char *s, char *prog)
     }
     /* if we get here, it is because none of the above succeeded and went
     to done */
-    zwarnnam(prog, "job not found: %s", s, 0);
+    zwarnnam(prog, "job not found: %s", s);
     returnval = -1;
   done:
     return returnval;
@@ -1528,7 +1528,7 @@ init_jobs(char **argv, char **envp)
      */
     jobtab = (struct job *)zalloc(init_bytes);
     if (!jobtab) {
-	zerr("failed to allocate job table, aborting.", NULL, 0);
+	zerr("failed to allocate job table, aborting.");
 	exit(1);
     }
     jobtabsize = MAXJOBS_ALLOC;
@@ -1643,11 +1643,11 @@ bin_fg(char *name, char **argv, Options ops, int func)
 	int len;
 
 	if(isset(RESTRICTED)) {
-	    zwarnnam(name, "-Z is restricted", NULL, 0);
+	    zwarnnam(name, "-Z is restricted");
 	    return 1;
 	}
 	if(!argv[0] || argv[1]) {
-	    zwarnnam(name, "-Z requires one argument", NULL, 0);
+	    zwarnnam(name, "-Z requires one argument");
 	    return 1;
 	}
 	queue_signals();
@@ -1670,7 +1670,7 @@ bin_fg(char *name, char **argv, Options ops, int func)
 
     if ((func == BIN_FG || func == BIN_BG) && !jobbing) {
 	/* oops... maybe bg and fg should have been disabled? */
-	zwarnnam(name, "no job control in this shell.", NULL, 0);
+	zwarnnam(name, "no job control in this shell.");
 	return 1;
     }
 
@@ -1694,7 +1694,7 @@ bin_fg(char *name, char **argv, Options ops, int func)
 	    /* W.r.t. the above comment, we'd better have a current job at this
 	    point or else. */
 	    if (curjob == -1 || (jobtab[curjob].stat & STAT_NOPRINT)) {
-		zwarnnam(name, "no current job", NULL, 0);
+		zwarnnam(name, "no current job");
 		unqueue_signals();
 		return 1;
 	    }
@@ -1755,7 +1755,7 @@ bin_fg(char *name, char **argv, Options ops, int func)
 		if (!retval)
 		    retval = lastval2;
 	    } else {
-		zwarnnam(name, "pid %d is not a child of this shell", 0, pid);
+		zwarnnam(name, "pid %d is not a child of this shell", pid);
 		/* presumably lastval2 doesn't tell us a heck of a lot? */
 		retval = 1;
 	    }
@@ -1771,7 +1771,7 @@ bin_fg(char *name, char **argv, Options ops, int func)
 	}
 	if (!(jobtab[job].stat & STAT_INUSE) ||
 	    (jobtab[job].stat & STAT_NOPRINT)) {
-	    zwarnnam(name, "no such job: %d", 0, job);
+	    zwarnnam(name, "no such job: %d", job);
 	    unqueue_signals();
 	    return 1;
 	}
@@ -1793,7 +1793,7 @@ bin_fg(char *name, char **argv, Options ops, int func)
 		makerunning(jobtab + job);
 	    else if (func == BIN_BG) {
 		/* Silly to bg a job already running. */
-		zwarnnam(name, "job already in background", NULL, 0);
+		zwarnnam(name, "job already in background");
 		thisjob = ocj;
 		unqueue_signals();
 		return 1;
@@ -1887,7 +1887,7 @@ bin_fg(char *name, char **argv, Options ops, int func)
 #else
                          "warning: job is stopped, use `kill -CONT%s' to resume",
 #endif
-                         pids, 0);
+                         pids);
 	    }
 	    deletejob(jobtab + job);
 	    break;
@@ -1964,14 +1964,14 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
 			    }
 			    if (sig > SIGCOUNT) {
 				zwarnnam(nam, "unknown signal: SIG%s",
-					 signame, 0);
+					 signame);
 				returnval++;
 			    } else
 				printf("%d\n", sig);
 			} else {
 			    if (*signame) {
 				zwarnnam(nam, "unknown signal: SIG%s",
-					 signame, 0);
+					 signame);
 				returnval++;
 			    } else {
 				if (WIFSIGNALED(sig))
@@ -1998,19 +1998,19 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
 	    	char *endp;
 
 	    	if (!*++argv) {
-		    zwarnnam(nam, "-n: argument expected", NULL, 0);
+		    zwarnnam(nam, "-n: argument expected");
 		    return 1;
 		}
 		sig = zstrtol(*argv, &endp, 10);
 		if (*endp) {
-		    zwarnnam(nam, "invalid signal number", signame, 0);
+		    zwarnnam(nam, "invalid signal number: %s", signame);
 		    return 1;
 		}
 	    } else {
 		if (!((*argv)[1] == 's' && (*argv)[2] == '\0'))
 		    signame = *argv + 1;
 		else if (!(*++argv)) {
-		    zwarnnam(nam, "-s: argument expected", NULL, 0);
+		    zwarnnam(nam, "-s: argument expected");
 		    return 1;
 		} else
 		    signame = *argv;
@@ -2035,8 +2035,8 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
 			}
 		}
 		if (sig > SIGCOUNT) {
-		    zwarnnam(nam, "unknown signal: SIG%s", signame, 0);
-		    zwarnnam(nam, "type kill -l for a List of signals", NULL, 0);
+		    zwarnnam(nam, "unknown signal: SIG%s", signame);
+		    zwarnnam(nam, "type kill -l for a List of signals");
 		    return 1;
 		}
 	    }
@@ -2045,7 +2045,7 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
     }
 
     if (!*argv) {
-    	zwarnnam(nam, "not enough arguments", NULL, 0);
+    	zwarnnam(nam, "not enough arguments");
 	return 1;
     }
 
@@ -2079,7 +2079,7 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
 		    killjb(jobtab + p, SIGCONT);
 	    }
 	} else if (!isanum(*argv)) {
-	    zwarnnam("kill", "illegal pid: %s", *argv, 0);
+	    zwarnnam("kill", "illegal pid: %s", *argv);
 	    returnval++;
 	} else if (kill(atoi(*argv), sig) == -1) {
 	    zwarnnam("kill", "kill %s failed: %e", *argv, errno);
@@ -2195,7 +2195,7 @@ bin_suspend(char *name, UNUSED(char **argv), Options ops, UNUSED(int func))
 {
     /* won't suspend a login shell, unless forced */
     if (islogin && !OPT_ISSET(ops,'f')) {
-	zwarnnam(name, "can't suspend login shell", NULL, 0);
+	zwarnnam(name, "can't suspend login shell");
 	return 1;
     }
     if (jobbing) {
diff --git a/Src/lex.c b/Src/lex.c
index 55920a142..635e847d2 100644
--- a/Src/lex.c
+++ b/Src/lex.c
@@ -1269,11 +1269,11 @@ gettokstr(int c, int sub)
   brk:
     hungetc(c);
     if (unmatched)
-	zerr("unmatched %c", NULL, unmatched);
+	zerr("unmatched %c", unmatched);
     if (in_brace_param) {
 	while(bct-- >= in_brace_param)
 	    cmdpop();
-	zerr("closing brace expected", NULL, 0);
+	zerr("closing brace expected");
     } else if (unset(IGNOREBRACES) && !sub && len > 1 &&
 	       peek == STRING && bptr[-1] == '}' && bptr[-2] != Bnull) {
 	/* hack to get {foo} command syntax work */
@@ -1438,9 +1438,9 @@ parsestr(char *s)
     if ((err = parsestrnoerr(s))) {
 	untokenize(s);
 	if (err > 32 && err < 127)
-	    zerr("parse error near `%c'", NULL, err);
+	    zerr("parse error near `%c'", err);
 	else
-	    zerr("parse error", NULL, 0);
+	    zerr("parse error");
     }
     return err;
 }
diff --git a/Src/loop.c b/Src/loop.c
index a29ac1982..7037ddc82 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -590,7 +590,7 @@ execcase(Estate state, int do_exec)
 	    }
 	    if (!(pprog = patcompile(pat, (save ? PAT_ZDUP : PAT_STATIC),
 				     NULL)))
-		zerr("bad pattern: %s", pat, 0);
+		zerr("bad pattern: %s", pat);
 	    else if (save)
 		*spprog = pprog;
 	}
diff --git a/Src/math.c b/Src/math.c
index b14c1cd7a..336416597 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -240,7 +240,7 @@ lexconstant(void)
 	if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
 #endif
 	if (ptr == nptr || *nptr == '.') {
-	    zerr("bad floating point constant", NULL, 0);
+	    zerr("bad floating point constant");
 	    return EOI;
 	}
 	ptr = nptr;
@@ -421,7 +421,7 @@ zzlex(void)
 		if (idigit(*ptr)) {
 		    n = zstrtol(ptr, &ptr, 10);
 		    if (*ptr != ']' || !idigit(*++ptr)) {
-			zerr("bad base syntax", NULL, 0);
+			zerr("bad base syntax");
 			return EOI;
 		    }
 		    yyval.u.l = zstrtol(ptr, &ptr, lastbase = n);
@@ -438,7 +438,7 @@ zzlex(void)
 		    outputradix = n * zstrtol(ptr, &ptr, 10);
 		} else {
 		    bofs:
-		    zerr("bad output format specification", NULL, 0);
+		    zerr("bad output format specification");
 		    return EOI;
 		}
 		if(*ptr != ']')
@@ -460,7 +460,7 @@ zzlex(void)
 
 		    ptr++;
 		    if (!*ptr) {
-			zerr("character missing after ##", NULL, 0);
+			zerr("character missing after ##");
 			return EOI;
 		    }
 		    ptr = getkeystring(ptr, NULL, 6, &v);
@@ -517,7 +517,7 @@ static void
 push(mnumber val, char *lval, int getme)
 {
     if (sp == STACKSZ - 1)
-	zerr("stack overflow", NULL, 0);
+	zerr("stack overflow");
     else
 	sp++;
     stack[sp].val = val;
@@ -561,7 +561,7 @@ static mnumber
 setvar(char *s, mnumber v)
 {
     if (!s) {
-	zerr("lvalue required", NULL, 0);
+	zerr("lvalue required");
 	v.type = MN_INTEGER;
 	v.u.l = 0;
 	return v;
@@ -631,8 +631,7 @@ callmathfunc(char *o)
 		}
 	    }
 	    if (*a && !errflag)
-		zerr("bad math expression: illegal character: %c",
-		     NULL, *a);
+		zerr("bad math expression: illegal character: %c", *a);
 	    if (!errflag) {
 		if (argc >= f->minargs && (f->maxargs < 0 ||
 					   argc <= f->maxargs)) {
@@ -640,7 +639,7 @@ callmathfunc(char *o)
 			char *shfnam = f->module ? f->module : n;
 			Eprog prog = getshfunc(shfnam);
 			if (prog == &dummy_eprog)
-			    zerr("no such function: %s", shfnam, 0);
+			    zerr("no such function: %s", shfnam);
 			else {
 			    doshfunc(n, prog, l, 0, 1);
 			    return lastmathval;
@@ -655,11 +654,11 @@ callmathfunc(char *o)
 			return f->nfunc(n, argc, argv, f->funcid);
 		    }
 		} else
-		    zerr("wrong number of arguments: %s", o, 0);
+		    zerr("wrong number of arguments: %s", o);
 	    }
 	}
     } else
-	zerr("unknown function: %s", n, 0);
+	zerr("unknown function: %s", n);
 
     dummy.type = MN_INTEGER;
     dummy.u.l = 0;
@@ -672,7 +671,7 @@ static int
 notzero(mnumber a)
 {
     if ((a.type & MN_INTEGER) ? a.u.l == 0 : a.u.d == 0.0) {
-	zerr("division by zero", NULL, 0);
+	zerr("division by zero");
 	return 0;
     }
     return 1;
@@ -691,7 +690,7 @@ op(int what)
     if (errflag)
 	return;
     if (sp < 0) {
-	zerr("bad math expression: stack empty", NULL, 0);
+	zerr("bad math expression: stack empty");
 	return;
     }
 
@@ -857,7 +856,7 @@ op(int what)
 			/* Error if (-num ** b) and b is not an integer */
 			double tst = (double)(zlong)b.u.d;
 			if (tst != b.u.d) {
-			    zerr("imaginary power", NULL, 0);
+			    zerr("imaginary power");
 			    return;
 			}
 		    }
@@ -934,7 +933,7 @@ op(int what)
 	push(((a.type & MN_FLOAT) ? a.u.d : a.u.l) ? b : c, NULL, 0);
 	break;
     case COLON:
-	zerr("':' without '?'", NULL, 0);
+	zerr("':' without '?'");
 	break;
     case PREPLUS:
 	if (spval->type & MN_FLOAT)
@@ -951,7 +950,7 @@ op(int what)
 	setvar(stack[sp].lval, *spval);
 	break;
     default:
-	zerr("out of integers", NULL, 0);
+	zerr("out of integers");
 	return;
     }
 }
@@ -999,7 +998,7 @@ mathevall(char *s, int prek, char **ep)
 	xyyval.type = MN_INTEGER;
 	xyyval.u.l = 0;
 
-	zerr("math recursion limit exceeded", NULL, 0);
+	zerr("math recursion limit exceeded");
 
 	return xyyval;
     }
@@ -1076,7 +1075,7 @@ matheval(char *s)
     x = mathevall(s, TOPPREC, &junk);
     mtok = xmtok;
     if (*junk)
-	zerr("bad math expression: illegal character: %c", NULL, *junk);
+	zerr("bad math expression: illegal character: %c", *junk);
     return x;
 }
 
@@ -1122,7 +1121,6 @@ checkunary(int mtokc, char *mptr)
 	    errmsg = 2;
     }
     if (errmsg) {
-	char errbuf[80];
 	int len, over = 0;
 	while (inblank(*mptr))
 	    mptr++;
@@ -1131,10 +1129,9 @@ checkunary(int mtokc, char *mptr)
 	    len = 10;
 	    over = 1;
 	}
-	sprintf(errbuf, "bad math expression: %s expected at `%%l%s'",
-		errmsg == 2 ? "operator" : "operand",
-		over ? "..." : ""); 
-	zerr(errbuf, mptr, len);
+	zerr("bad math expression: %s expected at `%l%s'",
+	     errmsg == 2 ? "operator" : "operand",
+	     mptr, len, over ? "..." : "");
     }
     unary = !(tp & OP_OPF);
 }
@@ -1176,7 +1173,7 @@ mathparse(int pc)
 	    mathparse(TOPPREC);
 	    if (mtok != M_OUTPAR) {
 		if (!errflag)
-		    zerr("')' expected", NULL, 0);
+		    zerr("')' expected");
 		return;
 	    }
 	    break;
@@ -1193,7 +1190,7 @@ mathparse(int pc)
 		noeval--;
 	    if (mtok != COLON) {
 		if (!errflag)
-		    zerr("':' expected", NULL, 0);
+		    zerr("':' expected");
 		return;
 	    }
 	    if (q)
diff --git a/Src/mem.c b/Src/mem.c
index bcdd1efe9..afc008cd7 100644
--- a/Src/mem.c
+++ b/Src/mem.c
@@ -321,7 +321,7 @@ mmap_heap_alloc(size_t *n)
     h = (Heap) mmap(NULL, *n, PROT_READ | PROT_WRITE,
 		    MMAP_FLAGS, -1, 0);
     if (h == ((Heap) -1)) {
-	zerr("fatal error: out of heap memory", NULL, 0);
+	zerr("fatal error: out of heap memory");
 	exit(1);
     }
 
@@ -581,7 +581,7 @@ zalloc(size_t size)
 	size = 1;
     queue_signals();
     if (!(ptr = (void *) malloc(size))) {
-	zerr("fatal error: out of memory", NULL, 0);
+	zerr("fatal error: out of memory");
 	exit(1);
     }
     unqueue_signals();
@@ -599,7 +599,7 @@ zshcalloc(size_t size)
 	size = 1;
     queue_signals();
     if (!(ptr = (void *) malloc(size))) {
-	zerr("fatal error: out of memory", NULL, 0);
+	zerr("fatal error: out of memory");
 	exit(1);
     }
     unqueue_signals();
@@ -623,7 +623,7 @@ zrealloc(void *ptr, size_t size)
 	if (size) {
 	    /* Do normal realloc */
 	    if (!(ptr = (void *) realloc(ptr, size))) {
-		zerr("fatal error: out of memory", NULL, 0);
+		zerr("fatal error: out of memory");
 		exit(1);
 	    }
 	    unqueue_signals();
diff --git a/Src/modentry.c b/Src/modentry.c
index 63c4b825d..87c89e0d7 100644
--- a/Src/modentry.c
+++ b/Src/modentry.c
@@ -1,15 +1,35 @@
 #include "zsh.mdh"
 
+int setup_ _((Module));
 int boot_ _((Module));
 int cleanup_ _((Module));
+int finish_ _((Module));
 int modentry _((int boot, Module m));
 
 /**/
 int
 modentry(int boot, Module m)
 {
-    if (boot)
+    switch (boot) {
+    case 0:
+	return setup_(m);
+	break;
+
+    case 1:
 	return boot_(m);
-    else
+	break;
+
+    case 2:
 	return cleanup_(m);
+	break;
+
+    case 3:
+	return finish_(m);
+	break;
+
+    default:
+	zerr("bad call to modentry");
+	return 1;
+	break;
+    }
 }
diff --git a/Src/module.c b/Src/module.c
index de3fd9932..fde78ac1d 100644
--- a/Src/module.c
+++ b/Src/module.c
@@ -161,7 +161,7 @@ addbuiltins(char const *nam, Builtin binl, int size)
 	if(b->node.flags & BINF_ADDED)
 	    continue;
 	if(addbuiltin(b)) {
-	    zwarnnam(nam, "name clash when adding builtin `%s'", b->node.nam, 0);
+	    zwarnnam(nam, "name clash when adding builtin `%s'", b->node.nam);
 	    hadf = 1;
 	} else {
 	    b->node.flags |= BINF_ADDED;
@@ -268,7 +268,7 @@ deletebuiltins(char const *nam, Builtin binl, int size)
 	if(!(b->node.flags & BINF_ADDED))
 	    continue;
 	if(deletebuiltin(b->node.nam)) {
-	    zwarnnam(nam, "builtin `%s' already deleted", b->node.nam, 0);
+	    zwarnnam(nam, "builtin `%s' already deleted", b->node.nam);
 	    hadf = 1;
 	} else
 	    hads = 2;
@@ -441,7 +441,7 @@ do_load_module(char const *name, int silent)
     ret = try_load_module(name);
     if (!ret && !silent) {
 	int waserr = errflag;
-	zerr("failed to load module: %s", name, 0);
+	zerr("failed to load module: %s", name);
 	errflag = waserr;
     }
     return ret;
@@ -457,7 +457,7 @@ do_load_module(char const *name, int silent)
     int waserr = errflag;
 
     if (!silent)
-	zerr("failed to load module: %s", name, 0);
+	zerr("failed to load module: %s", name);
     errflag = waserr;
 
     return NULL;
@@ -612,7 +612,7 @@ dyn_setup_module(Module m)
 
     if (fn)
 	return fn(m);
-    zwarnnam(m->nam, "no setup function", NULL, 0);
+    zwarnnam(m->nam, "no setup function");
     return 1;
 }
 
@@ -624,7 +624,7 @@ dyn_boot_module(Module m)
 
     if(fn)
 	return fn(m);
-    zwarnnam(m->nam, "no boot function", NULL, 0);
+    zwarnnam(m->nam, "no boot function");
     return 1;
 }
 
@@ -636,7 +636,7 @@ dyn_cleanup_module(Module m)
 
     if(fn)
 	return fn(m);
-    zwarnnam(m->nam, "no cleanup function", NULL, 0);
+    zwarnnam(m->nam, "no cleanup function");
     return 1;
 }
 
@@ -653,7 +653,7 @@ dyn_finish_module(Module m)
     if (fn)
 	r = fn(m);
     else {
-	zwarnnam(m->nam, "no finish function", NULL, 0);
+	zwarnnam(m->nam, "no finish function");
 	r = 1;
     }
     dlclose(m->u.handle);
@@ -764,7 +764,7 @@ load_module_silence(char const *name, int silent)
 
     if (!modname_ok(name)) {
 	if (!silent)
-	    zerr("invalid module name `%s'", name, 0);
+	    zerr("invalid module name `%s'", name);
 	return 0;
     }
     /*
@@ -814,7 +814,7 @@ load_module_silence(char const *name, int silent)
 	return 1;
     }
     if (m->flags & MOD_BUSY) {
-	zerr("circular dependencies for module %s", name, 0);
+	zerr("circular dependencies for module %s", name);
 	return 0;
     }
     m->flags |= MOD_BUSY;
@@ -891,7 +891,7 @@ require_module(char *nam, const char *module, UNUSED(int res), int test)
 	!(m->flags & MOD_UNLOAD)) {
 	if (test) {
 	    unqueue_signals();
-	    zwarnnam(nam, "module %s already loaded.", module, 0);
+	    zwarnnam(nam, "module %s already loaded.", module);
 	    return 0;
 	}
     } else
@@ -973,31 +973,30 @@ bin_zmodload(char *nam, char **args, Options ops, UNUSED(int func))
     int ret = 1;
 
     if (ops_bcpf && !ops_au) {
-	zwarnnam(nam, "-b, -c, -f, and -p must be combined with -a or -u",
-		 NULL, 0);
+	zwarnnam(nam, "-b, -c, -f, and -p must be combined with -a or -u");
 	return 1;
     }
     if (OPT_ISSET(ops,'A') || OPT_ISSET(ops,'R')) {
 	if (ops_bcpf || ops_au || OPT_ISSET(ops,'d') || 
 	    (OPT_ISSET(ops,'R') && OPT_ISSET(ops,'e'))) {
-	    zwarnnam(nam, "illegal flags combined with -A or -R", NULL, 0);
+	    zwarnnam(nam, "illegal flags combined with -A or -R");
 	    return 1;
 	}
 	if (!OPT_ISSET(ops,'e'))
 	    return bin_zmodload_alias(nam, args, ops);
     }
     if (OPT_ISSET(ops,'d') && OPT_ISSET(ops,'a')) {
-	zwarnnam(nam, "-d cannot be combined with -a", NULL, 0);
+	zwarnnam(nam, "-d cannot be combined with -a");
 	return 1;
     }
     if (OPT_ISSET(ops,'u') && !*args) {
-	zwarnnam(nam, "what do you want to unload?", NULL, 0);
+	zwarnnam(nam, "what do you want to unload?");
 	return 1;
     }
     if (OPT_ISSET(ops,'e') && (OPT_ISSET(ops,'I') || OPT_ISSET(ops,'L') || 
 			       OPT_ISSET(ops,'a') || OPT_ISSET(ops,'d') ||
 			       OPT_ISSET(ops,'i') || OPT_ISSET(ops,'u'))) {
-	zwarnnam(nam, "-e cannot be combined with other options", NULL, 0);
+	zwarnnam(nam, "-e cannot be combined with other options");
 	return 1;
     }
     queue_signals();
@@ -1018,7 +1017,7 @@ bin_zmodload(char *nam, char **args, Options ops, UNUSED(int func))
 	       OPT_ISSET(ops,'c') || OPT_ISSET(ops,'p')))
 	ret = bin_zmodload_load(nam, args, ops);
     else
-	zwarnnam(nam, "use only one of -b, -c, or -p", NULL, 0);
+	zwarnnam(nam, "use only one of -b, -c, or -p");
     unqueue_signals();
 
     return ret;
@@ -1046,7 +1045,7 @@ bin_zmodload_alias(char *nam, char **args, Options ops)
 
     if (!*args) {
 	if (OPT_ISSET(ops,'R')) {
-	    zwarnnam(nam, "no module alias to remove", NULL, 0);
+	    zwarnnam(nam, "no module alias to remove");
 	    return 1;
 	}
 	for (node = firstnode(modules); node; incnode(node)) {
@@ -1063,38 +1062,38 @@ bin_zmodload_alias(char *nam, char **args, Options ops)
 	if (eqpos)
 	    *eqpos = '\0';
 	if (!modname_ok(*args)) {
-	    zwarnnam(nam, "invalid module name `%s'", *args, 0);
+	    zwarnnam(nam, "invalid module name `%s'", *args);
 	    return 1;
 	}
 	if (OPT_ISSET(ops,'R')) {
 	    if (aliasname) {
 		zwarnnam(nam, "bad syntax for removing module alias: %s",
-			 *args, 0);
+			 *args);
 		return 1;
 	    }
 	    node = find_module(*args, 0, NULL);
 	    if (node) {
 		m = (Module) getdata(node);
 		if (!(m->flags & MOD_ALIAS)) {
-		    zwarnnam(nam, "module is not an alias: %s", *args, 0);
+		    zwarnnam(nam, "module is not an alias: %s", *args);
 		    return 1;
 		}
 		delete_module(node);
 	    } else {
-		zwarnnam(nam, "no such module alias: %s", *args, 0);
+		zwarnnam(nam, "no such module alias: %s", *args);
 		return 1;
 	    }
 	} else {
 	    if (aliasname) {
 		const char *mname = aliasname;
 		if (!modname_ok(aliasname)) {
-		    zwarnnam(nam, "invalid module name `%s'", aliasname, 0);
+		    zwarnnam(nam, "invalid module name `%s'", aliasname);
 		    return 1;
 		}
 		do {
 		    if (!strcmp(mname, *args)) {
 			zwarnnam(nam, "module alias would refer to itself: %s",
-				 *args, 0);
+				 *args);
 			return 1;
 		    }
 		} while ((node = find_module(mname, 0, NULL))
@@ -1104,7 +1103,7 @@ bin_zmodload_alias(char *nam, char **args, Options ops)
 		if (node) {
 		    m = (Module) getdata(node);
 		    if (!(m->flags & MOD_ALIAS)) {
-			zwarnnam(nam, "module is not an alias: %s", *args, 0);
+			zwarnnam(nam, "module is not an alias: %s", *args);
 			return 1;
 		    }
 		    zsfree(m->u.alias);
@@ -1121,12 +1120,11 @@ bin_zmodload_alias(char *nam, char **args, Options ops)
 		    if (m->flags & MOD_ALIAS)
 			printmodalias(m, ops);
 		    else {
-			zwarnnam(nam, "module is not an alias: %s",
-				 *args, 0);
+			zwarnnam(nam, "module is not an alias: %s", *args);
 			return 1;
 		    }
 		} else {
-		    zwarnnam(nam, "no such module alias: %s", *args, 0);
+		    zwarnnam(nam, "no such module alias: %s", *args);
 		    return 1;
 		}
 	    }
@@ -1259,11 +1257,11 @@ bin_zmodload_auto(char *nam, char **args, Options ops)
 	    Builtin bn = (Builtin) builtintab->getnode2(builtintab, *args);
 	    if (!bn) {
 		if(!OPT_ISSET(ops,'i')) {
-		    zwarnnam(nam, "%s: no such builtin", *args, 0);
+		    zwarnnam(nam, "%s: no such builtin", *args);
 		    ret = 1;
 		}
 	    } else if (bn->node.flags & BINF_ADDED) {
-		zwarnnam(nam, "%s: builtin is already defined", *args, 0);
+		zwarnnam(nam, "%s: builtin is already defined", *args);
 		ret = 1;
 	    } else
 		deletebuiltin(*args);
@@ -1281,10 +1279,10 @@ bin_zmodload_auto(char *nam, char **args, Options ops)
 	do {
 	    char *bnam = *args ? *args++ : modnam;
 	    if (strchr(bnam, '/')) {
-		zwarnnam(nam, "%s: `/' is illegal in a builtin", bnam, 0);
+		zwarnnam(nam, "%s: `/' is illegal in a builtin", bnam);
 		ret = 1;
 	    } else if (add_autobin(bnam, modnam) && !OPT_ISSET(ops,'i')) {
-		zwarnnam(nam, "failed to add builtin %s", bnam, 0);
+		zwarnnam(nam, "failed to add builtin %s", bnam);
 		ret = 1;
 	    }
 	} while(*args);
@@ -1305,11 +1303,11 @@ bin_zmodload_cond(char *nam, char **args, Options ops)
 
 	    if (!cd) {
 		if (!OPT_ISSET(ops,'i')) {
-		    zwarnnam(nam, "%s: no such condition", *args, 0);
+		    zwarnnam(nam, "%s: no such condition", *args);
 		    ret = 1;
 		}
 	    } else if (cd->flags & CONDF_ADDED) {
-		zwarnnam(nam, "%s: condition is already defined", *args, 0);
+		zwarnnam(nam, "%s: condition is already defined", *args);
 		ret = 1;
 	    } else
 		deleteconddef(cd);
@@ -1344,11 +1342,11 @@ bin_zmodload_cond(char *nam, char **args, Options ops)
 	do {
 	    char *cnam = *args ? *args++ : modnam;
 	    if (strchr(cnam, '/')) {
-		zwarnnam(nam, "%s: `/' is illegal in a condition", cnam, 0);
+		zwarnnam(nam, "%s: `/' is illegal in a condition", cnam);
 		ret = 1;
 	    } else if (add_autocond(cnam, OPT_ISSET(ops,'I'), modnam) &&
 		       !OPT_ISSET(ops,'i')) {
-		zwarnnam(nam, "failed to add condition `%s'", cnam, 0);
+		zwarnnam(nam, "failed to add condition `%s'", cnam);
 		ret = 1;
 	    }
 	} while(*args);
@@ -1369,11 +1367,11 @@ bin_zmodload_math(char *nam, char **args, Options ops)
 
 	    if (!f) {
 		if (!OPT_ISSET(ops,'i')) {
-		    zwarnnam(nam, "%s: no such math function", *args, 0);
+		    zwarnnam(nam, "%s: no such math function", *args);
 		    ret = 1;
 		}
 	    } else if (f->flags & MFF_ADDED) {
-		zwarnnam(nam, "%s: math function is already defined", *args, 0);
+		zwarnnam(nam, "%s: math function is already defined", *args);
 		ret = 1;
 	    } else
 		deletemathfunc(f);
@@ -1401,11 +1399,10 @@ bin_zmodload_math(char *nam, char **args, Options ops)
 	do {
 	    char *fnam = *args ? *args++ : modnam;
 	    if (strchr(fnam, '/')) {
-		zwarnnam(nam, "%s: `/' is illegal in a math function",
-			 fnam, 0);
+		zwarnnam(nam, "%s: `/' is illegal in a math function", fnam);
 		ret = 1;
 	    } else if (add_automathfunc(fnam, modnam) && !OPT_ISSET(ops,'i')) {
-		zwarnnam(nam, "failed to add math function `%s'", fnam, 0);
+		zwarnnam(nam, "failed to add math function `%s'", fnam);
 		ret = 1;
 	    }
 	} while(*args);
@@ -1439,11 +1436,11 @@ bin_zmodload_param(char *nam, char **args, Options ops)
 
 	    if (!pm) {
 		if (!OPT_ISSET(ops,'i')) {
-		    zwarnnam(nam, "%s: no such parameter", *args, 0);
+		    zwarnnam(nam, "%s: no such parameter", *args);
 		    ret = 1;
 		}
 	    } else if (!(pm->node.flags & PM_AUTOLOAD)) {
-		zwarnnam(nam, "%s: parameter is already defined", *args, 0);
+		zwarnnam(nam, "%s: parameter is already defined", *args);
 		ret = 1;
 	    } else
 		unsetparam_pm(pm, 0, 1);
@@ -1460,7 +1457,7 @@ bin_zmodload_param(char *nam, char **args, Options ops)
 	do {
 	    char *pnam = *args ? *args++ : modnam;
 	    if (strchr(pnam, '/')) {
-		zwarnnam(nam, "%s: `/' is illegal in a parameter", pnam, 0);
+		zwarnnam(nam, "%s: `/' is illegal in a parameter", pnam);
 		ret = 1;
 	    } else
 		add_autoparam(pnam, modnam);
@@ -1582,7 +1579,7 @@ unload_named_module(char *modname, char *nam, int silent)
 			if (m->flags & MOD_UNLOAD)
 			    del = 1;
 			else {
-			    zwarnnam(nam, "module %s is in use by another module and cannot be unloaded", mname, 0);
+			    zwarnnam(nam, "module %s is in use by another module and cannot be unloaded", mname);
 			    return 1;
 			}
 		    }
@@ -1595,7 +1592,7 @@ unload_named_module(char *modname, char *nam, int silent)
 	if (del)
 	    m->wrapper--;
     } else if (!silent) {
-	zwarnnam(nam, "no such module %s", modname, 0);
+	zwarnnam(nam, "no such module %s", modname);
 	ret = 1;
     }
 
@@ -1718,7 +1715,7 @@ addconddefs(char const *nam, Conddef c, int size)
 	    continue;
 	}
 	if (addconddef(c)) {
-	    zwarnnam(nam, "name clash when adding condition `%s'", c->name, 0);
+	    zwarnnam(nam, "name clash when adding condition `%s'", c->name);
 	    hadf = 1;
 	} else {
 	    c->flags |= CONDF_ADDED;
@@ -1775,7 +1772,7 @@ addhookdefs(char const *nam, Hookdef h, int size)
 
     while (size--) {
 	if (addhookdef(h)) {
-	    zwarnnam(nam, "name clash when adding hook `%s'", h->name, 0);
+	    zwarnnam(nam, "name clash when adding hook `%s'", h->name);
 	    hadf = 1;
 	} else
 	    hads = 2;
@@ -1957,7 +1954,7 @@ addparamdefs(char const *nam, Paramdef d, int size)
 
     while (size--) {
 	if (addparamdef(d)) {
-	    zwarnnam(nam, "error when adding parameter `%s'", d->name, 0);
+	    zwarnnam(nam, "error when adding parameter `%s'", d->name);
 	    hadf = 1;
 	} else
 	    hads = 2;
@@ -2051,7 +2048,7 @@ deleteconddefs(char const *nam, Conddef c, int size)
 	    continue;
 	}
 	if (deleteconddef(c)) {
-	    zwarnnam(nam, "condition `%s' already deleted", c->name, 0);
+	    zwarnnam(nam, "condition `%s' already deleted", c->name);
 	    hadf = 1;
 	} else
 	    hads = 2;
@@ -2162,7 +2159,7 @@ addmathfuncs(char const *nam, MathFunc f, int size)
 	}
 	if (addmathfunc(f)) {
 	    zwarnnam(nam, "name clash when adding math function `%s'",
-		     f->name, 0);
+		     f->name);
 	    hadf = 1;
 	} else
 	    hads = 2;
@@ -2232,8 +2229,7 @@ deletemathfuncs(char const *nam, MathFunc f, int size)
 	    continue;
 	}
 	if (deletemathfunc(f)) {
-	    zwarnnam(nam, "math function `%s' already deleted",
-		     f->name, 0);
+	    zwarnnam(nam, "math function `%s' already deleted", f->name);
 	    hadf = 1;
 	} else
 	    hads = 2;
diff --git a/Src/options.c b/Src/options.c
index bf989adf5..6c3fb26d1 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -517,22 +517,22 @@ bin_setopt(char *nam, char **args, UNUSED(Options ops), int isun)
 		if (!*++*args)
 		    args++;
 		if (!*args) {
-		    zwarnnam(nam, "string expected after -o", NULL, 0);
+		    zwarnnam(nam, "string expected after -o");
 		    inittyptab();
 		    return 1;
 		}
 		if(!(optno = optlookup(*args)))
-		    zwarnnam(nam, "no such option: %s", *args, 0);
+		    zwarnnam(nam, "no such option: %s", *args);
 		else if(dosetopt(optno, action, 0))
-		    zwarnnam(nam, "can't change option: %s", *args, 0);
+		    zwarnnam(nam, "can't change option: %s", *args);
 		break;
 	    } else if(**args == 'm') {
 		match = 1;
 	    } else {
 	    	if (!(optno = optlookupc(**args)))
-		    zwarnnam(nam, "bad option: -%c", NULL, **args);
+		    zwarnnam(nam, "bad option: -%c", **args);
 		else if(dosetopt(optno, action, 0))
-		    zwarnnam(nam, "can't change option: -%c", NULL, **args);
+		    zwarnnam(nam, "can't change option: -%c", **args);
 	    }
 	}
 	args++;
@@ -543,9 +543,9 @@ bin_setopt(char *nam, char **args, UNUSED(Options ops), int isun)
 	/* Not globbing the arguments -- arguments are simply option names. */
 	while (*args) {
 	    if(!(optno = optlookup(*args++)))
-		zwarnnam(nam, "no such option: %s", args[-1], 0);
+		zwarnnam(nam, "no such option: %s", args[-1]);
 	    else if(dosetopt(optno, !isun, 0))
-		zwarnnam(nam, "can't change option: %s", args[-1], 0);
+		zwarnnam(nam, "can't change option: %s", args[-1]);
 	}
     } else {
 	/* Globbing option (-m) set. */
@@ -565,7 +565,7 @@ bin_setopt(char *nam, char **args, UNUSED(Options ops), int isun)
 	    /* Expand the current arg. */
 	    tokenize(s);
 	    if (!(pprog = patcompile(s, PAT_STATIC, NULL))) {
-		zwarnnam(nam, "bad pattern: %s", *args, 0);
+		zwarnnam(nam, "bad pattern: %s", *args);
 		continue;
 	    }
 	    /* Loop over expansions. */
diff --git a/Src/params.c b/Src/params.c
index e2550fbf1..6965df0ed 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -424,7 +424,7 @@ getparamnode(HashTable ht, char *nam)
 	hn = gethashnode2(ht, nam);
 	if (((Param) hn) == pm && (pm->node.flags & PM_AUTOLOAD)) {
 	    pm->node.flags &= ~PM_AUTOLOAD;
-	    zwarnnam(nam, "autoload failed", NULL, 0);
+	    zwarnnam(nam, "autoload failed");
 	}
     }
     return hn;
@@ -799,7 +799,7 @@ createparam(char *name, int flags)
 		return NULL;
 	    }
 	    if ((oldpm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-		zerr("%s: restricted", name, 0);
+		zerr("%s: restricted", name);
 		return NULL;
 	    }
 
@@ -1325,7 +1325,7 @@ getindex(char **pptr, Value v, int dq)
     if (*tbrack)
 	*tbrack = Outbrack;
     else {
-	zerr("invalid subscript", NULL, 0);
+	zerr("invalid subscript");
 	*pptr = tbrack;
 	return 1;
     }
@@ -1361,7 +1361,7 @@ getindex(char **pptr, Value v, int dq)
 		v->end = start + 1;
 	    }
 	    if (*s == ',') {
-		zerr("invalid subscript", NULL, 0);
+		zerr("invalid subscript");
 		*tbrack = ']';
 		*pptr = tbrack+1;
 		return 1;
@@ -1697,17 +1697,17 @@ mod_export void
 setstrvalue(Value v, char *val)
 {
     if (v->pm->node.flags & PM_READONLY) {
-	zerr("read-only variable: %s", v->pm->node.nam, 0);
+	zerr("read-only variable: %s", v->pm->node.nam);
 	zsfree(val);
 	return;
     }
     if ((v->pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	zerr("%s: restricted", v->pm->node.nam, 0);
+	zerr("%s: restricted", v->pm->node.nam);
 	zsfree(val);
 	return;
     }
     if ((v->pm->node.flags & PM_HASHED) && (v->isarr & SCANPM_MATCHMANY)) {
-	zerr("%s: attempt to set slice of associative array", v->pm->node.nam, 0);
+	zerr("%s: attempt to set slice of associative array", v->pm->node.nam);
 	zsfree(val);
 	return;
     }
@@ -1798,11 +1798,11 @@ setnumvalue(Value v, mnumber val)
     char buf[BDIGBUFSIZE], *p;
 
     if (v->pm->node.flags & PM_READONLY) {
-	zerr("read-only variable: %s", v->pm->node.nam, 0);
+	zerr("read-only variable: %s", v->pm->node.nam);
 	return;
     }
     if ((v->pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	zerr("%s: restricted", v->pm->node.nam, 0);
+	zerr("%s: restricted", v->pm->node.nam);
 	return;
     }
     switch (PM_TYPE(v->pm->node.flags)) {
@@ -1835,19 +1835,19 @@ mod_export void
 setarrvalue(Value v, char **val)
 {
     if (v->pm->node.flags & PM_READONLY) {
-	zerr("read-only variable: %s", v->pm->node.nam, 0);
+	zerr("read-only variable: %s", v->pm->node.nam);
 	freearray(val);
 	return;
     }
     if ((v->pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	zerr("%s: restricted", v->pm->node.nam, 0);
+	zerr("%s: restricted", v->pm->node.nam);
 	freearray(val);
 	return;
     }
     if (!(PM_TYPE(v->pm->node.flags) & (PM_ARRAY|PM_HASHED))) {
 	freearray(val);
 	zerr("%s: attempt to assign array value to non-array",
-	     v->pm->node.nam, 0);
+	     v->pm->node.nam);
 	return;
     }
     if (v->start == 0 && v->end == -1) {
@@ -1865,7 +1865,7 @@ setarrvalue(Value v, char **val)
 	if ((PM_TYPE(v->pm->node.flags) == PM_HASHED)) {
 	    freearray(val);
 	    zerr("%s: attempt to set slice of associative array",
-		 v->pm->node.nam, 0);
+		 v->pm->node.nam);
 	    return;
 	}
 	if (v->inv && unset(KSHARRAYS)) {
@@ -2012,7 +2012,7 @@ assignsparam(char *s, char *val, int flags)
     int sstart;
 
     if (!isident(s)) {
-	zerr("not an identifier: %s", s, 0);
+	zerr("not an identifier: %s", s);
 	zsfree(val);
 	errflag = 1;
 	return NULL;
@@ -2047,7 +2047,7 @@ assignsparam(char *s, char *val, int flags)
     }
     if ((flags & ASSPM_WARN_CREATE) && v->pm->level == 0)
 	zwarn("scalar parameter %s created globally in function",
-	      v->pm->node.nam, 0);
+	      v->pm->node.nam);
     if (flags & ASSPM_AUGMENT) {
 	if (v->start == 0 && v->end == -1) {
 	    switch (PM_TYPE(v->pm->node.flags)) {
@@ -2098,8 +2098,7 @@ assignsparam(char *s, char *val, int flags)
 	    case PM_EFLOAT:
 	    case PM_FFLOAT:
 		unqueue_signals();
-		zerr("attempt to add to slice of a numeric variable",
-		    NULL, 0);
+		zerr("attempt to add to slice of a numeric variable");
 		zsfree(val);
 		return NULL;
 	    case PM_ARRAY:
@@ -2135,7 +2134,7 @@ assignaparam(char *s, char **val, int flags)
     char *ss;
 
     if (!isident(s)) {
-	zerr("not an identifier: %s", s, 0);
+	zerr("not an identifier: %s", s);
 	freearray(val);
 	errflag = 1;
 	return NULL;
@@ -2151,7 +2150,7 @@ assignaparam(char *s, char **val, int flags)
 	if (v && PM_TYPE(v->pm->node.flags) == PM_HASHED) {
 	    unqueue_signals();
 	    zerr("%s: attempt to set slice of associative array",
-		 v->pm->node.nam, 0);
+		 v->pm->node.nam);
 	    freearray(val);
 	    errflag = 1;
 	    return NULL;
@@ -2190,7 +2189,7 @@ assignaparam(char *s, char **val, int flags)
 
     if ((flags & ASSPM_WARN_CREATE) && v->pm->level == 0)
 	zwarn("array parameter %s created globally in function",
-	      v->pm->node.nam, 0);
+	      v->pm->node.nam);
     if (flags & ASSPM_AUGMENT) {
     	if (v->start == 0 && v->end == -1) {
 	    if (PM_TYPE(v->pm->node.flags) & PM_ARRAY) {
@@ -2222,14 +2221,14 @@ sethparam(char *s, char **val)
     char *t = s;
 
     if (!isident(s)) {
-	zerr("not an identifier: %s", s, 0);
+	zerr("not an identifier: %s", s);
 	freearray(val);
 	errflag = 1;
 	return NULL;
     }
     if (strchr(s, '[')) {
 	freearray(val);
-	zerr("nested associative arrays not yet supported", NULL, 0);
+	zerr("nested associative arrays not yet supported");
 	errflag = 1;
 	return NULL;
     }
@@ -2263,7 +2262,7 @@ setiparam(char *s, zlong val)
     mnumber mnval;
 
     if (!isident(s)) {
-	zerr("not an identifier: %s", s, 0);
+	zerr("not an identifier: %s", s);
 	errflag = 1;
 	return NULL;
     }
@@ -2304,7 +2303,7 @@ setnparam(char *s, mnumber val)
     Param pm;
 
     if (!isident(s)) {
-	zerr("not an identifier: %s", s, 0);
+	zerr("not an identifier: %s", s);
 	errflag = 1;
 	return NULL;
     }
@@ -2356,11 +2355,11 @@ unsetparam_pm(Param pm, int altflag, int exp)
     char *altremove;
 
     if ((pm->node.flags & PM_READONLY) && pm->level <= locallevel) {
-	zerr("read-only variable: %s", pm->node.nam, 0);
+	zerr("read-only variable: %s", pm->node.nam);
 	return 1;
     }
     if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	zerr("%s: restricted", pm->node.nam, 0);
+	zerr("%s: restricted", pm->node.nam);
 	return 1;
     }
 
@@ -2602,8 +2601,7 @@ arrhashsetfn(Param pm, char **val, int augment)
 
     if (alen % 2) {
 	freearray(val);
-	zerr("bad set of key/value pairs for associative array",
-	     NULL, 0);
+	zerr("bad set of key/value pairs for associative array");
 	return;
     }
     if (alen)
@@ -2936,7 +2934,7 @@ intsecondssetfn(UNUSED(Param pm), zlong x)
     diff = (zlong)now.tv_sec - x;
     shtimer.tv_sec = diff;
     if ((zlong)shtimer.tv_sec != diff)
-	zwarn("SECONDS truncated on assignment", NULL, 0);
+	zwarn("SECONDS truncated on assignment");
     shtimer.tv_usec = 0;
 }
 
@@ -3272,7 +3270,7 @@ errnosetfn(UNUSED(Param pm), zlong x)
 {
     errno = (int)x;
     if ((zlong)errno != x)
-	zwarn("errno truncated on assignment", NULL, 0);
+	zwarn("errno truncated on assignment");
 }
 
 /* Function to get value for special parameter `ERRNO' */
diff --git a/Src/parse.c b/Src/parse.c
index a45231d15..d436eef18 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -72,7 +72,7 @@ struct heredocs *hdocs;
 #define YYERROR(O)  { tok = LEXERR; ecused = (O); return 0; }
 #define YYERRORV(O) { tok = LEXERR; ecused = (O); return; }
 #define COND_ERROR(X,Y) do { \
-  zwarn(X,Y,0); \
+  zwarn(X,Y); \
   herrflush(); \
   if (noerrs != 2) \
     errflag = 1; \
@@ -2180,7 +2180,7 @@ yyerror(int noerr)
     else if (t0)
 	zwarn("parse error near `%l'", t, t0);
     else
-	zwarn("parse error", NULL, 0);
+	zwarn("parse error");
     if (!noerr && noerrs != 2)
 	errflag = 1;
 }
@@ -2538,11 +2538,11 @@ bin_zcompile(char *nam, char **args, Options ops, UNUSED(int func))
 	(OPT_ISSET(ops,'c') &&
 	 (OPT_ISSET(ops,'U') || OPT_ISSET(ops,'k') || OPT_ISSET(ops,'z'))) ||
 	(!(OPT_ISSET(ops,'c') || OPT_ISSET(ops,'a')) && OPT_ISSET(ops,'m'))) {
-	zwarnnam(nam, "illegal combination of options", NULL, 0);
+	zwarnnam(nam, "illegal combination of options");
 	return 1;
     }
     if ((OPT_ISSET(ops,'c') || OPT_ISSET(ops,'a')) && isset(KSHAUTOLOAD))
-	zwarnnam(nam, "functions will use zsh style autoloading", NULL, 0);
+	zwarnnam(nam, "functions will use zsh style autoloading");
 
     flags = (OPT_ISSET(ops,'k') ? FDHF_KSHLOAD :
 	     (OPT_ISSET(ops,'z') ? FDHF_ZSHLOAD : 0));
@@ -2551,7 +2551,7 @@ bin_zcompile(char *nam, char **args, Options ops, UNUSED(int func))
 	Wordcode f;
 
 	if (!*args) {
-	    zwarnnam(nam, "too few arguments", NULL, 0);
+	    zwarnnam(nam, "too few arguments");
 	    return 1;
 	}
 	if (!(f = load_dump_header(nam, (strsfx(FD_EXT, *args) ? *args :
@@ -2574,7 +2574,7 @@ bin_zcompile(char *nam, char **args, Options ops, UNUSED(int func))
 	}
     }
     if (!*args) {
-	zwarnnam(nam, "too few arguments", NULL, 0);
+	zwarnnam(nam, "too few arguments");
 	return 1;
     }
     map = (OPT_ISSET(ops,'M') ? 2 : (OPT_ISSET(ops,'R') ? 0 : 1));
@@ -2611,7 +2611,7 @@ load_dump_header(char *nam, char *name, int err)
 
     if ((fd = open(name, O_RDONLY)) < 0) {
 	if (err)
-	    zwarnnam(nam, "can't open zwc file: %s", name, 0);
+	    zwarnnam(nam, "can't open zwc file: %s", name);
 	return NULL;
     }
     if (read(fd, buf, (FD_PRELEN + 1) * sizeof(wordcode)) !=
@@ -2619,13 +2619,10 @@ load_dump_header(char *nam, char *name, int err)
 	(v = (fdmagic(buf) != FD_MAGIC && fdmagic(buf) != FD_OMAGIC))) {
 	if (err) {
 	    if (v) {
-		char msg[80];
-
-		sprintf(msg, "zwc file has wrong version (zsh-%s): %%s",
-			fdversion(buf));
-		zwarnnam(nam, msg , name, 0);
+		zwarnnam(nam, "zwc file has wrong version (zsh-%s): %s",
+			 fdversion(buf), name);
 	    } else
-		zwarnnam(nam, "invalid zwc file: %s" , name, 0);
+		zwarnnam(nam, "invalid zwc file: %s" , name);
 	}
 	close(fd);
 	return NULL;
@@ -2643,7 +2640,7 @@ load_dump_header(char *nam, char *name, int err)
 	    if (lseek(fd, o, 0) == -1 ||
 		read(fd, buf, (FD_PRELEN + 1) * sizeof(wordcode)) !=
 		((FD_PRELEN + 1) * sizeof(wordcode))) {
-		zwarnnam(nam, "invalid zwc file: %s" , name, 0);
+		zwarnnam(nam, "invalid zwc file: %s" , name);
 		close(fd);
 		return NULL;
 	    }
@@ -2655,7 +2652,7 @@ load_dump_header(char *nam, char *name, int err)
 	len -= (FD_PRELEN + 1) * sizeof(wordcode);
 	if (read(fd, head + (FD_PRELEN + 1), len) != len) {
 	    close(fd);
-	    zwarnnam(nam, "invalid zwc file: %s" , name, 0);
+	    zwarnnam(nam, "invalid zwc file: %s" , name);
 	    return NULL;
 	}
 	close(fd);
@@ -2756,7 +2753,7 @@ build_dump(char *nam, char *dump, char **files, int ali, int map, int flags)
 
     unlink(dump);
     if ((dfd = open(dump, O_WRONLY|O_CREAT, 0444)) < 0) {
-	zwarnnam(nam, "can't write zwc file: %s", dump, 0);
+	zwarnnam(nam, "can't write zwc file: %s", dump);
 	return 1;
     }
     progs = newlinklist();
@@ -2775,7 +2772,7 @@ build_dump(char *nam, char *dump, char **files, int ali, int map, int flags)
 	    if (fd >= 0)
 		close(fd);
 	    close(dfd);
-	    zwarnnam(nam, "can't open file: %s", *files, 0);
+	    zwarnnam(nam, "can't open file: %s", *files);
 	    noaliases = ona;
 	    unlink(dump);
 	    return 1;
@@ -2787,7 +2784,7 @@ build_dump(char *nam, char *dump, char **files, int ali, int map, int flags)
 	    close(fd);
 	    close(dfd);
 	    zfree(file, flen);
-	    zwarnnam(nam, "can't read file: %s", *files, 0);
+	    zwarnnam(nam, "can't read file: %s", *files);
 	    noaliases = ona;
 	    unlink(dump);
 	    return 1;
@@ -2799,7 +2796,7 @@ build_dump(char *nam, char *dump, char **files, int ali, int map, int flags)
 	    errflag = 0;
 	    close(dfd);
 	    zfree(file, flen);
-	    zwarnnam(nam, "can't read file: %s", *files, 0);
+	    zwarnnam(nam, "can't read file: %s", *files);
 	    noaliases = ona;
 	    unlink(dump);
 	    return 1;
@@ -2840,13 +2837,13 @@ cur_add_func(char *nam, Shfunc shf, LinkList names, LinkList progs,
 	int ona = noaliases;
 
 	if (!(what & 2)) {
-	    zwarnnam(nam, "function is not loaded: %s", shf->node.nam, 0);
+	    zwarnnam(nam, "function is not loaded: %s", shf->node.nam);
 	    return 1;
 	}
 	noaliases = (shf->node.flags & PM_UNALIASED);
 	if (!(prog = getfpfunc(shf->node.nam, NULL)) || prog == &dummy_eprog) {
 	    noaliases = ona;
-	    zwarnnam(nam, "can't load function: %s", shf->node.nam, 0);
+	    zwarnnam(nam, "can't load function: %s", shf->node.nam);
 	    return 1;
 	}
 	if (prog->dump)
@@ -2854,7 +2851,7 @@ cur_add_func(char *nam, Shfunc shf, LinkList names, LinkList progs,
 	noaliases = ona;
     } else {
 	if (!(what & 1)) {
-	    zwarnnam(nam, "function is already loaded: %s", shf->node.nam, 0);
+	    zwarnnam(nam, "function is already loaded: %s", shf->node.nam);
 	    return 1;
 	}
 	prog = dupeprog(shf->funcdef, 1);
@@ -2888,7 +2885,7 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map,
 
     unlink(dump);
     if ((dfd = open(dump, O_WRONLY|O_CREAT, 0444)) < 0) {
-	zwarnnam(nam, "can't write zwc file: %s", dump, 0);
+	zwarnnam(nam, "can't write zwc file: %s", dump);
 	return 1;
     }
     progs = newlinklist();
@@ -2919,7 +2916,7 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map,
 	for (; *names; names++) {
 	    tokenize(pat = dupstring(*names));
 	    if (!(pprog = patcompile(pat, PAT_STATIC, NULL))) {
-		zwarnnam(nam, "bad pattern: %s", *names, 0);
+		zwarnnam(nam, "bad pattern: %s", *names);
 		close(dfd);
 		unlink(dump);
 		return 1;
@@ -2940,7 +2937,7 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map,
 	for (; *names; names++) {
 	    if (errflag ||
 		!(shf = (Shfunc) shfunctab->getnode(shfunctab, *names))) {
-		zwarnnam(nam, "unknown function: %s", *names, 0);
+		zwarnnam(nam, "unknown function: %s", *names);
 		errflag = 0;
 		close(dfd);
 		unlink(dump);
@@ -2955,7 +2952,7 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map,
 	}
     }
     if (empty(progs)) {
-	zwarnnam(nam, "no functions", NULL, 0);
+	zwarnnam(nam, "no functions");
 	errflag = 0;
 	close(dfd);
 	unlink(dump);
diff --git a/Src/signals.c b/Src/signals.c
index 33e298e34..2771c98c2 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -531,7 +531,7 @@ zhandler(int sig)
 	    /* check for WAIT error */
             if (pid == -1) {
                 if (errno != ECHILD)
-                    zerr("wait failed: %e", NULL, errno);
+                    zerr("wait failed: %e", errno);
                 errno = old_errno;    /* WAIT changed errno, so restore the original */
                 break;
             }
@@ -606,7 +606,7 @@ zhandler(int sig)
 		alarm(tmout - idle);
 	    else {
 		errflag = noerrs = 0;
-		zwarn("timeout", NULL, 0);
+		zwarn("timeout");
 		stopmsg = 1;
 		zexit(SIGALRM, 1);
 	    }
@@ -648,7 +648,7 @@ killrunjobs(int from_signal)
                 killed++;
         }
     if (killed)
-        zwarn("warning: %d jobs SIGHUPed", NULL, killed);
+        zwarn("warning: %d jobs SIGHUPed", killed);
 }
 
 
@@ -776,7 +776,7 @@ settrap(int sig, Eprog l, int flags)
     if (sig == -1)
         return 1;
     if (jobbing && (sig == SIGTTOU || sig == SIGTSTP || sig == SIGTTIN)) {
-        zerr("can't trap SIG%s in interactive shells", sigs[sig], 0);
+        zerr("can't trap SIG%s in interactive shells", sigs[sig]);
         return 1;
     }
 
diff --git a/Src/subst.c b/Src/subst.c
index 6a4c26b6c..803f8d99d 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -125,7 +125,7 @@ stringsubst(LinkList list, LinkNode node, int ssub, int asssub)
 		char *str2 = str;
 		str2++;
 		if (skipparens(Inbrack, Outbrack, &str2)) {
-		    zerr("closing bracket missing", NULL, 0);
+		    zerr("closing bracket missing");
 		    return NULL;
 		}
 		str2[-1] = *str = '\0';
@@ -189,7 +189,7 @@ stringsubst(LinkList list, LinkNode node, int ssub, int asssub)
 		    *str = ztokens[c - Pound];
 	    str++;
 	    if (!(pl = getoutput(str2 + 1, qt || ssub))) {
-		zerr("parse error in command substitution", NULL, 0);
+		zerr("parse error in command substitution");
 		return NULL;
 	    }
 	    if (endchar == Outpar)
@@ -275,7 +275,7 @@ globlist(LinkList list, int nountok)
 	zglob(list, node, nountok);
     }
     if (badcshglob == 1)
-	zerr("no match", NULL, 0);
+	zerr("no match");
 }
 
 /* perform substitution on a single word */
@@ -485,7 +485,7 @@ filesubstr(char **namptr, int assign)
 	    *ptr = 0;
 	    if (!(hom = getnameddir(str))) {
 		if (isset(NOMATCH))
-		    zerr("no such user or named directory: %s", str, 0);
+		    zerr("no such user or named directory: %s", str);
 		*ptr = save;
 		return 0;
 	    }
@@ -501,7 +501,7 @@ filesubstr(char **namptr, int assign)
 	*pp = 0;
 	if (!(cnam = findcmd(str + 1, 1))) {
 	    if (isset(NOMATCH))
-		zerr("%s not found", str + 1, 0);
+		zerr("%s not found", str + 1);
 	    return 0;
 	}
 	*namptr = dupstring(cnam);
@@ -1376,7 +1376,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 
 		default:
 		  flagerr:
-		    zerr("error in flags", NULL, 0);
+		    zerr("error in flags");
 		    return NULL;
 		}
 	    }
@@ -1457,7 +1457,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		*str = aptr + 1;
 		return n;
 	    } else {
-		zerr("bad substitution", NULL, 0);
+		zerr("bad substitution");
 		return NULL;
 	    }
 	} else if (inbrace && inull(*s)) {
@@ -1859,7 +1859,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 	c != '#' && c != Pound &&
 	c != '?' && c != Quest &&
 	c != '}' && c != Outbrace) {
-	zerr("bad substitution", NULL, 0);
+	zerr("bad substitution");
 	return NULL;
     }
     /*
@@ -1928,7 +1928,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 
 	if (bct) {
 	noclosebrace:
-	    zerr("closing brace expected", NULL, 0);
+	    zerr("closing brace expected");
 	    return NULL;
 	}
 	if (c)
@@ -2134,12 +2134,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 	case '?':
 	case Quest:
 	    if (vunset) {
-		char *msg;
-
 		*idend = '\0';
-		msg = tricat(idbeg, ": ", *s ? s : "parameter not set");
-		zerr("%s", msg, 0);
-		zsfree(msg);
+		zerr("%s: %s", idbeg, *s ? s : "parameter not set");
 		if (!interact)
 		    exit(1);
 		return NULL;
@@ -2168,8 +2164,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		    if (haserr)
 			shtokenize(s);
 		} else if (haserr || errflag) {
-		    zerr("parse error in ${...%c...} substitution",
-			 NULL, s[-1]);
+		    zerr("parse error in ${...%c...} substitution", s[-1]);
 		    return NULL;
 		}
 	    }
@@ -2228,7 +2223,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 	} else if (vunset) {
 	    if (unset(UNSET)) {
 		*idend = '\0';
-		zerr("%s: parameter not set", idbeg, 0);
+		zerr("%s: parameter not set", idbeg);
 		return NULL;
 	    }
 	    val = dupstring("");
@@ -2262,9 +2257,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		copied = 1;
 		if (inbrace && *s) {
 		    if (*s == ':' && !imeta(s[1]))
-			zerr("unrecognized modifier `%c'", NULL, s[1]);
+			zerr("unrecognized modifier `%c'", s[1]);
 		    else
-			zerr("unrecognized modifier", NULL, 0);
+			zerr("unrecognized modifier");
 		    return NULL;
 		}
 	    }
@@ -2517,7 +2512,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		if (!quoteerr)
 		    errflag = oef;
 		else if (haserr || errflag) {
-		    zerr("parse error in parameter value", NULL, 0);
+		    zerr("parse error in parameter value");
 		    return NULL;
 		}
 	    }
@@ -2549,7 +2544,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		if (!quoteerr)
 		    errflag = oef;
 		else if (haserr || errflag) {
-		    zerr("parse error in parameter value", NULL, 0);
+		    zerr("parse error in parameter value");
 		    return NULL;
 		}
 		remnulargs(val);
@@ -2897,7 +2892,7 @@ modify(char **str, char **ptr)
 		del = *ptr1++;
 		for (ptr2 = ptr1; *ptr2 != del && *ptr2; ptr2++);
 		if (!*ptr2) {
-		    zerr("bad substitution", NULL, 0);
+		    zerr("bad substitution");
 		    return;
 		}
 		*ptr2++ = '\0';
@@ -2909,7 +2904,7 @@ modify(char **str, char **ptr)
 		    hsubl = ztrdup(ptr1);
  		}
 		if (!hsubl) {
-		    zerr("no previous substitution", NULL, 0);
+		    zerr("no previous substitution");
 		    return;
 		}
 		zsfree(hsubr);
@@ -3118,7 +3113,7 @@ dstackent(char ch, int val)
 	if (backwards && !val)
 	    return pwd;
 	if (isset(NOMATCH))
-	    zerr("not enough directory stack entries.", NULL, 0);
+	    zerr("not enough directory stack entries.");
 	return NULL;
     }
     return (char *)getdata(n);
diff --git a/Src/system.h b/Src/system.h
index 377cd173e..340f4693b 100644
--- a/Src/system.h
+++ b/Src/system.h
@@ -153,6 +153,10 @@ char *alloca _((size_t));
 # include <stdlib.h>
 #endif
 
+#ifdef HAVE_STDARG_H
+# include <stdarg.h>
+#endif
+
 #ifdef HAVE_ERRNO_H
 # include <errno.h>
 #endif
diff --git a/Src/utils.c b/Src/utils.c
index da453af6f..bb814a41b 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -47,72 +47,99 @@ mod_export wchar_t *wordchars_wide;
 /**/
 #endif
 
+
 /* Print an error */
- 
+
+static void
+zwarning(const char *cmd, const char *fmt, va_list ap)
+{
+    if (isatty(2))
+	trashzleptr();
+
+    if (cmd) {
+	if (unset(SHINSTDIN) || locallevel) {
+	    nicezputs(scriptname ? scriptname : argzero, stderr);
+	    fputc((unsigned char)':', stderr);
+	}
+	nicezputs(cmd, stderr);
+	fputc((unsigned char)':', stderr);
+    } else {
+	/*
+	 * scriptname is set when sourcing scripts, so that we get the
+	 * correct name instead of the generic name of whatever
+	 * program/script is running.  It's also set in shell functions,
+	 * so test locallevel, too.
+	 */
+	nicezputs((isset(SHINSTDIN) && !locallevel) ? "zsh" :
+		  scriptname ? scriptname : argzero, stderr);
+	fputc((unsigned char)':', stderr);
+    }
+
+    zerrmsg(fmt, ap);
+}
+
 /**/
 mod_export void
-zerr(const char *fmt, const char *str, int num)
+zerr(const char *fmt, ...)
 {
+    va_list ap;
+
     if (errflag || noerrs) {
 	if (noerrs < 2)
 	    errflag = 1;
 	return;
     }
-    zwarn(fmt, str, num);
+
+    va_start(ap, fmt);
+    zwarning(NULL, fmt, ap);
+    va_end(ap);
     errflag = 1;
 }
 
 /**/
 mod_export void
-zerrnam(const char *cmd, const char *fmt, const char *str, int num)
+zerrnam(const char *cmd, const char *fmt, ...)
 {
+    va_list ap;
+
     if (errflag || noerrs)
 	return;
 
-    zwarnnam(cmd, fmt, str, num);
+    va_start(ap, fmt);
+    zwarning(cmd, fmt, ap);
+    va_end(ap);
     errflag = 1;
 }
 
 /**/
 mod_export void
-zwarn(const char *fmt, const char *str, int num)
+zwarn(const char *fmt, ...)
 {
+    va_list ap;
+
     if (errflag || noerrs)
 	return;
-    if (isatty(2))
-	trashzleptr();
-    /*
-     * scriptname is set when sourcing scripts, so that we get the
-     * correct name instead of the generic name of whatever
-     * program/script is running.  It's also set in shell functions,
-     * so test locallevel, too.
-     */
-    nicezputs((isset(SHINSTDIN) && !locallevel) ? "zsh" :
-	      scriptname ? scriptname : argzero, stderr);
-    fputc((unsigned char)':', stderr);
-    zerrmsg(fmt, str, num);
+
+    va_start(ap, fmt);
+    zwarning(NULL, fmt, ap);
+    va_end(ap);
 }
 
 /**/
 mod_export void
-zwarnnam(const char *cmd, const char *fmt, const char *str, int num)
+zwarnnam(const char *cmd, const char *fmt, ...)
 {
-    if (!cmd) {
-	zwarn(fmt, str, num);
-	return;
-    }
+    va_list ap;
+
     if (errflag || noerrs)
 	return;
-    trashzleptr();
-    if (unset(SHINSTDIN) || locallevel) {
-	nicezputs(scriptname ? scriptname : argzero, stderr);
-	fputc((unsigned char)':', stderr);
-    }
-    nicezputs(cmd, stderr);
-    fputc((unsigned char)':', stderr);
-    zerrmsg(fmt, str, num);
+
+    va_start(ap, fmt);
+    zwarning(cmd, fmt, ap);
+    va_end(ap);
 }
 
+
 #ifdef __CYGWIN__
 /*
  * This works around an occasional problem with dllwrap on Cygwin, seen
@@ -128,8 +155,11 @@ zz_plural_z_alpha(void)
 
 /**/
 void
-zerrmsg(const char *fmt, const char *str, int num)
+zerrmsg(const char *fmt, va_list ap)
 {
+    const char *str;
+    int num;
+
     if ((unset(SHINSTDIN) || locallevel) && lineno)
 	fprintf(stderr, "%ld: ", (long)lineno);
     else
@@ -140,10 +170,13 @@ zerrmsg(const char *fmt, const char *str, int num)
 	    fmt++;
 	    switch (*fmt++) {
 	    case 's':
+		str = va_arg(ap, const char *);
 		nicezputs(str, stderr);
 		break;
 	    case 'l': {
 		char *s;
+		str = va_arg(ap, const char *);
+		num = va_arg(ap, int);
 		num = metalen(str, num);
 		s = zhalloc(num + 1);
 		memcpy(s, str, num);
@@ -152,12 +185,14 @@ zerrmsg(const char *fmt, const char *str, int num)
 		break;
 	    }
 	    case 'd':
+		num = va_arg(ap, int);
 		fprintf(stderr, "%d", num);
 		break;
 	    case '%':
 		putc('%', stderr);
 		break;
 	    case 'c':
+		num = va_arg(ap, int);
 #ifdef MULTIBYTE_SUPPORT
 		zputs(wcs_nicechar(num, NULL, NULL), stderr);
 #else
@@ -166,6 +201,7 @@ zerrmsg(const char *fmt, const char *str, int num)
 		break;
 	    case 'e':
 		/* print the corresponding message for this errno */
+		num = va_arg(ap, int);
 		if (num == EINTR) {
 		    fputs("interrupt\n", stderr);
 		    errflag = 1;
@@ -912,10 +948,10 @@ checkmailpath(char **s)
 	    u = v + 1;
 	if (**s == 0) {
 	    *v = c;
-	    zerr("empty MAILPATH component: %s", *s, 0);
+	    zerr("empty MAILPATH component: %s", *s);
 	} else if (mailstat(unmeta(*s), &st) == -1) {
 	    if (errno != ENOENT)
-		zerr("%e: %s", *s, errno);
+		zerr("%e: %s", errno, *s);
 	} else if (S_ISDIR(st.st_mode)) {
 	    LinkList l;
 	    DIR *lock = opendir(unmeta(*s));
@@ -1019,7 +1055,7 @@ gettyinfo(struct ttyinfo *ti)
 # else
 	if (ioctl(SHTTY, TCGETS, &ti->tio) == -1)
 # endif
-	    zerr("bad tcgets: %e", NULL, errno);
+	    zerr("bad tcgets: %e", errno);
 #else
 # ifdef HAVE_TERMIO_H
 	ioctl(SHTTY, TCGETA, &ti->tio);
@@ -1049,7 +1085,7 @@ settyinfo(struct ttyinfo *ti)
 	ioctl(SHTTY, TCSETS, &ti->tio);
     /* if (ioctl(SHTTY, TCSETS, &ti->tio) == -1) */
 # endif
-	/*	zerr("settyinfo: %e",NULL,errno)*/ ;
+	/*	zerr("settyinfo: %e",errno)*/ ;
 #else
 # ifdef HAVE_TERMIO_H
 	ioctl(SHTTY, TCSETA, &ti->tio);
@@ -1527,7 +1563,7 @@ zstrtol(const char *s, char **t, int base)
     }
 
     if (trunc)
-	zwarn("number truncated after %d digits: %s", inp, trunc - inp);
+	zwarn("number truncated after %d digits: %s", (int)(trunc - inp), inp);
 
     if (t)
 	*t = (char *)s;
@@ -2963,7 +2999,7 @@ attachtty(pid_t pgrp)
 	    else {
 		if (errno != ENOTTY)
 		{
-		    zwarn("can't set tty pgrp: %e", NULL, errno);
+		    zwarn("can't set tty pgrp: %e", errno);
 		    fflush(stderr);
 		}
 		opts[MONITOR] = 0;
@@ -4124,7 +4160,7 @@ getkeystring(char *s, int *len, int fromwhere, int *misc)
 #if defined(HAVE_WCHAR_H) && defined(HAVE_WCTOMB) && defined(__STDC_ISO_10646__)
 		count = wctomb(t, (wchar_t)wval);
 		if (count == -1) {
-		    zerr("character not in range", NULL, 0);
+		    zerr("character not in range");
 		    if (fromwhere == 4) {
 			for (u = t; (*u++ = *++s););
 			return t;
@@ -4153,7 +4189,7 @@ getkeystring(char *s, int *len, int fromwhere, int *misc)
 
     	    	    cd = iconv_open(nl_langinfo(CODESET), "UCS-4BE");
 		    if (cd == (iconv_t)-1) {
-			zerr("cannot do charset conversion", NULL, 0);
+			zerr("cannot do charset conversion");
 			if (fromwhere == 4) {
 			    for (u = t; (*u++ = *++s););
 			    return t;
@@ -4165,21 +4201,21 @@ getkeystring(char *s, int *len, int fromwhere, int *misc)
                     count = iconv(cd, &inptr, &inbytes, &t, &outbytes);
 		    iconv_close(cd);
 		    if (count == (size_t)-1) {
-                        zerr("character not in range", NULL, 0);
+                        zerr("character not in range");
 		        *t = '\0';
 			*len = t - buf;
 			return buf;
 		    }
 		    continue;
 #   else
-                    zerr("cannot do charset conversion", NULL, 0);
+                    zerr("cannot do charset conversion");
 		    *t = '\0';
 		    *len = t - buf;
 		    return buf;
 #   endif
 		}
 #  else
-                zerr("cannot do charset conversion", NULL, 0);
+                zerr("cannot do charset conversion");
 		*t = '\0';
 		*len = t - buf;
 		return buf;
diff --git a/configure.ac b/configure.ac
index f4eb5c56e..036980653 100644
--- a/configure.ac
+++ b/configure.ac
@@ -552,7 +552,8 @@ fi
 AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \
 		 termios.h sys/param.h sys/filio.h string.h memory.h \
 		 limits.h fcntl.h libc.h sys/utsname.h sys/resource.h \
-		 locale.h errno.h stdio.h stdlib.h unistd.h sys/capability.h \
+		 locale.h errno.h stdio.h stdarg.h stdlib.h \
+		 unistd.h sys/capability.h \
 		 utmp.h utmpx.h sys/types.h pwd.h grp.h poll.h sys/mman.h \
 		 netinet/in_systm.h pcre.h langinfo.h wchar.h stddef.h \
 		 sys/stropts.h iconv.h)