summaryrefslogtreecommitdiffstats
path: root/usr.bin/printf
diff options
context:
space:
mode:
authorpfg <pfg@FreeBSD.org>2014-04-21 22:47:18 +0000
committerpfg <pfg@FreeBSD.org>2014-04-21 22:47:18 +0000
commit540cea4ebc7db0a742da16bad4078a2fdfc50695 (patch)
treefff855d4510018bbb09fc9de05fda6039dad40e5 /usr.bin/printf
parent534840ba27f335f1e9ce6b8fb70f43a9f0cd3a0c (diff)
downloadFreeBSD-src-540cea4ebc7db0a742da16bad4078a2fdfc50695.zip
FreeBSD-src-540cea4ebc7db0a742da16bad4078a2fdfc50695.tar.gz
Add parameterized position handling to printf(1).
Add a new %n$ option to change the order of the parameters as done in the ksh93 builtin printf (among others). For example: %printf '%2$1d %1$s\n' one 2 three 4 2 one 4 three The feature was written by Garret D'Amore under a BSD license for Nexenta/illumos. Reference: http://garrett.damore.org/2010/10/new-implementation-of-printf.html PR: bin/152934 Obtained from: Illumos MFC after: 2 weeks
Diffstat (limited to 'usr.bin/printf')
-rw-r--r--usr.bin/printf/printf.15
-rw-r--r--usr.bin/printf/printf.c35
2 files changed, 39 insertions, 1 deletions
diff --git a/usr.bin/printf/printf.1 b/usr.bin/printf/printf.1
index c5bba97..7256b53d 100644
--- a/usr.bin/printf/printf.1
+++ b/usr.bin/printf/printf.1
@@ -31,7 +31,7 @@
.\" @(#)printf.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
-.Dd May 28, 2011
+.Dd April 21, 2014
.Dt PRINTF 1
.Os
.Sh NAME
@@ -290,6 +290,9 @@ octal escapes are
.Cm \e0 Ns Ar num
instead of
.Cm \e Ns Ar num .
+.It Cm n$
+Allows reordering of the output according to
+.Ar argument .
.It Cm \&%
Print a `%'; no argument is used.
.El
diff --git a/usr.bin/printf/printf.c b/usr.bin/printf/printf.c
index 8569f5f..7ed0c21 100644
--- a/usr.bin/printf/printf.c
+++ b/usr.bin/printf/printf.c
@@ -1,4 +1,5 @@
/*-
+ * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -69,6 +70,11 @@ static const char rcsid[] =
#define PF(f, func) do { \
char *b = NULL; \
+ int dollar = 0; \
+ if (*f == '$') { \
+ dollar++; \
+ *f = '%'; \
+ } \
if (havewidth) \
if (haveprec) \
(void)asprintf(&b, f, fieldwidth, precision, func); \
@@ -82,6 +88,8 @@ static const char rcsid[] =
(void)fputs(b, stdout); \
free(b); \
} \
+ if (dollar) \
+ *f = '$'; \
} while (0)
static int asciicode(void);
@@ -96,6 +104,8 @@ static const char
static char *mknum(char *, char);
static void usage(void);
+static int myargc;
+static char **myargv;
static char **gargv;
int
@@ -146,7 +156,13 @@ main(int argc, char *argv[])
chopped = escape(fmt, 1, &len); /* backslash interpretation */
rval = end = 0;
gargv = ++argv;
+
for (;;) {
+ char **maxargv = gargv;
+
+ myargv = gargv;
+ for (myargc = 0; gargv[myargc]; myargc++)
+ /* nop */;
start = fmt;
while (fmt < format + len) {
if (fmt[0] == '%') {
@@ -168,7 +184,10 @@ main(int argc, char *argv[])
start = fmt;
} else
fmt++;
+ if (gargv > maxargv)
+ maxargv = gargv;
}
+ gargv = maxargv;
if (end == 1) {
warnx("missing format character");
@@ -202,6 +221,22 @@ printf_doformat(char *start, int *rval)
char convch, nextch;
fmt = start + 1;
+
+ /* look for "n$" field index specifier */
+ fmt += strspn(fmt, skip2);
+ if ((*fmt == '$') && (fmt != (start + 1))) {
+ int idx = atoi(start + 1);
+ if (idx <= myargc) {
+ gargv = &myargv[idx - 1];
+ } else {
+ gargv = &myargv[myargc];
+ }
+ start = fmt;
+ fmt++;
+ } else {
+ fmt = start + 1;
+ }
+
/* skip to field width */
fmt += strspn(fmt, skip1);
if (*fmt == '*') {
OpenPOWER on IntegriCloud