diff options
| author | jtc <jtc@NetBSD.org> | 1995-05-02 19:52:41 +0000 |
|---|---|---|
| committer | jtc <jtc@NetBSD.org> | 1995-05-02 19:52:41 +0000 |
| commit | 615fb07b157b8da9d76f35a0bc709dc50fcec381 (patch) | |
| tree | cdd633ddef456ddb846d283055e9209f62da2ec8 /lib/libc/stdio/vfprintf.c | |
| parent | be2c7f3d132ac0681c07bfab5a099b4eb0bbb40b (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.c | 23 |
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 '%' */ |
