diff options
Diffstat (limited to 'src/stdio')
-rw-r--r-- | src/stdio/fgetwc.c | 15 | ||||
-rw-r--r-- | src/stdio/fputwc.c | 5 | ||||
-rw-r--r-- | src/stdio/fputws.c | 5 | ||||
-rw-r--r-- | src/stdio/fwide.c | 11 | ||||
-rw-r--r-- | src/stdio/ungetwc.c | 5 |
5 files changed, 33 insertions, 8 deletions
diff --git a/src/stdio/fgetwc.c b/src/stdio/fgetwc.c index b261b44f..e455cfec 100644 --- a/src/stdio/fgetwc.c +++ b/src/stdio/fgetwc.c @@ -1,8 +1,9 @@ #include "stdio_impl.h" +#include "locale_impl.h" #include <wchar.h> #include <errno.h> -wint_t __fgetwc_unlocked(FILE *f) +static wint_t __fgetwc_unlocked_internal(FILE *f) { mbstate_t st = { 0 }; wchar_t wc; @@ -10,8 +11,6 @@ wint_t __fgetwc_unlocked(FILE *f) unsigned char b; size_t l; - if (f->mode <= 0) fwide(f, 1); - /* Convert character from buffer if possible */ if (f->rpos < f->rend) { l = mbrtowc(&wc, (void *)f->rpos, f->rend - f->rpos, &st); @@ -39,6 +38,16 @@ wint_t __fgetwc_unlocked(FILE *f) return wc; } +wint_t __fgetwc_unlocked(FILE *f) +{ + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc; + if (f->mode <= 0) fwide(f, 1); + *ploc = f->locale; + wchar_t wc = __fgetwc_unlocked_internal(f); + *ploc = loc; + return wc; +} + wint_t fgetwc(FILE *f) { wint_t c; diff --git a/src/stdio/fputwc.c b/src/stdio/fputwc.c index 1bf165bf..789fe9c9 100644 --- a/src/stdio/fputwc.c +++ b/src/stdio/fputwc.c @@ -1,4 +1,5 @@ #include "stdio_impl.h" +#include "locale_impl.h" #include <wchar.h> #include <limits.h> #include <ctype.h> @@ -7,8 +8,10 @@ wint_t __fputwc_unlocked(wchar_t c, FILE *f) { char mbc[MB_LEN_MAX]; int l; + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc; if (f->mode <= 0) fwide(f, 1); + *ploc = f->locale; if (isascii(c)) { c = putc_unlocked(c, f); @@ -20,6 +23,8 @@ wint_t __fputwc_unlocked(wchar_t c, FILE *f) l = wctomb(mbc, c); if (l < 0 || __fwritex((void *)mbc, l, f) < l) c = WEOF; } + if (c==WEOF) f->flags |= F_ERR; + *ploc = loc; return c; } diff --git a/src/stdio/fputws.c b/src/stdio/fputws.c index 317d65f1..0ed02f1c 100644 --- a/src/stdio/fputws.c +++ b/src/stdio/fputws.c @@ -1,23 +1,28 @@ #include "stdio_impl.h" +#include "locale_impl.h" #include <wchar.h> int fputws(const wchar_t *restrict ws, FILE *restrict f) { unsigned char buf[BUFSIZ]; size_t l=0; + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc; FLOCK(f); fwide(f, 1); + *ploc = f->locale; while (ws && (l = wcsrtombs((void *)buf, (void*)&ws, sizeof buf, 0))+1 > 1) if (__fwritex(buf, l, f) < l) { FUNLOCK(f); + *ploc = loc; return -1; } FUNLOCK(f); + *ploc = loc; return l; /* 0 or -1 */ } diff --git a/src/stdio/fwide.c b/src/stdio/fwide.c index 8088e7ad..8410b153 100644 --- a/src/stdio/fwide.c +++ b/src/stdio/fwide.c @@ -1,13 +1,14 @@ -#include <wchar.h> #include "stdio_impl.h" - -#define SH (8*sizeof(int)-1) -#define NORMALIZE(x) ((x)>>SH | -((-(x))>>SH)) +#include "locale_impl.h" int fwide(FILE *f, int mode) { FLOCK(f); - if (!f->mode) f->mode = NORMALIZE(mode); + if (mode) { + if (!f->locale) f->locale = MB_CUR_MAX==1 + ? C_LOCALE : UTF8_LOCALE; + if (!f->mode) f->mode = mode>0 ? 1 : -1; + } mode = f->mode; FUNLOCK(f); return mode; diff --git a/src/stdio/ungetwc.c b/src/stdio/ungetwc.c index d4c7de39..80d6e203 100644 --- a/src/stdio/ungetwc.c +++ b/src/stdio/ungetwc.c @@ -1,4 +1,5 @@ #include "stdio_impl.h" +#include "locale_impl.h" #include <wchar.h> #include <limits.h> #include <ctype.h> @@ -8,15 +9,18 @@ wint_t ungetwc(wint_t c, FILE *f) { unsigned char mbc[MB_LEN_MAX]; int l=1; + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc; FLOCK(f); if (f->mode <= 0) fwide(f, 1); + *ploc = f->locale; if (!f->rpos) __toread(f); if (!f->rpos || f->rpos < f->buf - UNGET + l || c == WEOF || (!isascii(c) && (l = wctomb((void *)mbc, c)) < 0)) { FUNLOCK(f); + *ploc = loc; return WEOF; } @@ -26,5 +30,6 @@ wint_t ungetwc(wint_t c, FILE *f) f->flags &= ~F_EOF; FUNLOCK(f); + *ploc = loc; return c; } |