scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit d5f4c9d32392738c76bc040db5569c4f7f443708
parent 9a4739eeaaf26ade4ba17ecfd4a0699335df81b3
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon,  7 Nov 2022 16:40:59 +0100

libc/stdio: Count number of bytes for wide strings

The standard requires to count the number of bytes in printf
for wide character strings but as we were using fputc() it
was impossible to count them. This patch adds an internal
function used by printf() and by fputwc() that can return
the number of bytes actually written.

Diffstat:
Msrc/libc/libc.h | 3+++
Msrc/libc/stdio/vfprintf.c | 16+++++++++-------
Msrc/libc/wchar/fputwc.c | 12+++++++++++-
3 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/libc/libc.h b/src/libc/libc.h @@ -61,4 +61,7 @@ extern void (*_atexithdl)(void); #ifdef _WCHAR_H extern int _validutf8(wchar_t); +#ifdef _STDIO_H +extern wint_t _fputwc(wchar_t, FILE *, int *); +#endif #endif diff --git a/src/libc/stdio/vfprintf.c b/src/libc/stdio/vfprintf.c @@ -6,6 +6,8 @@ #include <string.h> #include <wchar.h> +#include "../libc.h" + #define MAXPREC 50 #undef vfprintf @@ -120,7 +122,7 @@ savecnt(va_list *va, int flags, size_t cnt) static size_t wstrout(wchar_t *ws, size_t len, int width, int fill, FILE *restrict fp) { - int left = 0, adjust; + int left = 0, adjust, n; size_t cnt = 0; wchar_t wc; @@ -134,18 +136,18 @@ wstrout(wchar_t *ws, size_t len, int width, int fill, FILE *restrict fp) adjust = -adjust; for ( ; adjust > 0; adjust--) { - putwc(fill, fp); - ++cnt; + _fputwc(fill, fp, &n); + cnt += n; } for ( ; len-- > 0 && (wc = *ws) != '\0'; ++ws) { - putwc(wc, fp); - ++cnt; + _fputwc(wc, fp, &n); + cnt += n; } for ( ; adjust < 0; adjust++) { - putwc(' ', fp); - ++cnt; + _fputwc(' ', fp, &n); + cnt += n; } return cnt; diff --git a/src/libc/wchar/fputwc.c b/src/libc/wchar/fputwc.c @@ -6,7 +6,7 @@ #undef fputwc wint_t -fputwc(wchar_t wc, FILE *fp) +_fputwc(wchar_t wc, FILE *fp, int *np) { int n; mbstate_t state; @@ -17,9 +17,19 @@ fputwc(wchar_t wc, FILE *fp) goto err; if (fwrite(buf, 1, n, fp) < n) goto err; + + if (np) + *np = n; + return wc; err: fp->flags |= _IOERR; return WEOF; } + +wint_t +fputwc(wchar_t wc, FILE *fp) +{ + return _fputwc(wc, fp, NULL); +}