Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm
Precedence: bulk
X-No-Archive: yes
List-Id: Zsh Workers List <zsh-workers.zsh.org>
List-Post: <mailto:zsh-workers@zsh.org>
List-Help: <mailto:zsh-workers-help@zsh.org>
X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au
X-Spam-Level: 
X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,T_DKIM_INVALID
	autolearn=ham autolearn_force=no version=3.4.0
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=brasslantern-com.20150623.gappssmtp.com; s=20150623;
        h=from:message-id:date:to:subject:mime-version:content-type;
        bh=NZEcEdSpFylI/e5P3LzLUDpJJpz+0SG4Tw/neqSMjcs=;
        b=mNIeqBDHLlT67hxXASZgHr6DMLjpDidYYTcE33YAfzUPIiQ2cAxdiJ5MLp/TjWfRQz
         NUgj4Hy58zNIIMSV6ZZgwTkr7S632Vk78BUjMVy/lWem4qPU7V48XpdUF+ZUxcauzE14
         9kn2q4EhP5J3RZZfxTDkguYAFYpTjwAiclXTzQXMsAPo31HieQmOXKCUFxnydmpmPr3B
         QF/HGt7rckIHjp9oxqIMruLjad6QVWkyq+/DzmrPAaDBZM4hr45J5uKDrByhGyzRPG8Z
         D9QeY7ql985wyjkm+agejVot4kKKPdDYSf5kgbuGbxFCSUTI/EF+jQjxjveRyfc5/joA
         3v/g==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:from:message-id:date:to:subject:mime-version
         :content-type;
        bh=NZEcEdSpFylI/e5P3LzLUDpJJpz+0SG4Tw/neqSMjcs=;
        b=T1T5okt8GDNo72U/Vko6Rcy3+C3dg3oy0MIn/Cnz6djKvFOn2PFd6lkjR4jQWIZJKj
         va9ZDucoCnbOqIKVKQgNBviUGftmlDsjcLn4tHlBO+I56yqginDI8H6CIaDgkt8MdnKg
         83z4GN3x0ptyPGnoJ++utbf8AT3lyddo04eUs73/1PWEhgrvLmef050Yg5rcxYQ1zezQ
         NC9TB7q4w7XOGp2B42sUJlMpa1ygShUutzfPNKxf8e3r0XIsfvu29aIpnatIW3hcxfEt
         6soru/Mr6K2qx1N35PEULe7i5eE2zFxa3VU9m6onVM3lMltfoOesq+2zL7MZEZoKGNVS
         fBzQ==
X-Gm-Message-State: ALoCoQkZsTIzHeG/aEngNBiGByUpFJeM8oB1rtBmaOpYBAEyoEMknPXi3I+/0ArRvBP3Ao++hP8OqskiT/V225PRYjkkykBGxQ==
X-Received: by 10.98.44.213 with SMTP id s204mr114413271pfs.1.1451976469072;
        Mon, 04 Jan 2016 22:47:49 -0800 (PST)
From: Bart Schaefer <schaefer@brasslantern.com>
Message-Id: <160104224749.ZM6378@torch.brasslantern.com>
Date: Mon, 4 Jan 2016 22:47:49 -0800
X-Mailer: OpenZMail Classic (0.9.2 24April2005)
To: zsh-workers@zsh.org
Subject: PATCH misc. cleanup in bin_print()
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
X-Seq: zsh-workers 37503

Is there any objection to making some of these incompatible combinations
of print options into errors, instead of either implicit precedences or
bugs waiting to happen?  The one I left commented out has an explicit
Test/B03* check so I'm guessing maybe there's a reason for it.

I moved the -C block up so simple option misuse can be detected before
we go through file expansion or sorting.  The rest of the changes are
cosmetic, except for the last one which I think was a memory leak in
the case of an error, though I could never make it happen.


