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
This commit is contained in:
parent
534840ba27
commit
540cea4ebc
@ -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
|
||||
|
@ -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 == '*') {
|
||||
|
Loading…
Reference in New Issue
Block a user