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();