summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio
diff options
context:
space:
mode:
authortheraven <theraven@FreeBSD.org>2011-11-20 14:45:42 +0000
committertheraven <theraven@FreeBSD.org>2011-11-20 14:45:42 +0000
commit0f6ef690b3118882121ed67561c7ce2660cfebe1 (patch)
tree909189922493cddbeeac84af2e316dc897661311 /lib/libc/stdio
parent18b29f3fb8abee5d57ed8f4a44f806bec7e0eeff (diff)
downloadFreeBSD-src-0f6ef690b3118882121ed67561c7ce2660cfebe1.zip
FreeBSD-src-0f6ef690b3118882121ed67561c7ce2660cfebe1.tar.gz
Implement xlocale APIs from Darwin, mainly for use by libc++. This adds a
load of _l suffixed versions of various standard library functions that use the global locale, making them take an explicit locale parameter. Also adds support for per-thread locales. This work was funded by the FreeBSD Foundation. Please test any code you have that uses the C standard locale functions! Reviewed by: das (gdtoa changes) Approved by: dim (mentor)
Diffstat (limited to 'lib/libc/stdio')
-rw-r--r--lib/libc/stdio/Symbol.map40
-rw-r--r--lib/libc/stdio/asprintf.c18
-rw-r--r--lib/libc/stdio/fgetwc.c21
-rw-r--r--lib/libc/stdio/fgetwln.c16
-rw-r--r--lib/libc/stdio/fgetws.c18
-rw-r--r--lib/libc/stdio/fprintf.c20
-rw-r--r--lib/libc/stdio/fputwc.c20
-rw-r--r--lib/libc/stdio/fputws.c17
-rw-r--r--lib/libc/stdio/fscanf.c22
-rw-r--r--lib/libc/stdio/fwprintf.c18
-rw-r--r--lib/libc/stdio/fwscanf.c18
-rw-r--r--lib/libc/stdio/getwc.c12
-rw-r--r--lib/libc/stdio/getwchar.c12
-rw-r--r--lib/libc/stdio/local.h20
-rw-r--r--lib/libc/stdio/printf.c17
-rw-r--r--lib/libc/stdio/printfcommon.h24
-rw-r--r--lib/libc/stdio/putwc.c15
-rw-r--r--lib/libc/stdio/putwchar.c15
-rw-r--r--lib/libc/stdio/scanf.c22
-rw-r--r--lib/libc/stdio/snprintf.c33
-rw-r--r--lib/libc/stdio/sprintf.c19
-rw-r--r--lib/libc/stdio/sscanf.c18
-rw-r--r--lib/libc/stdio/swprintf.c19
-rw-r--r--lib/libc/stdio/swscanf.c19
-rw-r--r--lib/libc/stdio/ungetwc.c21
-rw-r--r--lib/libc/stdio/vasprintf.c16
-rw-r--r--lib/libc/stdio/vdprintf.c8
-rw-r--r--lib/libc/stdio/vfprintf.c62
-rw-r--r--lib/libc/stdio/vfscanf.c51
-rw-r--r--lib/libc/stdio/vfwprintf.c80
-rw-r--r--lib/libc/stdio/vfwscanf.c88
-rw-r--r--lib/libc/stdio/vprintf.c12
-rw-r--r--lib/libc/stdio/vscanf.c19
-rw-r--r--lib/libc/stdio/vsnprintf.c19
-rw-r--r--lib/libc/stdio/vsprintf.c17
-rw-r--r--lib/libc/stdio/vsscanf.c19
-rw-r--r--lib/libc/stdio/vswprintf.c21
-rw-r--r--lib/libc/stdio/vswscanf.c21
-rw-r--r--lib/libc/stdio/vwprintf.c12
-rw-r--r--lib/libc/stdio/vwscanf.c12
-rw-r--r--lib/libc/stdio/wprintf.c18
-rw-r--r--lib/libc/stdio/wscanf.c18
42 files changed, 805 insertions, 182 deletions
diff --git a/lib/libc/stdio/Symbol.map b/lib/libc/stdio/Symbol.map
index df66ab3..cafb0c6 100644
--- a/lib/libc/stdio/Symbol.map
+++ b/lib/libc/stdio/Symbol.map
@@ -117,6 +117,46 @@ FBSD_1.1 {
vdprintf;
};
+FBSD_1.3 {
+ asprintf_l;
+ fprintf_l;
+ fwprintf_l;
+ printf_l;
+ snprintf_l;
+ sprintf_l;
+ swprintf_l;
+ vasprintf_l;
+ vfprintf_l;
+ vfwprintf_l;
+ vprintf_l;
+ vsnprintf_l;
+ vsprintf_l;
+ vswprintf_l;
+ vwprintf_l;
+ wprintf_l;
+ fgetwc_l;
+ fputwc_l;
+ ungetwc_l;
+ vfwscanf_l;
+ vswscanf_l;
+ fscanf_l;
+ fwscanf_l;
+ scanf_l;
+ sscanf_l;
+ swscanf_l;
+ vfscanf_l;
+ vscanf_l;
+ vsscanf_l;
+ vwscanf_l;
+ wscanf_l;
+ fgetws_l;
+ fputws_l;
+ getwc_l;
+ getwchar_l;
+ putwc_l;
+ putwchar_l;
+};
+
FBSDprivate_1.0 {
_flockfile;
_flockfile_debug_stub;
diff --git a/lib/libc/stdio/asprintf.c b/lib/libc/stdio/asprintf.c
index 90c62bc..cd475cd 100644
--- a/lib/libc/stdio/asprintf.c
+++ b/lib/libc/stdio/asprintf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -35,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdarg.h>
+#include <xlocale.h>
int
asprintf(char ** __restrict s, char const * __restrict fmt, ...)
@@ -47,3 +53,15 @@ asprintf(char ** __restrict s, char const * __restrict fmt, ...)
va_end(ap);
return (ret);
}
+int
+asprintf_l(char ** __restrict s, locale_t locale, char const * __restrict fmt,
+ ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vasprintf_l(s, locale, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libc/stdio/fgetwc.c b/lib/libc/stdio/fgetwc.c
index 3a5b09b..0e87753 100644
--- a/lib/libc/stdio/fgetwc.c
+++ b/lib/libc/stdio/fgetwc.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -36,31 +41,39 @@ __FBSDID("$FreeBSD$");
#include "libc_private.h"
#include "local.h"
#include "mblocal.h"
+#include "xlocale_private.h"
/*
* MT-safe version.
*/
wint_t
-fgetwc(FILE *fp)
+fgetwc_l(FILE *fp, locale_t locale)
{
wint_t r;
+ FIX_LOCALE(locale);
FLOCKFILE(fp);
ORIENT(fp, 1);
- r = __fgetwc(fp);
+ r = __fgetwc(fp, locale);
FUNLOCKFILE(fp);
return (r);
}
+wint_t
+fgetwc(FILE *fp)
+{
+ return fgetwc_l(fp, __get_locale());
+}
/*
* Non-MT-safe version.
*/
wint_t
-__fgetwc(FILE *fp)
+__fgetwc(FILE *fp, locale_t locale)
{
wchar_t wc;
size_t nconv;
+ struct xlocale_ctype *l = XLOCALE_CTYPE(locale);
if (fp->_r <= 0 && __srefill(fp))
return (WEOF);
@@ -71,7 +84,7 @@ __fgetwc(FILE *fp)
return (wc);
}
do {
- nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_mbstate);
+ nconv = l->__mbrtowc(&wc, fp->_p, fp->_r, &fp->_mbstate);
if (nconv == (size_t)-1)
break;
else if (nconv == (size_t)-2)
diff --git a/lib/libc/stdio/fgetwln.c b/lib/libc/stdio/fgetwln.c
index 1a1ad2d..6d9087b 100644
--- a/lib/libc/stdio/fgetwln.c
+++ b/lib/libc/stdio/fgetwln.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -33,18 +38,20 @@ __FBSDID("$FreeBSD$");
#include "un-namespace.h"
#include "libc_private.h"
#include "local.h"
+#include "xlocale_private.h"
wchar_t *
-fgetwln(FILE * __restrict fp, size_t *lenp)
+fgetwln_l(FILE * __restrict fp, size_t *lenp, locale_t locale)
{
wint_t wc;
size_t len;
+ FIX_LOCALE(locale);
FLOCKFILE(fp);
ORIENT(fp, 1);
len = 0;
- while ((wc = __fgetwc(fp)) != WEOF) {
+ while ((wc = __fgetwc(fp, locale)) != WEOF) {
#define GROW 512
if (len * sizeof(wchar_t) >= fp->_lb._size &&
__slbexpand(fp, (len + GROW) * sizeof(wchar_t)))
@@ -65,3 +72,8 @@ error:
*lenp = 0;
return (NULL);
}
+wchar_t *
+fgetwln(FILE * __restrict fp, size_t *lenp)
+{
+ return fgetwln_l(fp, lenp, __get_locale());
+}
diff --git a/lib/libc/stdio/fgetws.c b/lib/libc/stdio/fgetws.c
index 550843d..f7a63fe 100644
--- a/lib/libc/stdio/fgetws.c
+++ b/lib/libc/stdio/fgetws.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -38,12 +43,14 @@ __FBSDID("$FreeBSD$");
#include "mblocal.h"
wchar_t *
-fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp)
+fgetws_l(wchar_t * __restrict ws, int n, FILE * __restrict fp, locale_t locale)
{
wchar_t *wsp;
size_t nconv;
const char *src;
unsigned char *nl;
+ FIX_LOCALE(locale);
+ struct xlocale_ctype *l = XLOCALE_CTYPE(locale);
FLOCKFILE(fp);
ORIENT(fp, 1);
@@ -60,7 +67,7 @@ fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp)
do {
src = fp->_p;
nl = memchr(fp->_p, '\n', fp->_r);
- nconv = __mbsnrtowcs(wsp, &src,
+ nconv = l->__mbsnrtowcs(wsp, &src,
nl != NULL ? (nl - fp->_p + 1) : fp->_r,
n - 1, &fp->_mbstate);
if (nconv == (size_t)-1)
@@ -86,7 +93,7 @@ fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp)
if (wsp == ws)
/* EOF */
goto error;
- if (!__mbsinit(&fp->_mbstate))
+ if (!l->__mbsinit(&fp->_mbstate))
/* Incomplete character */
goto error;
*wsp = L'\0';
@@ -98,3 +105,8 @@ error:
FUNLOCKFILE(fp);
return (NULL);
}
+wchar_t *
+fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp)
+{
+ return fgetws_l(ws, n, fp, __get_locale());
+}
diff --git a/lib/libc/stdio/fprintf.c b/lib/libc/stdio/fprintf.c
index bebc182..169532d 100644
--- a/lib/libc/stdio/fprintf.c
+++ b/lib/libc/stdio/fprintf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -38,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdarg.h>
+#include "xlocale_private.h"
int
fprintf(FILE * __restrict fp, const char * __restrict fmt, ...)
@@ -46,7 +52,19 @@ fprintf(FILE * __restrict fp, const char * __restrict fmt, ...)
va_list ap;
va_start(ap, fmt);
- ret = vfprintf(fp, fmt, ap);
+ ret = vfprintf_l(fp, __get_locale(), fmt, ap);
+ va_end(ap);
+ return (ret);
+}
+int
+fprintf_l(FILE * __restrict fp, locale_t locale, const char * __restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+ FIX_LOCALE(locale);
+
+ va_start(ap, fmt);
+ ret = vfprintf_l(fp, locale, fmt, ap);
va_end(ap);
return (ret);
}
diff --git a/lib/libc/stdio/fputwc.c b/lib/libc/stdio/fputwc.c
index ae92f66..7b05d4a 100644
--- a/lib/libc/stdio/fputwc.c
+++ b/lib/libc/stdio/fputwc.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -42,10 +47,11 @@ __FBSDID("$FreeBSD$");
* Non-MT-safe version.
*/
wint_t
-__fputwc(wchar_t wc, FILE *fp)
+__fputwc(wchar_t wc, FILE *fp, locale_t locale)
{
char buf[MB_LEN_MAX];
size_t i, len;
+ struct xlocale_ctype *l = XLOCALE_CTYPE(locale);
if (MB_CUR_MAX == 1 && wc > 0 && wc <= UCHAR_MAX) {
/*
@@ -56,7 +62,7 @@ __fputwc(wchar_t wc, FILE *fp)
*buf = (unsigned char)wc;
len = 1;
} else {
- if ((len = __wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) {
+ if ((len = l->__wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) {
fp->_flags |= __SERR;
return (WEOF);
}
@@ -73,14 +79,20 @@ __fputwc(wchar_t wc, FILE *fp)
* MT-safe version.
*/
wint_t
-fputwc(wchar_t wc, FILE *fp)
+fputwc_l(wchar_t wc, FILE *fp, locale_t locale)
{
wint_t r;
+ FIX_LOCALE(locale);
FLOCKFILE(fp);
ORIENT(fp, 1);
- r = __fputwc(wc, fp);
+ r = __fputwc(wc, fp, locale);
FUNLOCKFILE(fp);
return (r);
}
+wint_t
+fputwc(wchar_t wc, FILE *fp)
+{
+ return fputwc_l(wc, fp, __get_locale());
+}
diff --git a/lib/libc/stdio/fputws.c b/lib/libc/stdio/fputws.c
index b4462b7..a318e2d 100644
--- a/lib/libc/stdio/fputws.c
+++ b/lib/libc/stdio/fputws.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -39,13 +44,15 @@ __FBSDID("$FreeBSD$");
#include "mblocal.h"
int
-fputws(const wchar_t * __restrict ws, FILE * __restrict fp)
+fputws_l(const wchar_t * __restrict ws, FILE * __restrict fp, locale_t locale)
{
size_t nbytes;
char buf[BUFSIZ];
struct __suio uio;
struct __siov iov;
const wchar_t *wsp;
+ FIX_LOCALE(locale);
+ struct xlocale_ctype *l = XLOCALE_CTYPE(locale);
FLOCKFILE(fp);
ORIENT(fp, 1);
@@ -56,7 +63,7 @@ fputws(const wchar_t * __restrict ws, FILE * __restrict fp)
iov.iov_base = buf;
do {
wsp = ws;
- nbytes = __wcsnrtombs(buf, &wsp, SIZE_T_MAX, sizeof(buf),
+ nbytes = l->__wcsnrtombs(buf, &wsp, SIZE_T_MAX, sizeof(buf),
&fp->_mbstate);
if (nbytes == (size_t)-1)
goto error;
@@ -71,3 +78,9 @@ error:
FUNLOCKFILE(fp);
return (-1);
}
+
+int
+fputws(const wchar_t * __restrict ws, FILE * __restrict fp)
+{
+ return fputws_l(ws, fp, __get_locale());
+}
diff --git a/lib/libc/stdio/fscanf.c b/lib/libc/stdio/fscanf.c
index ce3001a..c5fa85f 100644
--- a/lib/libc/stdio/fscanf.c
+++ b/lib/libc/stdio/fscanf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -42,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include "un-namespace.h"
#include "libc_private.h"
#include "local.h"
+#include "xlocale_private.h"
int
fscanf(FILE * __restrict fp, char const * __restrict fmt, ...)
@@ -51,7 +57,21 @@ fscanf(FILE * __restrict fp, char const * __restrict fmt, ...)
va_start(ap, fmt);
FLOCKFILE(fp);
- ret = __svfscanf(fp, fmt, ap);
+ ret = __svfscanf(fp, __get_locale(), fmt, ap);
+ va_end(ap);
+ FUNLOCKFILE(fp);
+ return (ret);
+}
+int
+fscanf_l(FILE * __restrict fp, locale_t locale, char const * __restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+ FIX_LOCALE(locale);
+
+ va_start(ap, fmt);
+ FLOCKFILE(fp);
+ ret = __svfscanf(fp, locale, fmt, ap);
va_end(ap);
FUNLOCKFILE(fp);
return (ret);
diff --git a/lib/libc/stdio/fwprintf.c b/lib/libc/stdio/fwprintf.c
index a22edae..f4342ab 100644
--- a/lib/libc/stdio/fwprintf.c
+++ b/lib/libc/stdio/fwprintf.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002 Tim J. Robbins
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -30,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <stdarg.h>
#include <stdio.h>
#include <wchar.h>
+#include <xlocale.h>
int
fwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt, ...)
@@ -43,3 +49,15 @@ fwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt, ...)
return (ret);
}
+int
+fwprintf_l(FILE * __restrict fp, locale_t locale, const wchar_t * __restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vfwprintf_l(fp, locale, fmt, ap);
+ va_end(ap);
+
+ return (ret);
+}
diff --git a/lib/libc/stdio/fwscanf.c b/lib/libc/stdio/fwscanf.c
index f779c53..1756077 100644
--- a/lib/libc/stdio/fwscanf.c
+++ b/lib/libc/stdio/fwscanf.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002 Tim J. Robbins
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -30,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <stdarg.h>
#include <stdio.h>
#include <wchar.h>
+#include <xlocale.h>
int
fwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, ...)
@@ -43,3 +49,15 @@ fwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, ...)
return (r);
}
+int
+fwscanf_l(FILE * __restrict fp, locale_t locale, const wchar_t * __restrict fmt, ...)
+{
+ va_list ap;
+ int r;
+
+ va_start(ap, fmt);
+ r = vfwscanf_l(fp, locale, fmt, ap);
+ va_end(ap);
+
+ return (r);
+}
diff --git a/lib/libc/stdio/getwc.c b/lib/libc/stdio/getwc.c
index ba5ab60..666350b 100644
--- a/lib/libc/stdio/getwc.c
+++ b/lib/libc/stdio/getwc.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002 Tim J. Robbins.
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -30,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include "namespace.h"
#include <stdio.h>
#include <wchar.h>
+#include <xlocale.h>
#include "un-namespace.h"
#include "libc_private.h"
#include "local.h"
@@ -46,3 +52,9 @@ getwc(FILE *fp)
return (fgetwc(fp));
}
+wint_t
+getwc_l(FILE *fp, locale_t locale)
+{
+
+ return (fgetwc_l(fp, locale));
+}
diff --git a/lib/libc/stdio/getwchar.c b/lib/libc/stdio/getwchar.c
index 79dd7bc..bc3b8a6 100644
--- a/lib/libc/stdio/getwchar.c
+++ b/lib/libc/stdio/getwchar.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002 Tim J. Robbins.
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -30,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include "namespace.h"
#include <stdio.h>
#include <wchar.h>
+#include <xlocale.h>
#include "un-namespace.h"
#include "libc_private.h"
#include "local.h"
@@ -42,6 +48,10 @@ __FBSDID("$FreeBSD$");
wint_t
getwchar(void)
{
-
return (fgetwc(stdin));
}
+wint_t
+getwchar_l(locale_t locale)
+{
+ return (fgetwc_l(stdin, locale));
+}
diff --git a/lib/libc/stdio/local.h b/lib/libc/stdio/local.h
index 6380b83..8b37f0d 100644
--- a/lib/libc/stdio/local.h
+++ b/lib/libc/stdio/local.h
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -37,6 +42,7 @@
#include <pthread.h>
#include <string.h>
#include <wchar.h>
+#include <locale.h>
/*
* Information local to this implementation of stdio,
@@ -50,8 +56,8 @@ extern int _ftello(FILE *, fpos_t *);
extern int _fseeko(FILE *, off_t, int, int);
extern int __fflush(FILE *fp);
extern void __fcloseall(void);
-extern wint_t __fgetwc(FILE *);
-extern wint_t __fputwc(wchar_t, FILE *);
+extern wint_t __fgetwc(FILE *, locale_t);
+extern wint_t __fputwc(wchar_t, FILE *, locale_t);
extern int __sflush(FILE *);
extern FILE *__sfp(void);
extern int __slbexpand(FILE *, size_t);
@@ -65,15 +71,15 @@ extern void _cleanup(void);
extern void __smakebuf(FILE *);
extern int __swhatbuf(FILE *, size_t *, int *);
extern int _fwalk(int (*)(FILE *));
-extern int __svfscanf(FILE *, const char *, __va_list);
+extern int __svfscanf(FILE *, locale_t, const char *, __va_list);
extern int __swsetup(FILE *);
extern int __sflags(const char *, int *);
extern int __ungetc(int, FILE *);
-extern wint_t __ungetwc(wint_t, FILE *);
-extern int __vfprintf(FILE *, const char *, __va_list);
+extern wint_t __ungetwc(wint_t, FILE *, locale_t);
+extern int __vfprintf(FILE *, locale_t, const char *, __va_list);
extern int __vfscanf(FILE *, const char *, __va_list);
-extern int __vfwprintf(FILE *, const wchar_t *, __va_list);
-extern int __vfwscanf(FILE * __restrict, const wchar_t * __restrict,
+extern int __vfwprintf(FILE *, locale_t, const wchar_t *, __va_list);
+extern int __vfwscanf(FILE * __restrict, locale_t, const wchar_t * __restrict,
__va_list);
extern size_t __fread(void * __restrict buf, size_t size, size_t count,
FILE * __restrict fp);
diff --git a/lib/libc/stdio/printf.c b/lib/libc/stdio/printf.c
index df290fa..f623f2f 100644
--- a/lib/libc/stdio/printf.c
+++ b/lib/libc/stdio/printf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -38,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdarg.h>
+#include <xlocale.h>
int
printf(char const * __restrict fmt, ...)
@@ -50,3 +56,14 @@ printf(char const * __restrict fmt, ...)
va_end(ap);
return (ret);
}
+int
+printf_l(locale_t locale, char const * __restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vfprintf_l(stdout, locale, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libc/stdio/printfcommon.h b/lib/libc/stdio/printfcommon.h
index 39b0003..97acc53 100644
--- a/lib/libc/stdio/printfcommon.h
+++ b/lib/libc/stdio/printfcommon.h
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -79,14 +84,14 @@ io_init(struct io_state *iop, FILE *fp)
* remain valid until io_flush() is called.
*/
static inline int
-io_print(struct io_state *iop, const CHAR * __restrict ptr, int len)
+io_print(struct io_state *iop, const CHAR * __restrict ptr, int len, locale_t locale)
{
iop->iov[iop->uio.uio_iovcnt].iov_base = (char *)ptr;
iop->iov[iop->uio.uio_iovcnt].iov_len = len;
iop->uio.uio_resid += len;
if (++iop->uio.uio_iovcnt >= NIOV)
- return (__sprint(iop->fp, &iop->uio));
+ return (__sprint(iop->fp, &iop->uio, locale));
else
return (0);
}
@@ -107,13 +112,14 @@ static const CHAR zeroes[PADSIZE] =
* or the zeroes array.
*/
static inline int
-io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with)
+io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with,
+ locale_t locale)
{
int n;
while (howmany > 0) {
n = (howmany >= PADSIZE) ? PADSIZE : howmany;
- if (io_print(iop, with, n))
+ if (io_print(iop, with, n, locale))
return (-1);
howmany -= n;
}
@@ -126,7 +132,7 @@ io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with)
*/
static inline int
io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep,
- int len, const CHAR * __restrict with)
+ int len, const CHAR * __restrict with, locale_t locale)
{
int p_len;
@@ -134,19 +140,19 @@ io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep,
if (p_len > len)
p_len = len;
if (p_len > 0) {
- if (io_print(iop, p, p_len))
+ if (io_print(iop, p, p_len, locale))
return (-1);
} else {
p_len = 0;
}
- return (io_pad(iop, len - p_len, with));
+ return (io_pad(iop, len - p_len, with, locale));
}
static inline int
-io_flush(struct io_state *iop)
+io_flush(struct io_state *iop, locale_t locale)
{
- return (__sprint(iop->fp, &iop->uio));
+ return (__sprint(iop->fp, &iop->uio, locale));
}
/*
diff --git a/lib/libc/stdio/putwc.c b/lib/libc/stdio/putwc.c
index 8fe065b..56acf50 100644
--- a/lib/libc/stdio/putwc.c
+++ b/lib/libc/stdio/putwc.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002 Tim J. Robbins.
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -33,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include "un-namespace.h"
#include "libc_private.h"
#include "local.h"
+#include "xlocale_private.h"
#undef putwc
@@ -41,8 +47,13 @@ __FBSDID("$FreeBSD$");
* macro, may evaluate `fp' more than once.
*/
wint_t
+putwc_l(wchar_t wc, FILE *fp, locale_t locale)
+{
+ FIX_LOCALE(locale);
+ return (fputwc_l(wc, fp, locale));
+}
+wint_t
putwc(wchar_t wc, FILE *fp)
{
-
- return (fputwc(wc, fp));
+ return putwc_l(wc, fp, __get_locale());
}
diff --git a/lib/libc/stdio/putwchar.c b/lib/libc/stdio/putwchar.c
index 5503071..8673bd5 100644
--- a/lib/libc/stdio/putwchar.c
+++ b/lib/libc/stdio/putwchar.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002 Tim J. Robbins.
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -33,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include "un-namespace.h"
#include "libc_private.h"
#include "local.h"
+#include "xlocale_private.h"
#undef putwchar
@@ -40,8 +46,13 @@ __FBSDID("$FreeBSD$");
* Synonym for fputwc(wc, stdout).
*/
wint_t
+putwchar_l(wchar_t wc, locale_t locale)
+{
+ FIX_LOCALE(locale);
+ return (fputwc_l(wc, stdout, locale));
+}
+wint_t
putwchar(wchar_t wc)
{
-
- return (fputwc(wc, stdout));
+ return putwchar_l(wc, __get_locale());
}
diff --git a/lib/libc/stdio/scanf.c b/lib/libc/stdio/scanf.c
index 4ae88da..ba33caa 100644
--- a/lib/libc/stdio/scanf.c
+++ b/lib/libc/stdio/scanf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -42,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include "un-namespace.h"
#include "libc_private.h"
#include "local.h"
+#include "xlocale_private.h"
int
scanf(char const * __restrict fmt, ...)
@@ -51,7 +57,21 @@ scanf(char const * __restrict fmt, ...)
va_start(ap, fmt);
FLOCKFILE(stdin);
- ret = __svfscanf(stdin, fmt, ap);
+ ret = __svfscanf(stdin, __get_locale(), fmt, ap);
+ FUNLOCKFILE(stdin);
+ va_end(ap);
+ return (ret);
+}
+int
+scanf_l(locale_t locale, char const * __restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+ FIX_LOCALE(locale);
+
+ va_start(ap, fmt);
+ FLOCKFILE(stdin);
+ ret = __svfscanf(stdin, locale, fmt, ap);
FUNLOCKFILE(stdin);
va_end(ap);
return (ret);
diff --git a/lib/libc/stdio/snprintf.c b/lib/libc/stdio/snprintf.c
index e6d7115..74af42d 100644
--- a/lib/libc/stdio/snprintf.c
+++ b/lib/libc/stdio/snprintf.c
@@ -2,6 +2,11 @@
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
@@ -39,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <limits.h>
#include <stdio.h>
#include <stdarg.h>
+#include "xlocale_private.h"
#include "local.h"
@@ -59,7 +65,32 @@ snprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...)
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = n;
- ret = __vfprintf(&f, fmt, ap);
+ ret = __vfprintf(&f, __get_locale(), fmt, ap);
+ if (on > 0)
+ *f._p = '\0';
+ va_end(ap);
+ return (ret);
+}
+int
+snprintf_l(char * __restrict str, size_t n, locale_t locale,
+ char const * __restrict fmt, ...)
+{
+ size_t on;
+ int ret;
+ va_list ap;
+ FILE f = FAKE_FILE;
+ FIX_LOCALE(locale);
+
+ on = n;
+ if (n != 0)
+ n--;
+ if (n > INT_MAX)
+ n = INT_MAX;
+ va_start(ap, fmt);
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = n;
+ ret = __vfprintf(&f, locale, fmt, ap);
if (on > 0)
*f._p = '\0';
va_end(ap);
diff --git a/lib/libc/stdio/sprintf.c b/lib/libc/stdio/sprintf.c
index b55bd6c..6e20e04 100644
--- a/lib/libc/stdio/sprintf.c
+++ b/lib/libc/stdio/sprintf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -40,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <stdarg.h>
#include <limits.h>
#include "local.h"
+#include "xlocale_private.h"
int
sprintf(char * __restrict str, char const * __restrict fmt, ...)
@@ -52,3 +58,16 @@ sprintf(char * __restrict str, char const * __restrict fmt, ...)
va_end(ap);
return (ret);
}
+int
+sprintf_l(char * __restrict str, locale_t locale, char const * __restrict fmt,
+ ...)
+{
+ int ret;
+ va_list ap;
+ FIX_LOCALE(locale);
+
+ va_start(ap, fmt);
+ ret = vsprintf_l(str, locale, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libc/stdio/sscanf.c b/lib/libc/stdio/sscanf.c
index c793b86..1c339eb 100644
--- a/lib/libc/stdio/sscanf.c
+++ b/lib/libc/stdio/sscanf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -39,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
+#include <xlocale.h>
#include "local.h"
int
@@ -52,3 +58,15 @@ sscanf(const char * __restrict str, char const * __restrict fmt, ...)
va_end(ap);
return (ret);
}
+int
+sscanf_l(const char * __restrict str, locale_t locale,
+ char const * __restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vsscanf_l(str, locale, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libc/stdio/swprintf.c b/lib/libc/stdio/swprintf.c
index d665318..1f6ecc6 100644
--- a/lib/libc/stdio/swprintf.c
+++ b/lib/libc/stdio/swprintf.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002 Tim J. Robbins
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -30,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <stdarg.h>
#include <stdio.h>
#include <wchar.h>
+#include <xlocale.h>
int
swprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, ...)
@@ -43,3 +49,16 @@ swprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, ...)
return (ret);
}
+int
+swprintf_l(wchar_t * __restrict s, size_t n, locale_t locale,
+ const wchar_t * __restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vswprintf_l(s, n, locale, fmt, ap);
+ va_end(ap);
+
+ return (ret);
+}
diff --git a/lib/libc/stdio/swscanf.c b/lib/libc/stdio/swscanf.c
index 728a3d6..c305ac1 100644
--- a/lib/libc/stdio/swscanf.c
+++ b/lib/libc/stdio/swscanf.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002 Tim J. Robbins
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -30,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <stdarg.h>
#include <stdio.h>
#include <wchar.h>
+#include <xlocale.h>
int
swscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, ...)
@@ -43,3 +49,16 @@ swscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, ...)
return (r);
}
+int
+swscanf_l(const wchar_t * __restrict str, locale_t locale,
+ const wchar_t * __restrict fmt, ...)
+{
+ va_list ap;
+ int r;
+
+ va_start(ap, fmt);
+ r = vswscanf_l(str, locale, fmt, ap);
+ va_end(ap);
+
+ return (r);
+}
diff --git a/lib/libc/stdio/ungetwc.c b/lib/libc/stdio/ungetwc.c
index 10dbbbf..78bc38d 100644
--- a/lib/libc/stdio/ungetwc.c
+++ b/lib/libc/stdio/ungetwc.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -37,19 +42,21 @@ __FBSDID("$FreeBSD$");
#include "libc_private.h"
#include "local.h"
#include "mblocal.h"
+#include "xlocale_private.h"
/*
* Non-MT-safe version.
*/
wint_t
-__ungetwc(wint_t wc, FILE *fp)
+__ungetwc(wint_t wc, FILE *fp, locale_t locale)
{
char buf[MB_LEN_MAX];
size_t len;
+ struct xlocale_ctype *l = XLOCALE_CTYPE(locale);
if (wc == WEOF)
return (WEOF);
- if ((len = __wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) {
+ if ((len = l->__wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) {
fp->_flags |= __SERR;
return (WEOF);
}
@@ -64,14 +71,20 @@ __ungetwc(wint_t wc, FILE *fp)
* MT-safe version.
*/
wint_t
-ungetwc(wint_t wc, FILE *fp)
+ungetwc_l(wint_t wc, FILE *fp, locale_t locale)
{
wint_t r;
+ FIX_LOCALE(locale);
FLOCKFILE(fp);
ORIENT(fp, 1);
- r = __ungetwc(wc, fp);
+ r = __ungetwc(wc, fp, locale);
FUNLOCKFILE(fp);
return (r);
}
+wint_t
+ungetwc(wint_t wc, FILE *fp)
+{
+ return ungetwc_l(wc, fp, __get_locale());
+}
diff --git a/lib/libc/stdio/vasprintf.c b/lib/libc/stdio/vasprintf.c
index a1b600a..8feb23d 100644
--- a/lib/libc/stdio/vasprintf.c
+++ b/lib/libc/stdio/vasprintf.c
@@ -4,6 +4,11 @@
* Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -33,13 +38,15 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
+#include "xlocale_private.h"
#include "local.h"
int
-vasprintf(char **str, const char *fmt, __va_list ap)
+vasprintf_l(char **str, locale_t locale, const char *fmt, __va_list ap)
{
FILE f = FAKE_FILE;
int ret;
+ FIX_LOCALE(locale);
f._flags = __SWR | __SSTR | __SALC;
f._bf._base = f._p = malloc(128);
@@ -49,7 +56,7 @@ vasprintf(char **str, const char *fmt, __va_list ap)
return (-1);
}
f._bf._size = f._w = 127; /* Leave room for the NUL */
- ret = __vfprintf(&f, fmt, ap);
+ ret = __vfprintf(&f, locale, fmt, ap);
if (ret < 0) {
free(f._bf._base);
*str = NULL;
@@ -60,3 +67,8 @@ vasprintf(char **str, const char *fmt, __va_list ap)
*str = (char *)f._bf._base;
return (ret);
}
+int
+vasprintf(char **str, const char *fmt, __va_list ap)
+{
+ return vasprintf_l(str, __get_locale(), fmt, ap);
+}
diff --git a/lib/libc/stdio/vdprintf.c b/lib/libc/stdio/vdprintf.c
index 3ad273e..454b0f9 100644
--- a/lib/libc/stdio/vdprintf.c
+++ b/lib/libc/stdio/vdprintf.c
@@ -2,6 +2,11 @@
* Copyright (c) 2009 David Schultz <das@FreeBSD.org>
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -35,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include "un-namespace.h"
#include "local.h"
+#include "xlocale_private.h"
int
vdprintf(int fd, const char * __restrict fmt, va_list ap)
@@ -57,7 +63,7 @@ vdprintf(int fd, const char * __restrict fmt, va_list ap)
f._bf._base = buf;
f._bf._size = sizeof(buf);
- if ((ret = __vfprintf(&f, fmt, ap)) < 0)
+ if ((ret = __vfprintf(&f, __get_locale(), fmt, ap)) < 0)
return (ret);
return (__fflush(&f) ? EOF : ret);
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index 17ad824..bfbdc13 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -57,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include <printf.h>
#include <stdarg.h>
+#include "xlocale_private.h"
#include "un-namespace.h"
#include "libc_private.h"
@@ -64,8 +70,8 @@ __FBSDID("$FreeBSD$");
#include "fvwrite.h"
#include "printflocal.h"
-static int __sprint(FILE *, struct __suio *);
-static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0)
+static int __sprint(FILE *, struct __suio *, locale_t);
+static int __sbprintf(FILE *, locale_t, const char *, va_list) __printflike(3, 0)
__noinline;
static char *__wcsconv(wchar_t *, int);
@@ -87,11 +93,11 @@ struct grouping_state {
* of bytes that will be needed.
*/
static int
-grouping_init(struct grouping_state *gs, int ndigits)
+grouping_init(struct grouping_state *gs, int ndigits, locale_t loc)
{
struct lconv *locale;
- locale = localeconv();
+ locale = localeconv_l(loc);
gs->grouping = locale->grouping;
gs->thousands_sep = locale->thousands_sep;
gs->thousep_len = strlen(gs->thousands_sep);
@@ -116,11 +122,11 @@ grouping_init(struct grouping_state *gs, int ndigits)
*/
static int
grouping_print(struct grouping_state *gs, struct io_state *iop,
- const CHAR *cp, const CHAR *ep)
+ const CHAR *cp, const CHAR *ep, locale_t locale)
{
const CHAR *cp0 = cp;
- if (io_printandpad(iop, cp, ep, gs->lead, zeroes))
+ if (io_printandpad(iop, cp, ep, gs->lead, zeroes, locale))
return (-1);
cp += gs->lead;
while (gs->nseps > 0 || gs->nrepeats > 0) {
@@ -130,9 +136,9 @@ grouping_print(struct grouping_state *gs, struct io_state *iop,
gs->grouping--;
gs->nseps--;
}
- if (io_print(iop, gs->thousands_sep, gs->thousep_len))
+ if (io_print(iop, gs->thousands_sep, gs->thousep_len, locale))
return (-1);
- if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes))
+ if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes, locale))
return (-1);
cp += *gs->grouping;
}
@@ -146,7 +152,7 @@ grouping_print(struct grouping_state *gs, struct io_state *iop,
* then reset it so that it can be reused.
*/
static int
-__sprint(FILE *fp, struct __suio *uio)
+__sprint(FILE *fp, struct __suio *uio, locale_t locale)
{
int err;
@@ -166,7 +172,7 @@ __sprint(FILE *fp, struct __suio *uio)
* worries about ungetc buffers and so forth.
*/
static int
-__sbprintf(FILE *fp, const char *fmt, va_list ap)
+__sbprintf(FILE *fp, locale_t locale, const char *fmt, va_list ap)
{
int ret;
FILE fake = FAKE_FILE;
@@ -190,7 +196,7 @@ __sbprintf(FILE *fp, const char *fmt, va_list ap)
fake._lbfsize = 0; /* not actually used, but Just In Case */
/* do the work, then copy any error status */
- ret = __vfprintf(&fake, fmt, ap);
+ ret = __vfprintf(&fake, locale, fmt, ap);
if (ret >= 0 && __fflush(&fake))
ret = EOF;
if (fake._flags & __SERR)
@@ -261,21 +267,27 @@ __wcsconv(wchar_t *wcsarg, int prec)
* MT-safe version
*/
int
-vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap)
-
+vfprintf_l(FILE * __restrict fp, locale_t locale, const char * __restrict fmt0,
+ va_list ap)
{
int ret;
+ FIX_LOCALE(locale);
FLOCKFILE(fp);
/* optimise fprintf(stderr) (and other unbuffered Unix files) */
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
fp->_file >= 0)
- ret = __sbprintf(fp, fmt0, ap);
+ ret = __sbprintf(fp, locale, fmt0, ap);
else
- ret = __vfprintf(fp, fmt0, ap);
+ ret = __vfprintf(fp, locale, fmt0, ap);
FUNLOCKFILE(fp);
return (ret);
}
+int
+vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap)
+{
+ return vfprintf_l(fp, __get_locale(), fmt0, ap);
+}
/*
* The size of the buffer we use as scratch space for integer
@@ -292,7 +304,7 @@ vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap)
* Non-MT-safe version
*/
int
-__vfprintf(FILE *fp, const char *fmt0, va_list ap)
+__vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap)
{
char *fmt; /* format string */
int ch; /* character from fmt */
@@ -357,19 +369,19 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
/* BEWARE, these `goto error' on error. */
#define PRINT(ptr, len) { \
- if (io_print(&io, (ptr), (len))) \
+ if (io_print(&io, (ptr), (len), locale)) \
goto error; \
}
#define PAD(howmany, with) { \
- if (io_pad(&io, (howmany), (with))) \
+ if (io_pad(&io, (howmany), (with), locale)) \
goto error; \
}
#define PRINTANDPAD(p, ep, len, with) { \
- if (io_printandpad(&io, (p), (ep), (len), (with))) \
+ if (io_printandpad(&io, (p), (ep), (len), (with), locale)) \
goto error; \
}
#define FLUSH() { \
- if (io_flush(&io)) \
+ if (io_flush(&io, locale)) \
goto error; \
}
@@ -454,7 +466,7 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
ret = 0;
#ifndef NO_FLOATING_POINT
dtoaresult = NULL;
- decimal_point = localeconv()->decimal_point;
+ decimal_point = localeconv_l(locale)->decimal_point;
/* The overwhelmingly common case is decpt_len == 1. */
decpt_len = (decimal_point[1] == '\0' ? 1 : strlen(decimal_point));
#endif
@@ -750,7 +762,7 @@ fp_common:
if (prec || flags & ALT)
size += prec + decpt_len;
if ((flags & GROUPING) && expt > 0)
- size += grouping_init(&gs, expt);
+ size += grouping_init(&gs, expt, locale);
}
break;
#endif /* !NO_FLOATING_POINT */
@@ -887,7 +899,7 @@ number: if ((dprec = prec) >= 0)
if (size > BUF) /* should never happen */
abort();
if ((flags & GROUPING) && size != 0)
- size += grouping_init(&gs, size);
+ size += grouping_init(&gs, size, locale);
break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
@@ -950,7 +962,7 @@ number: if ((dprec = prec) >= 0)
/* leading zeroes from decimal precision */
PAD(dprec - size, zeroes);
if (gs.grouping) {
- if (grouping_print(&gs, &io, cp, buf+BUF) < 0)
+ if (grouping_print(&gs, &io, cp, buf+BUF, locale) < 0)
goto error;
} else {
PRINT(cp, size);
@@ -968,7 +980,7 @@ number: if ((dprec = prec) >= 0)
} else {
if (gs.grouping) {
n = grouping_print(&gs, &io,
- cp, dtoaend);
+ cp, dtoaend, locale);
if (n < 0)
goto error;
cp += n;
diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c
index bce4481..0e78949 100644
--- a/lib/libc/stdio/vfscanf.c
+++ b/lib/libc/stdio/vfscanf.c
@@ -2,6 +2,11 @@
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
@@ -51,6 +56,7 @@ __FBSDID("$FreeBSD$");
#include "collate.h"
#include "libc_private.h"
#include "local.h"
+#include "xlocale_private.h"
#ifndef NO_FLOATING_POINT
#include <locale.h>
@@ -95,7 +101,7 @@ __FBSDID("$FreeBSD$");
static const u_char *__sccl(char *, const u_char *);
#ifndef NO_FLOATING_POINT
-static int parsefloat(FILE *, char *, char *);
+static int parsefloat(FILE *, char *, char *, locale_t);
#endif
__weak_reference(__vfscanf, vfscanf);
@@ -109,7 +115,18 @@ __vfscanf(FILE *fp, char const *fmt0, va_list ap)
int ret;
FLOCKFILE(fp);
- ret = __svfscanf(fp, fmt0, ap);
+ ret = __svfscanf(fp, __get_locale(), fmt0, ap);
+ FUNLOCKFILE(fp);
+ return (ret);
+}
+int
+vfscanf_l(FILE *fp, locale_t locale, char const *fmt0, va_list ap)
+{
+ int ret;
+ FIX_LOCALE(locale);
+
+ FLOCKFILE(fp);
+ ret = __svfscanf(fp, locale, fmt0, ap);
FUNLOCKFILE(fp);
return (ret);
}
@@ -118,7 +135,7 @@ __vfscanf(FILE *fp, char const *fmt0, va_list ap)
* __svfscanf - non-MT-safe version of __vfscanf
*/
int
-__svfscanf(FILE *fp, const char *fmt0, va_list ap)
+__svfscanf(FILE *fp, locale_t locale, const char *fmt0, va_list ap)
{
const u_char *fmt = (const u_char *)fmt0;
int c; /* character from format, or conversion */
@@ -733,9 +750,9 @@ literal:
*p = 0;
if ((flags & UNSIGNED) == 0)
- res = strtoimax(buf, (char **)NULL, base);
+ res = strtoimax_l(buf, (char **)NULL, base, locale);
else
- res = strtoumax(buf, (char **)NULL, base);
+ res = strtoumax_l(buf, (char **)NULL, base, locale);
if (flags & POINTER)
*va_arg(ap, void **) =
(void *)(uintptr_t)res;
@@ -766,17 +783,17 @@ literal:
/* scan a floating point number as if by strtod */
if (width == 0 || width > sizeof(buf) - 1)
width = sizeof(buf) - 1;
- if ((width = parsefloat(fp, buf, buf + width)) == 0)
+ if ((width = parsefloat(fp, buf, buf + width, locale)) == 0)
goto match_failure;
if ((flags & SUPPRESS) == 0) {
if (flags & LONGDBL) {
- long double res = strtold(buf, &p);
+ long double res = strtold_l(buf, &p, locale);
*va_arg(ap, long double *) = res;
} else if (flags & LONG) {
- double res = strtod(buf, &p);
+ double res = strtod_l(buf, &p, locale);
*va_arg(ap, double *) = res;
} else {
- float res = strtof(buf, &p);
+ float res = strtof_l(buf, &p, locale);
*va_arg(ap, float *) = res;
}
nassigned++;
@@ -805,6 +822,8 @@ __sccl(tab, fmt)
const u_char *fmt;
{
int c, n, v, i;
+ struct xlocale_collate *table =
+ (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE];
/* first `clear' the whole table */
c = *fmt++; /* first char hat => negated scanset */
@@ -858,8 +877,8 @@ doswitch:
*/
n = *fmt;
if (n == ']'
- || (__collate_load_error ? n < c :
- __collate_range_cmp (n, c) < 0
+ || (table->__collate_load_error ? n < c :
+ __collate_range_cmp (table, n, c) < 0
)
) {
c = '-';
@@ -867,14 +886,14 @@ doswitch:
}
fmt++;
/* fill in the range */
- if (__collate_load_error) {
+ if (table->__collate_load_error) {
do {
tab[++c] = v;
} while (c < n);
} else {
for (i = 0; i < 256; i ++)
- if ( __collate_range_cmp (c, i) < 0
- && __collate_range_cmp (i, n) <= 0
+ if ( __collate_range_cmp (table, c, i) < 0
+ && __collate_range_cmp (table, i, n) <= 0
)
tab[i] = v;
}
@@ -908,7 +927,7 @@ doswitch:
#ifndef NO_FLOATING_POINT
static int
-parsefloat(FILE *fp, char *buf, char *end)
+parsefloat(FILE *fp, char *buf, char *end, locale_t locale)
{
char *commit, *p;
int infnanpos = 0, decptpos = 0;
@@ -917,7 +936,7 @@ parsefloat(FILE *fp, char *buf, char *end)
S_DIGITS, S_DECPT, S_FRAC, S_EXP, S_EXPDIGITS
} state = S_START;
unsigned char c;
- const char *decpt = localeconv()->decimal_point;
+ const char *decpt = localeconv_l(locale)->decimal_point;
_Bool gotmantdig = 0, ishex = 0;
/*
diff --git a/lib/libc/stdio/vfwprintf.c b/lib/libc/stdio/vfwprintf.c
index d34f559..73e37c9 100644
--- a/lib/libc/stdio/vfwprintf.c
+++ b/lib/libc/stdio/vfwprintf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -65,10 +70,11 @@ __FBSDID("$FreeBSD$");
#include "local.h"
#include "fvwrite.h"
#include "printflocal.h"
+#include "xlocale_private.h"
-static int __sprint(FILE *, struct __suio *);
-static int __sbprintf(FILE *, const wchar_t *, va_list) __noinline;
-static wint_t __xfputwc(wchar_t, FILE *);
+static int __sprint(FILE *, struct __suio *, locale_t);
+static int __sbprintf(FILE *, locale_t, const wchar_t *, va_list) __noinline;
+static wint_t __xfputwc(wchar_t, FILE *, locale_t);
static wchar_t *__mbsconv(char *, int);
#define CHAR wchar_t
@@ -85,28 +91,28 @@ struct grouping_state {
static const mbstate_t initial_mbs;
static inline wchar_t
-get_decpt(void)
+get_decpt(locale_t locale)
{
mbstate_t mbs;
wchar_t decpt;
int nconv;
mbs = initial_mbs;
- nconv = mbrtowc(&decpt, localeconv()->decimal_point, MB_CUR_MAX, &mbs);
+ nconv = mbrtowc(&decpt, localeconv_l(locale)->decimal_point, MB_CUR_MAX, &mbs);
if (nconv == (size_t)-1 || nconv == (size_t)-2)
decpt = '.'; /* failsafe */
return (decpt);
}
static inline wchar_t
-get_thousep(void)
+get_thousep(locale_t locale)
{
mbstate_t mbs;
wchar_t thousep;
int nconv;
mbs = initial_mbs;
- nconv = mbrtowc(&thousep, localeconv()->thousands_sep,
+ nconv = mbrtowc(&thousep, localeconv_l(locale)->thousands_sep,
MB_CUR_MAX, &mbs);
if (nconv == (size_t)-1 || nconv == (size_t)-2)
thousep = '\0'; /* failsafe */
@@ -119,11 +125,11 @@ get_thousep(void)
* of wide characters that will be printed.
*/
static int
-grouping_init(struct grouping_state *gs, int ndigits)
+grouping_init(struct grouping_state *gs, int ndigits, locale_t locale)
{
- gs->grouping = localeconv()->grouping;
- gs->thousands_sep = get_thousep();
+ gs->grouping = localeconv_l(locale)->grouping;
+ gs->thousands_sep = get_thousep(locale);
gs->nseps = gs->nrepeats = 0;
gs->lead = ndigits;
@@ -145,11 +151,11 @@ grouping_init(struct grouping_state *gs, int ndigits)
*/
static int
grouping_print(struct grouping_state *gs, struct io_state *iop,
- const CHAR *cp, const CHAR *ep)
+ const CHAR *cp, const CHAR *ep, locale_t locale)
{
const CHAR *cp0 = cp;
- if (io_printandpad(iop, cp, ep, gs->lead, zeroes))
+ if (io_printandpad(iop, cp, ep, gs->lead, zeroes, locale))
return (-1);
cp += gs->lead;
while (gs->nseps > 0 || gs->nrepeats > 0) {
@@ -159,9 +165,9 @@ grouping_print(struct grouping_state *gs, struct io_state *iop,
gs->grouping--;
gs->nseps--;
}
- if (io_print(iop, &gs->thousands_sep, 1))
+ if (io_print(iop, &gs->thousands_sep, 1, locale))
return (-1);
- if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes))
+ if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes, locale))
return (-1);
cp += *gs->grouping;
}
@@ -180,7 +186,7 @@ grouping_print(struct grouping_state *gs, struct io_state *iop,
* string eclipses the benefits of buffering.
*/
static int
-__sprint(FILE *fp, struct __suio *uio)
+__sprint(FILE *fp, struct __suio *uio, locale_t locale)
{
struct __siov *iov;
wchar_t *p;
@@ -191,7 +197,7 @@ __sprint(FILE *fp, struct __suio *uio)
p = (wchar_t *)iov->iov_base;
len = iov->iov_len;
for (i = 0; i < len; i++) {
- if (__xfputwc(p[i], fp) == WEOF)
+ if (__xfputwc(p[i], fp, locale) == WEOF)
return (-1);
}
}
@@ -205,7 +211,7 @@ __sprint(FILE *fp, struct __suio *uio)
* worries about ungetc buffers and so forth.
*/
static int
-__sbprintf(FILE *fp, const wchar_t *fmt, va_list ap)
+__sbprintf(FILE *fp, locale_t locale, const wchar_t *fmt, va_list ap)
{
int ret;
FILE fake;
@@ -229,7 +235,7 @@ __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap)
fake._lbfsize = 0; /* not actually used, but Just In Case */
/* do the work, then copy any error status */
- ret = __vfwprintf(&fake, fmt, ap);
+ ret = __vfwprintf(&fake, locale, fmt, ap);
if (ret >= 0 && __fflush(&fake))
ret = WEOF;
if (fake._flags & __SERR)
@@ -242,7 +248,7 @@ __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap)
* File must already be locked.
*/
static wint_t
-__xfputwc(wchar_t wc, FILE *fp)
+__xfputwc(wchar_t wc, FILE *fp, locale_t locale)
{
mbstate_t mbs;
char buf[MB_LEN_MAX];
@@ -251,7 +257,7 @@ __xfputwc(wchar_t wc, FILE *fp)
size_t len;
if ((fp->_flags & __SSTR) == 0)
- return (__fputwc(wc, fp));
+ return (__fputwc(wc, fp, locale));
mbs = initial_mbs;
if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) {
@@ -343,21 +349,27 @@ __mbsconv(char *mbsarg, int prec)
* MT-safe version
*/
int
-vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap)
+vfwprintf_l(FILE * __restrict fp, locale_t locale,
+ const wchar_t * __restrict fmt0, va_list ap)
{
int ret;
-
+ FIX_LOCALE(locale);
FLOCKFILE(fp);
/* optimise fprintf(stderr) (and other unbuffered Unix files) */
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
fp->_file >= 0)
- ret = __sbprintf(fp, fmt0, ap);
+ ret = __sbprintf(fp, locale, fmt0, ap);
else
- ret = __vfwprintf(fp, fmt0, ap);
+ ret = __vfwprintf(fp, locale, fmt0, ap);
FUNLOCKFILE(fp);
return (ret);
}
+int
+vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap)
+{
+ return vfwprintf_l(fp, __get_locale(), fmt0, ap);
+}
/*
* The size of the buffer we use as scratch space for integer
@@ -374,7 +386,7 @@ vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap)
* Non-MT-safe version
*/
int
-__vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
+__vfwprintf(FILE *fp, locale_t locale, const wchar_t *fmt0, va_list ap)
{
wchar_t *fmt; /* format string */
wchar_t ch; /* character from fmt */
@@ -437,19 +449,19 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
/* BEWARE, these `goto error' on error. */
#define PRINT(ptr, len) do { \
- if (io_print(&io, (ptr), (len))) \
+ if (io_print(&io, (ptr), (len), locale)) \
goto error; \
} while (0)
#define PAD(howmany, with) { \
- if (io_pad(&io, (howmany), (with))) \
+ if (io_pad(&io, (howmany), (with), locale)) \
goto error; \
}
#define PRINTANDPAD(p, ep, len, with) { \
- if (io_printandpad(&io, (p), (ep), (len), (with))) \
+ if (io_printandpad(&io, (p), (ep), (len), (with), locale)) \
goto error; \
}
#define FLUSH() { \
- if (io_flush(&io)) \
+ if (io_flush(&io, locale)) \
goto error; \
}
@@ -529,7 +541,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
io_init(&io, fp);
ret = 0;
#ifndef NO_FLOATING_POINT
- decimal_point = get_decpt();
+ decimal_point = get_decpt(locale);
#endif
/*
@@ -816,7 +828,7 @@ fp_common:
if (prec || flags & ALT)
size += prec + 1;
if ((flags & GROUPING) && expt > 0)
- size += grouping_init(&gs, expt);
+ size += grouping_init(&gs, expt, locale);
}
break;
#endif /* !NO_FLOATING_POINT */
@@ -955,7 +967,7 @@ number: if ((dprec = prec) >= 0)
if (size > BUF) /* should never happen */
abort();
if ((flags & GROUPING) && size != 0)
- size += grouping_init(&gs, size);
+ size += grouping_init(&gs, size, locale);
break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
@@ -1018,7 +1030,7 @@ number: if ((dprec = prec) >= 0)
/* leading zeroes from decimal precision */
PAD(dprec - size, zeroes);
if (gs.grouping) {
- if (grouping_print(&gs, &io, cp, buf+BUF) < 0)
+ if (grouping_print(&gs, &io, cp, buf+BUF, locale) < 0)
goto error;
} else {
PRINT(cp, size);
@@ -1036,7 +1048,7 @@ number: if ((dprec = prec) >= 0)
} else {
if (gs.grouping) {
n = grouping_print(&gs, &io,
- cp, convbuf + ndig);
+ cp, convbuf + ndig, locale);
if (n < 0)
goto error;
cp += n;
diff --git a/lib/libc/stdio/vfwscanf.c b/lib/libc/stdio/vfwscanf.c
index 60c7c71..22b0827 100644
--- a/lib/libc/stdio/vfwscanf.c
+++ b/lib/libc/stdio/vfwscanf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -53,10 +58,7 @@ __FBSDID("$FreeBSD$");
#include "libc_private.h"
#include "local.h"
-
-#ifndef NO_FLOATING_POINT
-#include <locale.h>
-#endif
+#include "xlocale_private.h"
#define BUF 513 /* Maximum length of numeric string. */
@@ -96,7 +98,7 @@ __FBSDID("$FreeBSD$");
#define CT_FLOAT 4 /* %[efgEFG] conversion */
#ifndef NO_FLOATING_POINT
-static int parsefloat(FILE *, wchar_t *, wchar_t *);
+static int parsefloat(FILE *, wchar_t *, wchar_t *, locale_t);
#endif
#define INCCL(_c) \
@@ -109,22 +111,30 @@ static const mbstate_t initial_mbs;
* MT-safe version.
*/
int
-vfwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, va_list ap)
+vfwscanf_l(FILE * __restrict fp, locale_t locale,
+ const wchar_t * __restrict fmt, va_list ap)
{
int ret;
+ FIX_LOCALE(locale);
FLOCKFILE(fp);
ORIENT(fp, 1);
- ret = __vfwscanf(fp, fmt, ap);
+ ret = __vfwscanf(fp, locale, fmt, ap);
FUNLOCKFILE(fp);
return (ret);
}
+int
+vfwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, va_list ap)
+{
+ return vfwscanf_l(fp, __get_locale(), fmt, ap);
+}
/*
* Non-MT-safe version.
*/
int
-__vfwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, va_list ap)
+__vfwscanf(FILE * __restrict fp, locale_t locale,
+ const wchar_t * __restrict fmt, va_list ap)
{
wint_t c; /* character from format, or conversion */
size_t width; /* field width, or 0 */
@@ -159,11 +169,11 @@ __vfwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, va_list ap)
if (c == 0)
return (nassigned);
if (iswspace(c)) {
- while ((c = __fgetwc(fp)) != WEOF &&
- iswspace(c))
+ while ((c = __fgetwc(fp, locale)) != WEOF &&
+ iswspace_l(c, locale))
;
if (c != WEOF)
- __ungetwc(c, fp);
+ __ungetwc(c, fp, locale);
continue;
}
if (c != '%')
@@ -178,10 +188,10 @@ again: c = *fmt++;
switch (c) {
case '%':
literal:
- if ((wi = __fgetwc(fp)) == WEOF)
+ if ((wi = __fgetwc(fp, locale)) == WEOF)
goto input_failure;
if (wi != c) {
- __ungetwc(wi, fp);
+ __ungetwc(wi, fp, locale);
goto input_failure;
}
nread++;
@@ -341,11 +351,11 @@ literal:
* that suppress this.
*/
if ((flags & NOSKIP) == 0) {
- while ((wi = __fgetwc(fp)) != WEOF && iswspace(wi))
+ while ((wi = __fgetwc(fp, locale)) != WEOF && iswspace(wi))
nread++;
if (wi == WEOF)
goto input_failure;
- __ungetwc(wi, fp);
+ __ungetwc(wi, fp, locale);
}
/*
@@ -362,7 +372,7 @@ literal:
p = va_arg(ap, wchar_t *);
n = 0;
while (width-- != 0 &&
- (wi = __fgetwc(fp)) != WEOF) {
+ (wi = __fgetwc(fp, locale)) != WEOF) {
if (!(flags & SUPPRESS))
*p++ = (wchar_t)wi;
n++;
@@ -378,7 +388,7 @@ literal:
n = 0;
mbs = initial_mbs;
while (width != 0 &&
- (wi = __fgetwc(fp)) != WEOF) {
+ (wi = __fgetwc(fp, locale)) != WEOF) {
if (width >= MB_CUR_MAX &&
!(flags & SUPPRESS)) {
nconv = wcrtomb(mbp, wi, &mbs);
@@ -390,7 +400,7 @@ literal:
if (nconv == (size_t)-1)
goto input_failure;
if (nconv > width) {
- __ungetwc(wi, fp);
+ __ungetwc(wi, fp, locale);
break;
}
if (!(flags & SUPPRESS))
@@ -418,20 +428,20 @@ literal:
/* take only those things in the class */
if ((flags & SUPPRESS) && (flags & LONG)) {
n = 0;
- while ((wi = __fgetwc(fp)) != WEOF &&
+ while ((wi = __fgetwc(fp, locale)) != WEOF &&
width-- != 0 && INCCL(wi))
n++;
if (wi != WEOF)
- __ungetwc(wi, fp);
+ __ungetwc(wi, fp, locale);
if (n == 0)
goto match_failure;
} else if (flags & LONG) {
p0 = p = va_arg(ap, wchar_t *);
- while ((wi = __fgetwc(fp)) != WEOF &&
+ while ((wi = __fgetwc(fp, locale)) != WEOF &&
width-- != 0 && INCCL(wi))
*p++ = (wchar_t)wi;
if (wi != WEOF)
- __ungetwc(wi, fp);
+ __ungetwc(wi, fp, locale);
n = p - p0;
if (n == 0)
goto match_failure;
@@ -442,7 +452,7 @@ literal:
mbp = va_arg(ap, char *);
n = 0;
mbs = initial_mbs;
- while ((wi = __fgetwc(fp)) != WEOF &&
+ while ((wi = __fgetwc(fp, locale)) != WEOF &&
width != 0 && INCCL(wi)) {
if (width >= MB_CUR_MAX &&
!(flags & SUPPRESS)) {
@@ -466,7 +476,7 @@ literal:
n++;
}
if (wi != WEOF)
- __ungetwc(wi, fp);
+ __ungetwc(wi, fp, locale);
if (!(flags & SUPPRESS)) {
*mbp = 0;
nassigned++;
@@ -481,29 +491,29 @@ literal:
if (width == 0)
width = (size_t)~0;
if ((flags & SUPPRESS) && (flags & LONG)) {
- while ((wi = __fgetwc(fp)) != WEOF &&
+ while ((wi = __fgetwc(fp, locale)) != WEOF &&
width-- != 0 &&
!iswspace(wi))
nread++;
if (wi != WEOF)
- __ungetwc(wi, fp);
+ __ungetwc(wi, fp, locale);
} else if (flags & LONG) {
p0 = p = va_arg(ap, wchar_t *);
- while ((wi = __fgetwc(fp)) != WEOF &&
+ while ((wi = __fgetwc(fp, locale)) != WEOF &&
width-- != 0 &&
!iswspace(wi)) {
*p++ = (wchar_t)wi;
nread++;
}
if (wi != WEOF)
- __ungetwc(wi, fp);
+ __ungetwc(wi, fp, locale);
*p = '\0';
nassigned++;
} else {
if (!(flags & SUPPRESS))
mbp = va_arg(ap, char *);
mbs = initial_mbs;
- while ((wi = __fgetwc(fp)) != WEOF &&
+ while ((wi = __fgetwc(fp, locale)) != WEOF &&
width != 0 &&
!iswspace(wi)) {
if (width >= MB_CUR_MAX &&
@@ -528,7 +538,7 @@ literal:
nread++;
}
if (wi != WEOF)
- __ungetwc(wi, fp);
+ __ungetwc(wi, fp, locale);
if (!(flags & SUPPRESS)) {
*mbp = 0;
nassigned++;
@@ -544,7 +554,7 @@ literal:
width = sizeof(buf) / sizeof(*buf) - 1;
flags |= SIGNOK | NDIGITS | NZDIGITS;
for (p = buf; width; width--) {
- c = __fgetwc(fp);
+ c = __fgetwc(fp, locale);
/*
* Switch on the character; `goto ok'
* if we accept it as a part of number.
@@ -628,7 +638,7 @@ literal:
* for a number. Stop accumulating digits.
*/
if (c != WEOF)
- __ungetwc(c, fp);
+ __ungetwc(c, fp, locale);
break;
ok:
/*
@@ -644,13 +654,13 @@ literal:
*/
if (flags & NDIGITS) {
if (p > buf)
- __ungetwc(*--p, fp);
+ __ungetwc(*--p, fp, locale);
goto match_failure;
}
c = p[-1];
if (c == 'x' || c == 'X') {
--p;
- __ungetwc(c, fp);
+ __ungetwc(c, fp, locale);
}
if ((flags & SUPPRESS) == 0) {
uintmax_t res;
@@ -691,7 +701,7 @@ literal:
if (width == 0 || width > sizeof(buf) /
sizeof(*buf) - 1)
width = sizeof(buf) / sizeof(*buf) - 1;
- if ((width = parsefloat(fp, buf, buf + width)) == 0)
+ if ((width = parsefloat(fp, buf, buf + width, locale)) == 0)
goto match_failure;
if ((flags & SUPPRESS) == 0) {
if (flags & LONGDBL) {
@@ -720,7 +730,7 @@ match_failure:
#ifndef NO_FLOATING_POINT
static int
-parsefloat(FILE *fp, wchar_t *buf, wchar_t *end)
+parsefloat(FILE *fp, wchar_t *buf, wchar_t *end, locale_t locale)
{
mbstate_t mbs;
size_t nconv;
@@ -751,7 +761,7 @@ parsefloat(FILE *fp, wchar_t *buf, wchar_t *end)
commit = buf - 1;
c = WEOF;
for (p = buf; p < end; ) {
- if ((c = __fgetwc(fp)) == WEOF)
+ if ((c = __fgetwc(fp, locale)) == WEOF)
break;
reswitch:
switch (state) {
@@ -871,9 +881,9 @@ reswitch:
parsedone:
if (c != WEOF)
- __ungetwc(c, fp);
+ __ungetwc(c, fp, locale);
while (commit < --p)
- __ungetwc(*p, fp);
+ __ungetwc(*p, fp, locale);
*++commit = '\0';
return (commit - buf);
}
diff --git a/lib/libc/stdio/vprintf.c b/lib/libc/stdio/vprintf.c
index a610b7d..c15ef4d 100644
--- a/lib/libc/stdio/vprintf.c
+++ b/lib/libc/stdio/vprintf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -37,10 +42,15 @@ static char sccsid[] = "@(#)vprintf.c 8.1 (Berkeley) 6/4/93";
__FBSDID("$FreeBSD$");
#include <stdio.h>
+#include <xlocale.h>
int
vprintf(const char * __restrict fmt, __va_list ap)
{
-
return (vfprintf(stdout, fmt, ap));
}
+int
+vprintf_l(locale_t locale, const char * __restrict fmt, __va_list ap)
+{
+ return (vfprintf_l(stdout, locale, fmt, ap));
+}
diff --git a/lib/libc/stdio/vscanf.c b/lib/libc/stdio/vscanf.c
index 25bce72..d56bb3b 100644
--- a/lib/libc/stdio/vscanf.c
+++ b/lib/libc/stdio/vscanf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Donn Seeley at UUNET Technologies, Inc.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -41,16 +46,26 @@ __FBSDID("$FreeBSD$");
#include "un-namespace.h"
#include "libc_private.h"
#include "local.h"
+#include "xlocale_private.h"
int
-vscanf(fmt, ap)
+vscanf_l(locale, fmt, ap)
+ locale_t locale;
const char * __restrict fmt;
__va_list ap;
{
int retval;
+ FIX_LOCALE(locale);
FLOCKFILE(stdin);
- retval = __svfscanf(stdin, fmt, ap);
+ retval = __svfscanf(stdin, locale, fmt, ap);
FUNLOCKFILE(stdin);
return (retval);
}
+int
+vscanf(fmt, ap)
+ const char * __restrict fmt;
+ __va_list ap;
+{
+ return vscanf_l(__get_locale(), fmt, ap);
+}
diff --git a/lib/libc/stdio/vsnprintf.c b/lib/libc/stdio/vsnprintf.c
index 70e4c53..d2bad0f 100644
--- a/lib/libc/stdio/vsnprintf.c
+++ b/lib/libc/stdio/vsnprintf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -39,15 +44,17 @@ __FBSDID("$FreeBSD$");
#include <limits.h>
#include <stdio.h>
#include "local.h"
+#include "xlocale_private.h"
int
-vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt,
- __va_list ap)
+vsnprintf_l(char * __restrict str, size_t n, locale_t locale,
+ const char * __restrict fmt, __va_list ap)
{
size_t on;
int ret;
char dummy[2];
FILE f = FAKE_FILE;
+ FIX_LOCALE(locale);
on = n;
if (n != 0)
@@ -64,8 +71,14 @@ vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt,
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = n;
- ret = __vfprintf(&f, fmt, ap);
+ ret = __vfprintf(&f, locale, fmt, ap);
if (on > 0)
*f._p = '\0';
return (ret);
}
+int
+vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt,
+ __va_list ap)
+{
+ return vsnprintf_l(str, n, __get_locale(), fmt, ap);
+}
diff --git a/lib/libc/stdio/vsprintf.c b/lib/libc/stdio/vsprintf.c
index 3890af7..04f2df3 100644
--- a/lib/libc/stdio/vsprintf.c
+++ b/lib/libc/stdio/vsprintf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -39,17 +44,25 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <limits.h>
#include "local.h"
+#include "xlocale_private.h"
int
-vsprintf(char * __restrict str, const char * __restrict fmt, __va_list ap)
+vsprintf_l(char * __restrict str, locale_t locale,
+ const char * __restrict fmt, __va_list ap)
{
int ret;
FILE f = FAKE_FILE;
+ FIX_LOCALE(locale);
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = INT_MAX;
- ret = __vfprintf(&f, fmt, ap);
+ ret = __vfprintf(&f, locale, fmt, ap);
*f._p = 0;
return (ret);
}
+int
+vsprintf(char * __restrict str, const char * __restrict fmt, __va_list ap)
+{
+ return vsprintf_l(str, __get_locale(), fmt, ap);
+}
diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c
index 82429c6..5668ab5 100644
--- a/lib/libc/stdio/vsscanf.c
+++ b/lib/libc/stdio/vsscanf.c
@@ -2,6 +2,11 @@
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* This code is derived from software contributed to Berkeley by
* Donn Seeley at UUNET Technologies, Inc.
*
@@ -39,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <string.h>
#include "local.h"
+#include "xlocale_private.h"
static int
eofread(void *, char *, int);
@@ -52,14 +58,21 @@ eofread(void *cookie, char *buf, int len)
}
int
-vsscanf(const char * __restrict str, const char * __restrict fmt,
- __va_list ap)
+vsscanf_l(const char * __restrict str, locale_t locale,
+ const char * __restrict fmt, __va_list ap)
{
FILE f = FAKE_FILE;
+ FIX_LOCALE(locale);
f._flags = __SRD;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._r = strlen(str);
f._read = eofread;
- return (__svfscanf(&f, fmt, ap));
+ return (__svfscanf(&f, locale, fmt, ap));
+}
+int
+vsscanf(const char * __restrict str, const char * __restrict fmt,
+ __va_list ap)
+{
+ return vsscanf_l(str, __get_locale(), fmt, ap);
}
diff --git a/lib/libc/stdio/vswprintf.c b/lib/libc/stdio/vswprintf.c
index 2cfe724..023c537 100644
--- a/lib/libc/stdio/vswprintf.c
+++ b/lib/libc/stdio/vswprintf.c
@@ -4,6 +4,11 @@
* Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -38,10 +43,11 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <wchar.h>
#include "local.h"
+#include "xlocale_private.h"
int
-vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
- __va_list ap)
+vswprintf_l(wchar_t * __restrict s, size_t n, locale_t locale,
+ const wchar_t * __restrict fmt, __va_list ap)
{
static const mbstate_t initial;
mbstate_t mbs;
@@ -49,6 +55,7 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
char *mbp;
int ret, sverrno;
size_t nwc;
+ FIX_LOCALE(locale);
if (n == 0) {
errno = EINVAL;
@@ -62,7 +69,7 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
return (-1);
}
f._bf._size = f._w = 127; /* Leave room for the NUL */
- ret = __vfwprintf(&f, fmt, ap);
+ ret = __vfwprintf(&f, locale, fmt, ap);
if (ret < 0) {
sverrno = errno;
free(f._bf._base);
@@ -76,7 +83,7 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
* fputwc() did in __vfwprintf().
*/
mbs = initial;
- nwc = mbsrtowcs(s, (const char **)&mbp, n, &mbs);
+ nwc = mbsrtowcs_l(s, (const char **)&mbp, n, &mbs, locale);
free(f._bf._base);
if (nwc == (size_t)-1) {
errno = EILSEQ;
@@ -90,3 +97,9 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
return (ret);
}
+int
+vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
+ __va_list ap)
+{
+ return vswprintf_l(s, n, __get_locale(), fmt, ap);
+}
diff --git a/lib/libc/stdio/vswscanf.c b/lib/libc/stdio/vswscanf.c
index f06fc02..f646e85 100644
--- a/lib/libc/stdio/vswscanf.c
+++ b/lib/libc/stdio/vswscanf.c
@@ -5,6 +5,11 @@
* This code is derived from software contributed to Berkeley by
* Donn Seeley at UUNET Technologies, Inc.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -46,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <wchar.h>
#include "local.h"
+#include "xlocale_private.h"
static int eofread(void *, char *, int);
@@ -57,8 +63,8 @@ eofread(void *cookie, char *buf, int len)
}
int
-vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
- va_list ap)
+vswscanf_l(const wchar_t * __restrict str, locale_t locale,
+ const wchar_t * __restrict fmt, va_list ap)
{
static const mbstate_t initial;
mbstate_t mbs;
@@ -67,6 +73,7 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
size_t mlen;
int r;
const wchar_t *strp;
+ FIX_LOCALE(locale);
/*
* XXX Convert the wide character string to multibyte, which
@@ -76,7 +83,7 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
return (EOF);
mbs = initial;
strp = str;
- if ((mlen = wcsrtombs(mbstr, &strp, SIZE_T_MAX, &mbs)) == (size_t)-1) {
+ if ((mlen = wcsrtombs_l(mbstr, &strp, SIZE_T_MAX, &mbs, locale)) == (size_t)-1) {
free(mbstr);
return (EOF);
}
@@ -84,8 +91,14 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
f._bf._base = f._p = (unsigned char *)mbstr;
f._bf._size = f._r = mlen;
f._read = eofread;
- r = __vfwscanf(&f, fmt, ap);
+ r = __vfwscanf(&f, locale, fmt, ap);
free(mbstr);
return (r);
}
+int
+vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
+ va_list ap)
+{
+ return vswscanf_l(str, __get_locale(), fmt, ap);
+}
diff --git a/lib/libc/stdio/vwprintf.c b/lib/libc/stdio/vwprintf.c
index 91212a8..e09a30e 100644
--- a/lib/libc/stdio/vwprintf.c
+++ b/lib/libc/stdio/vwprintf.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002 Tim J. Robbins
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -30,10 +35,15 @@ __FBSDID("$FreeBSD$");
#include <stdarg.h>
#include <stdio.h>
#include <wchar.h>
+#include <xlocale.h>
int
vwprintf(const wchar_t * __restrict fmt, va_list ap)
{
-
return (vfwprintf(stdout, fmt, ap));
}
+int
+vwprintf_l(locale_t locale, const wchar_t * __restrict fmt, va_list ap)
+{
+ return (vfwprintf_l(stdout, locale, fmt, ap));
+}
diff --git a/lib/libc/stdio/vwscanf.c b/lib/libc/stdio/vwscanf.c
index 4a21af2..730beee 100644
--- a/lib/libc/stdio/vwscanf.c
+++ b/lib/libc/stdio/vwscanf.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002 Tim J. Robbins
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -30,10 +35,15 @@ __FBSDID("$FreeBSD$");
#include <stdarg.h>
#include <stdio.h>
#include <wchar.h>
+#include <xlocale.h>
int
vwscanf(const wchar_t * __restrict fmt, va_list ap)
{
-
return (vfwscanf(stdin, fmt, ap));
}
+int
+vwscanf_l(locale_t locale, const wchar_t * __restrict fmt, va_list ap)
+{
+ return (vfwscanf_l(stdin, locale, fmt, ap));
+}
diff --git a/lib/libc/stdio/wprintf.c b/lib/libc/stdio/wprintf.c
index 92426f6..fdffa86 100644
--- a/lib/libc/stdio/wprintf.c
+++ b/lib/libc/stdio/wprintf.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002 Tim J. Robbins
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -30,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <stdarg.h>
#include <stdio.h>
#include <wchar.h>
+#include <xlocale.h>
int
wprintf(const wchar_t * __restrict fmt, ...)
@@ -43,3 +49,15 @@ wprintf(const wchar_t * __restrict fmt, ...)
return (ret);
}
+int
+wprintf_l(locale_t locale, const wchar_t * __restrict fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vfwprintf_l(stdout, locale, fmt, ap);
+ va_end(ap);
+
+ return (ret);
+}
diff --git a/lib/libc/stdio/wscanf.c b/lib/libc/stdio/wscanf.c
index 5e27b40..22ce9bd 100644
--- a/lib/libc/stdio/wscanf.c
+++ b/lib/libc/stdio/wscanf.c
@@ -2,6 +2,11 @@
* Copyright (c) 2002 Tim J. Robbins
* All rights reserved.
*
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -30,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <stdarg.h>
#include <stdio.h>
#include <wchar.h>
+#include <xlocale.h>
int
wscanf(const wchar_t * __restrict fmt, ...)
@@ -43,3 +49,15 @@ wscanf(const wchar_t * __restrict fmt, ...)
return (r);
}
+int
+wscanf_l(locale_t locale, const wchar_t * __restrict fmt, ...)
+{
+ va_list ap;
+ int r;
+
+ va_start(ap, fmt);
+ r = vfwscanf_l(stdin, locale, fmt, ap);
+ va_end(ap);
+
+ return (r);
+}
OpenPOWER on IntegriCloud