Module Name:    src
Committed By:   kre
Date:           Mon Jul 22 17:34:31 UTC 2019

Modified Files:
        src/usr.bin/printf: printf.c

Log Message:
Amend the previous change: we can have (almost) the best of both
worlds, as when the first arg (which should be the format) contains
no % conversions, and there are more args, the results are unspecified
(according to POSIX).

We can use this so the previous usage
        printf -- format arg...
(which is stupid, and pointless, but used to work) continues to
simply ignore the -- (unspecified results mean we can do whatever
feels good...)

This brings back the #if 0'd block from the previous modification
(so there is no longer anything that needs cleaning up later) but runs
the getopt() loop it contained only when there are at least 2 args
(so any 1 arg printf always uses that arg as the format string,
whatever it contains, including just "--") and also only when the
first (format) arg contains no '%' characters (which guarantees no %
conversions without needing to actually parse the arg).  This is the
(or a) "unspecified results" case from POSIX, so we are free to do
anything we like - including assuming that we might have options
(we don't) and pretending to process them.


To generate a diff of this commit:
cvs rdiff -u -r1.49 -r1.50 src/usr.bin/printf/printf.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/printf/printf.c
diff -u src/usr.bin/printf/printf.c:1.49 src/usr.bin/printf/printf.c:1.50
--- src/usr.bin/printf/printf.c:1.49	Sun Jul 21 15:25:39 2019
+++ src/usr.bin/printf/printf.c	Mon Jul 22 17:34:31 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: printf.c,v 1.49 2019/07/21 15:25:39 kre Exp $	*/
+/*	$NetBSD: printf.c,v 1.50 2019/07/22 17:34:31 kre Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -41,7 +41,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 19
 #if 0
 static char sccsid[] = "@(#)printf.c	8.2 (Berkeley) 3/22/95";
 #else
-__RCSID("$NetBSD: printf.c,v 1.49 2019/07/21 15:25:39 kre Exp $");
+__RCSID("$NetBSD: printf.c,v 1.50 2019/07/22 17:34:31 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -138,27 +138,39 @@ main(int argc, char *argv[])
 
 	rval = 0;	/* clear for builtin versions (avoid holdover) */
 
-#if 0
-	int o;
-
 	/*
 	 * printf does not comply with Posix XBD 12.2 - there are no opts,
 	 * not even the -- end of options marker.   Do not run getoot().
 	 */
-	while ((o = getopt(argc, argv, "")) != -1) {
-		switch (o) {
-		case '?':
-		default:
-			usage();
-			return 1;
+	if (argc > 2 && strchr(argv[1], '%') == NULL) {
+		int o;
+
+		/*
+		 * except that if there are multiple args and
+		 * the first (the nominal format) contains no '%'
+		 * conversions (which we will approximate as no '%'
+		 * characters at all, conversions or not) then the
+		 * results are unspecified, and we can do what we
+		 * like.   So in that case, for some backward compat
+		 * to scripts which (stupidly) do:
+		 *	printf -- format args
+		 * process this case the old way.
+		 */
+
+		while ((o = getopt(argc, argv, "")) != -1) {
+			switch (o) {
+			case '?':
+			default:
+				usage();
+				return 1;
+			}
 		}
+		argc -= optind;
+		argv += optind;
+	} else {
+		argc -= 1;	/* drop argv[0] (the program name) */
+		argv += 1;
 	}
-	argc -= optind;
-	argv += optind;
-#else
-	argc -= 1;
-	argv += 1;
-#endif
 
 	if (argc < 1) {
 		usage();

Reply via email to