Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/printf Amend the previous change: we can have (almos...



details:   https://anonhg.NetBSD.org/src/rev/27ce0a7a5385
branches:  trunk
changeset: 457831:27ce0a7a5385
user:      kre <kre%NetBSD.org@localhost>
date:      Mon Jul 22 17:34:31 2019 +0000

description:
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.

diffstat:

 usr.bin/printf/printf.c |  46 +++++++++++++++++++++++++++++-----------------
 1 files changed, 29 insertions(+), 17 deletions(-)

diffs (73 lines):

diff -r b46cebf9c543 -r 27ce0a7a5385 usr.bin/printf/printf.c
--- a/usr.bin/printf/printf.c   Mon Jul 22 14:47:51 2019 +0000
+++ b/usr.bin/printf/printf.c   Mon Jul 22 17:34:31 2019 +0000
@@ -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 @@
 #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 @@
 
        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();



Home | Main Index | Thread Index | Old Index