diff --git a/Src/builtin.c b/Src/builtin.c
index 03fefa6..cfc14a8 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -4036,10 +4036,46 @@ bin_print(char *name, char **args, Options ops, int func)
     zulong zulongval;
     char *stringval;
 
-    if (OPT_ISSET(ops, 'z') + OPT_ISSET(ops, 's') + OPT_ISSET(ops, 'v') > 1) {
-	zwarnnam(name, "only one of -z, -s, or -v allowed");
+    /* Error check option combinations and option arguments */
+
+    if (OPT_ISSET(ops, 'z') +
+	OPT_ISSET(ops, 's') + OPT_ISSET(ops, 'S') +
+	OPT_ISSET(ops, 'v') > 1) {
+	zwarnnam(name, "only one of -s, -S, -v, or -z allowed");
+	return 1;
+    }
+    if ((OPT_ISSET(ops, 'z') | OPT_ISSET(ops, 's') | OPT_ISSET(ops, 'S')) +
+	(OPT_ISSET(ops, 'c') | OPT_ISSET(ops, 'C')) > 1) {
+	zwarnnam(name, "-c or -C not allowed with -s, -S, or -z");
 	return 1;
     }
+    if ((OPT_ISSET(ops, 'z') | OPT_ISSET(ops, 'v') |
+         OPT_ISSET(ops, 's') | OPT_ISSET(ops, 'S')) +
+	(OPT_ISSET(ops, 'p') | OPT_ISSET(ops, 'u')) > 1) {
+	zwarnnam(name, "-p or -u not allowed with -s, -S, -v, or -z");
+	return 1;
+    }
+    /*
+    if (OPT_ISSET(ops, 'f') &&
+	(OPT_ISSET(ops, 'S') || OPT_ISSET(ops, 'c') || OPT_ISSET(ops, 'C'))) {
+	zwarnnam(name, "-f not allowed with -c, -C, or -S");
+	return 1;
+    }
+    */
+
+    /* -C -- number of columns */
+    if (!fmt && OPT_ISSET(ops,'C')) {
+	char *eptr, *argptr = OPT_ARG(ops,'C');
+	nc = (int)zstrtol(argptr, &eptr, 10);
+	if (*eptr) {
+	    zwarnnam(name, "number expected after -%c: %s", 'C', argptr);
+	    return 1;
+	}
+	if (nc <= 0) {
+	    zwarnnam(name, "invalid number of columns: %s", argptr);
+	    return 1;
+	}
+    }
 
     if (func == BIN_PRINTF) {
         if (!strcmp(*args, "--") && !*++args) {
@@ -4105,7 +4141,7 @@ bin_print(char *name, char **args, Options ops, int func)
 	    }
 	}
 	/* -P option -- interpret as a prompt sequence */
-	if(OPT_ISSET(ops,'P')) {
+	if (OPT_ISSET(ops,'P')) {
 	    /*
 	     * promptexpand uses permanent storage: to avoid
 	     * messy memory management, stick it on the heap
@@ -4119,13 +4155,13 @@ bin_print(char *name, char **args, Options ops, int func)
 	    free(str);
 	}
 	/* -D option -- interpret as a directory, and use ~ */
-	if(OPT_ISSET(ops,'D')) {
+	if (OPT_ISSET(ops,'D')) {
 	    Nameddir d;
 
 	    queue_signals();
 	    /* TODO: finddir takes a metafied file */
 	    d = finddir(args[n]);
-	    if(d) {
+	    if (d) {
 		int dirlen = strlen(d->dir);
 		char *arg = zhalloc(len[n] - dirlen + strlen(d->node.nam) + 2);
 		sprintf(arg, "~%s%s", d->node.nam, args[n] + dirlen);
@@ -4148,20 +4184,6 @@ bin_print(char *name, char **args, Options ops, int func)
 	strmetasort(args, flags, len);
     }
 
-    /* -C -- number of columns */
-    if (!fmt && OPT_ISSET(ops,'C')) {
-	char *eptr, *argptr = OPT_ARG(ops,'C');
-	nc = (int)zstrtol(argptr, &eptr, 10);
-	if (*eptr) {
-	    zwarnnam(name, "number expected after -%c: %s", 'C', argptr);
-	    return 1;
-	}
-	if (nc <= 0) {
-	    zwarnnam(name, "invalid number of columns: %s", argptr);
-	    return 1;
-	}
-    }
-
     /* -u and -p -- output to other than standard output */
     if ((OPT_HASARG(ops,'u') || OPT_ISSET(ops,'p')) &&
 	/* rule out conflicting options -- historical precedence */
@@ -4188,8 +4210,7 @@ bin_print(char *name, char **args, Options ops, int func)
 	    } else {
 		fdarg = (int)zstrtol(argptr, &eptr, 10);
 		if (*eptr) {
-		    zwarnnam(name, "number expected after -%c: %s", 'u',
-			     argptr);
+		    zwarnnam(name, "number expected after -u: %s", argptr);
 		    return 1;
 		}
 	    }
@@ -4358,8 +4379,8 @@ bin_print(char *name, char **args, Options ops, int func)
 	    fputc(OPT_ISSET(ops,'N') ? '\0' : '\n', fout);
 	}
 	/* Testing EBADF special-cases >&- redirections */
-	if ((fout != stdout) ? (fclose(fout) != 0) :
-	    (fflush(fout) != 0 && errno != EBADF)) {
+	if ((fout == stdout) ? (fflush(fout) != 0 && errno != EBADF) :
+	    (fclose(fout) != 0)) {
             zwarnnam(name, "write error: %e", errno);
             ret = 1;
 	}
@@ -4368,8 +4389,8 @@ bin_print(char *name, char **args, Options ops, int func)
 
     /* normal output */
     if (!fmt) {
-	if (OPT_ISSET(ops, 'z') || OPT_ISSET(ops, 's') ||
-	    OPT_ISSET(ops, 'v')) {
+	if (OPT_ISSET(ops, 'z') || OPT_ISSET(ops, 'v') ||
+	    OPT_ISSET(ops, 's') || OPT_ISSET(ops, 'S')) {
 	    /*
 	     * We don't want the arguments unmetafied after all.
 	     */
@@ -4477,8 +4498,8 @@ bin_print(char *name, char **args, Options ops, int func)
 	if (!(OPT_ISSET(ops,'n') || nnl))
 	    fputc(OPT_ISSET(ops,'N') ? '\0' : '\n', fout);
 	/* Testing EBADF special-cases >&- redirections */
-	if ((fout != stdout) ? (fclose(fout) != 0) :
-	    (fflush(fout) != 0 && errno != EBADF)) {
+	if ((fout == stdout) ? (fflush(fout) != 0 && errno != EBADF) :
+	    (fclose(fout) != 0)) {
             zwarnnam(name, "write error: %e", errno);
             ret = 1;
 	}
@@ -4769,8 +4790,8 @@ bin_print(char *name, char **args, Options ops, int func)
 		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)) {
+		if ((fout == stdout) ? (fflush(fout) != 0 && errno != EBADF) :
+		    (fclose(fout) != 0)) {
 		    zwarnnam(name, "write error: %e", errno);
 		}
 #ifdef HAVE_OPEN_MEMSTREAM
@@ -4886,6 +4907,7 @@ bin_print(char *name, char **args, Options ops, int func)
 #endif
 	queue_signals();
 	stringval = metafy(buf, rcount - 1, META_REALLOC);
+	buf = NULL;
 	if (OPT_ISSET(ops,'z')) {
 	    zpushnode(bufstack, stringval);
 	} else if (OPT_ISSET(ops,'v')) {
@@ -4911,6 +4933,8 @@ bin_print(char *name, char **args, Options ops, int func)
 	    zwarnnam(name, "write error: %e", errno);
 	    ret = 1;
 	}
+	if (buf)
+	    free(buf);
     }
     return ret;
 }

