summaryrefslogtreecommitdiff
path: root/lib/libc/stdio/vfprintf.c
diff options
context:
space:
mode:
authorjtc <jtc@NetBSD.org>1995-05-02 19:52:41 +0000
committerjtc <jtc@NetBSD.org>1995-05-02 19:52:41 +0000
commit615fb07b157b8da9d76f35a0bc709dc50fcec381 (patch)
treecdd633ddef456ddb846d283055e9209f62da2ec8 /lib/libc/stdio/vfprintf.c
parentbe2c7f3d132ac0681c07bfab5a099b4eb0bbb40b (diff)
The C Standard says that printf's format string is a multi-byte
character string. NA1 says that the 99 characters required by the Standard have representations in the initial state which are one byte long and do not alter the state. Thus we can safely break apart the format string with mbtowc() until we reach a '%' character, and the process format directive characters one by one. We really shouldn't be using mbtowc(), rather mbrtowc() (which takes a mbstate-t argument) but we don't have the NA1 functions implemented yet. This is safe, because even when we do we're not likely to support multi-byte character encodings that use shift states.
Diffstat (limited to 'lib/libc/stdio/vfprintf.c')
-rw-r--r--lib/libc/stdio/vfprintf.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index 059707c0e5a..17fb6831bc4 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -36,7 +36,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)vfprintf.c 5.50 (Berkeley) 12/16/92";*/
-static char *rcsid = "$Id: vfprintf.c,v 1.16 1995/03/22 00:56:55 jtc Exp $";
+static char *rcsid = "$Id: vfprintf.c,v 1.17 1995/05/02 19:52:41 jtc Exp $";
#endif /* LIBC_SCCS and not lint */
/*
@@ -162,7 +162,7 @@ vfprintf(fp, fmt0, ap)
{
register char *fmt; /* format string */
register int ch; /* character from fmt */
- register int n; /* handy integer (short term usage) */
+ register int n, m; /* handy integers (short term usage) */
register char *cp; /* handy char pointer (short term usage) */
register struct __siov *iovp;/* for PRINT macro */
register int flags; /* flags as above */
@@ -170,6 +170,7 @@ vfprintf(fp, fmt0, ap)
int width; /* width from format (%8d), or 0 */
int prec; /* precision from format (%.3d), or -1 */
char sign; /* sign prefix (' ', '+', '-', or \0) */
+ wchar_t wc;
#ifdef FLOATING_POINT
char *decimal_point = localeconv()->decimal_point;
char softsign; /* temporary negative sign for floats */
@@ -272,13 +273,19 @@ vfprintf(fp, fmt0, ap)
* Scan the format for conversions (`%' character).
*/
for (;;) {
- for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
- /* void */;
- if ((n = fmt - cp) != 0) {
- PRINT(cp, n);
- ret += n;
+ cp = fmt;
+ while ((n = mbtowc(&wc, fmt, MB_CUR_MAX)) > 0) {
+ fmt += n;
+ if (wc == '%') {
+ fmt--;
+ break;
+ }
+ }
+ if ((m = fmt - cp) != 0) {
+ PRINT(cp, m);
+ ret += m;
}
- if (ch == '\0')
+ if (n <= 0)
goto done;
fmt++; /* skip over '%' */