summaryrefslogtreecommitdiffstats
path: root/usr.bin/printf
diff options
context:
space:
mode:
authorgrehan <grehan@FreeBSD.org>2011-06-28 06:26:03 +0000
committergrehan <grehan@FreeBSD.org>2011-06-28 06:26:03 +0000
commit2c6741be0f59191f2283eb268e4f7690399d578a (patch)
treeb139c8c6dcca4fa284815daade405b75886ee360 /usr.bin/printf
parent3c35264f695e0a1f8a04dbcca1c93bb5159b2274 (diff)
parent19ae02bba572390c7299166228d31e54003e094a (diff)
downloadFreeBSD-src-2c6741be0f59191f2283eb268e4f7690399d578a.zip
FreeBSD-src-2c6741be0f59191f2283eb268e4f7690399d578a.tar.gz
IFC @ r222830
Diffstat (limited to 'usr.bin/printf')
-rw-r--r--usr.bin/printf/printf.128
-rw-r--r--usr.bin/printf/printf.c22
2 files changed, 37 insertions, 13 deletions
diff --git a/usr.bin/printf/printf.1 b/usr.bin/printf/printf.1
index 56c6855..792529a 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 April 25, 2011
+.Dd May 28, 2011
.Dt PRINTF 1
.Os
.Sh NAME
@@ -68,8 +68,7 @@ otherwise it is evaluated as a C constant, with the following extensions:
A leading plus or minus sign is allowed.
.It
If the leading character is a single or double quote, the value is the
-.Tn ASCII
-code of the next character.
+character code of the next character.
.El
.Pp
The format string is reused as often as necessary to satisfy the
@@ -172,7 +171,7 @@ A `\-' overrides a `0' if both are used;
.It "Field Width:"
An optional digit string specifying a
.Em field width ;
-if the output string has fewer characters than the field width it will
+if the output string has fewer bytes than the field width it will
be blank-padded on the left (or right, if the left-adjustment indicator
has been given) to make up the field width (note that a leading zero
is a flag, but an embedded zero is part of a field width);
@@ -186,7 +185,7 @@ for
.Cm e
and
.Cm f
-formats, or the maximum number of characters to be printed
+formats, or the maximum number of bytes to be printed
from a string; if the digit string is missing, the precision is treated
as zero;
.It Format:
@@ -272,15 +271,15 @@ and
.Ql nan ,
respectively.
.It Cm c
-The first character of
+The first byte of
.Ar argument
is printed.
.It Cm s
-Characters from the string
+Bytes from the string
.Ar argument
-are printed until the end is reached or until the number of characters
+are printed until the end is reached or until the number of bytes
indicated by the precision specification is reached; however if the
-precision is 0 or missing, all characters in the string are printed.
+precision is 0 or missing, the string is printed entirely.
.It Cm b
As for
.Cm s ,
@@ -347,6 +346,17 @@ to interpret the dash as a program argument.
.Nm --
must be used before
.Ar format .
+.Pp
+If the locale contains multibyte characters
+(such as UTF-8),
+the
+.Cm c
+format and
+.Cm b
+and
+.Cm s
+formats with a precision
+may not operate as expected.
.Sh BUGS
Since the floating point numbers are translated from
.Tn ASCII
diff --git a/usr.bin/printf/printf.c b/usr.bin/printf/printf.c
index 56c1caf..eace370 100644
--- a/usr.bin/printf/printf.c
+++ b/usr.bin/printf/printf.c
@@ -58,6 +58,7 @@ static const char rcsid[] =
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <wchar.h>
#ifdef SHELL
#define main printfcmd
@@ -537,10 +538,23 @@ static int
asciicode(void)
{
int ch;
-
- ch = **gargv;
- if (ch == '\'' || ch == '"')
- ch = (*gargv)[1];
+ wchar_t wch;
+ mbstate_t mbs;
+
+ ch = (unsigned char)**gargv;
+ if (ch == '\'' || ch == '"') {
+ memset(&mbs, 0, sizeof(mbs));
+ switch (mbrtowc(&wch, *gargv + 1, MB_LEN_MAX, &mbs)) {
+ case (size_t)-2:
+ case (size_t)-1:
+ wch = (unsigned char)gargv[0][1];
+ break;
+ case 0:
+ wch = 0;
+ break;
+ }
+ ch = wch;
+ }
++gargv;
return (ch);
}
OpenPOWER on IntegriCloud