summaryrefslogtreecommitdiff
path: root/src/stdio
diff options
context:
space:
mode:
Diffstat (limited to 'src/stdio')
-rw-r--r--src/stdio/fgetwc.c15
-rw-r--r--src/stdio/fputwc.c5
-rw-r--r--src/stdio/fputws.c5
-rw-r--r--src/stdio/fwide.c11
-rw-r--r--src/stdio/ungetwc.c5
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;
}