summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2004-04-06 13:14:03 +0000
committertjr <tjr@FreeBSD.org>2004-04-06 13:14:03 +0000
commit4212f9711ffee179c943b9f40b788b759a1ad9e6 (patch)
tree6779dc19a3df61ca545f851748ebd5f5de3a255e /lib/libc
parentfcc4fa555ff7fcd7b9e4327aa717b090a18361b5 (diff)
downloadFreeBSD-src-4212f9711ffee179c943b9f40b788b759a1ad9e6.zip
FreeBSD-src-4212f9711ffee179c943b9f40b788b759a1ad9e6.tar.gz
Prepare to handle state-dependent encodings. This mainly involves not
taking shortcuts when it comes to storing and passing around conversion states.
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/locale/btowc.c11
-rw-r--r--lib/libc/locale/mblen.c26
-rw-r--r--lib/libc/locale/mbrlen.c9
-rw-r--r--lib/libc/locale/mbrtowc.c3
-rw-r--r--lib/libc/locale/mbsrtowcs.c11
-rw-r--r--lib/libc/locale/mbstowcs.c11
-rw-r--r--lib/libc/locale/mbtowc.c15
-rw-r--r--lib/libc/locale/wcrtomb.c3
-rw-r--r--lib/libc/locale/wcsrtombs.c28
-rw-r--r--lib/libc/locale/wcstombs.c11
-rw-r--r--lib/libc/locale/wctob.c12
-rw-r--r--lib/libc/locale/wctomb.c18
12 files changed, 87 insertions, 71 deletions
diff --git a/lib/libc/locale/btowc.c b/lib/libc/locale/btowc.c
index b0b24f2..34439b8 100644
--- a/lib/libc/locale/btowc.c
+++ b/lib/libc/locale/btowc.c
@@ -28,28 +28,25 @@
__FBSDID("$FreeBSD$");
#include <stdio.h>
-#include <string.h>
#include <wchar.h>
wint_t
btowc(int c)
{
+ static const mbstate_t initial;
+ mbstate_t mbs = initial;
char cc;
wchar_t wc;
if (c == EOF)
return (WEOF);
- cc = (char)c;
/*
* We expect mbrtowc() to return 0 or 1, hence the check for n > 1
* which detects error return values as well as "impossible" byte
* counts.
- *
- * We pass NULL as the state pointer to mbrtowc() because we don't
- * support state-dependent encodings and don't want to waste time
- * creating a zeroed mbstate_t that will not be used.
*/
- if (mbrtowc(&wc, &cc, 1, NULL) > 1)
+ cc = (char)c;
+ if (mbrtowc(&wc, &cc, 1, &mbs) > 1)
return (WEOF);
return (wc);
}
diff --git a/lib/libc/locale/mblen.c b/lib/libc/locale/mblen.c
index 5025115..8db5335 100644
--- a/lib/libc/locale/mblen.c
+++ b/lib/libc/locale/mblen.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002, 2003 Tim J. Robbins.
+ * Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,15 +27,29 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <errno.h>
+#include <limits.h>
#include <stdlib.h>
+#include <wchar.h>
int
mblen(const char *s, size_t n)
{
+ static const mbstate_t initial;
+ static mbstate_t mbs;
+ size_t rval;
- /*
- * Calling mbtowc() is only legal because we don't support
- * state-dependent encodings.
- */
- return (mbtowc(NULL, s, n));
+ if (s == NULL) {
+ /* No support for state dependent encodings. */
+ mbs = initial;
+ return (0);
+ }
+ rval = mbrtowc(NULL, s, n, &mbs);
+ if (rval == (size_t)-1 || rval == (size_t)-2)
+ return (-1);
+ if (rval > INT_MAX) {
+ errno = ERANGE;
+ return (-1);
+ }
+ return ((int)rval);
}
diff --git a/lib/libc/locale/mbrlen.c b/lib/libc/locale/mbrlen.c
index a2ab65b..edad289 100644
--- a/lib/libc/locale/mbrlen.c
+++ b/lib/libc/locale/mbrlen.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002 Tim J. Robbins.
+ * Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,11 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
size_t
-mbrlen(const char * __restrict s, size_t n, mbstate_t * __restrict ps __unused)
+mbrlen(const char * __restrict s, size_t n, mbstate_t * __restrict ps)
{
+ static mbstate_t mbs;
- return (mbrtowc(NULL, s, n, NULL));
+ if (ps == NULL)
+ ps = &mbs;
+ return (mbrtowc(NULL, s, n, ps));
}
diff --git a/lib/libc/locale/mbrtowc.c b/lib/libc/locale/mbrtowc.c
index f3b12b4..22a9041 100644
--- a/lib/libc/locale/mbrtowc.c
+++ b/lib/libc/locale/mbrtowc.c
@@ -36,6 +36,9 @@ size_t
mbrtowc(wchar_t * __restrict pwc, const char * __restrict s,
size_t n, mbstate_t * __restrict ps)
{
+ static mbstate_t mbs;
+ if (ps == NULL)
+ ps = &mbs;
return (__mbrtowc(pwc, s, n, ps));
}
diff --git a/lib/libc/locale/mbsrtowcs.c b/lib/libc/locale/mbsrtowcs.c
index 3e7b3b8..8b3de2f 100644
--- a/lib/libc/locale/mbsrtowcs.c
+++ b/lib/libc/locale/mbsrtowcs.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002 Tim J. Robbins.
+ * Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,8 +34,9 @@ __FBSDID("$FreeBSD$");
size_t
mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len,
- mbstate_t * __restrict ps __unused)
+ mbstate_t * __restrict ps)
{
+ static mbstate_t mbs;
const char *s;
size_t nchr;
wchar_t wc;
@@ -44,9 +45,11 @@ mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len,
s = *src;
nchr = 0;
+ if (ps == NULL)
+ ps = &mbs;
if (dst == NULL) {
for (;;) {
- if ((nb = (int)mbrtowc(&wc, s, MB_CUR_MAX, NULL)) < 0)
+ if ((nb = (int)mbrtowc(&wc, s, MB_CUR_MAX, ps)) < 0)
/* Invalid sequence - mbrtowc() sets errno. */
return ((size_t)-1);
else if (nb == 0)
@@ -58,7 +61,7 @@ mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len,
}
while (len-- > 0) {
- if ((nb = (int)mbrtowc(dst, s, MB_CUR_MAX, NULL)) < 0) {
+ if ((nb = (int)mbrtowc(dst, s, MB_CUR_MAX, ps)) < 0) {
*src = s;
return ((size_t)-1);
} else if (nb == 0) {
diff --git a/lib/libc/locale/mbstowcs.c b/lib/libc/locale/mbstowcs.c
index 419c1d3..b63f1f2 100644
--- a/lib/libc/locale/mbstowcs.c
+++ b/lib/libc/locale/mbstowcs.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002, 2003 Tim J. Robbins.
+ * Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,17 +28,12 @@
__FBSDID("$FreeBSD$");
#include <stdlib.h>
-#include <string.h>
#include <wchar.h>
size_t
mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n)
{
+ static mbstate_t mbs;
- /*
- * We pass NULL as the state pointer to mbsrtowcs() because we don't
- * support state-dependent encodings and don't want to waste time
- * creating a zeroed mbstate_t that will not be used.
- */
- return (mbsrtowcs(pwcs, &s, n, NULL));
+ return (mbsrtowcs(pwcs, &s, n, &mbs));
}
diff --git a/lib/libc/locale/mbtowc.c b/lib/libc/locale/mbtowc.c
index cc88566..465f45a 100644
--- a/lib/libc/locale/mbtowc.c
+++ b/lib/libc/locale/mbtowc.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002, 2003 Tim J. Robbins.
+ * Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,17 +36,16 @@ __FBSDID("$FreeBSD$");
int
mbtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n)
{
+ static const mbstate_t initial;
+ static mbstate_t mbs;
size_t rval;
- if (s == NULL)
+ if (s == NULL) {
/* No support for state dependent encodings. */
+ mbs = initial;
return (0);
- /*
- * We pass NULL as the state pointer to mbrtowc() because we don't
- * support state-dependent encodings and don't want to waste time
- * creating a zeroed mbstate_t that will not be used.
- */
- rval = mbrtowc(pwc, s, n, NULL);
+ }
+ rval = mbrtowc(pwc, s, n, &mbs);
if (rval == (size_t)-1 || rval == (size_t)-2)
return (-1);
if (rval > INT_MAX) {
diff --git a/lib/libc/locale/wcrtomb.c b/lib/libc/locale/wcrtomb.c
index 722e5c1..5f79949 100644
--- a/lib/libc/locale/wcrtomb.c
+++ b/lib/libc/locale/wcrtomb.c
@@ -34,6 +34,9 @@ extern size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict);
size_t
wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps)
{
+ static mbstate_t mbs;
+ if (ps == NULL)
+ ps = &mbs;
return (__wcrtomb(s, wc, ps));
}
diff --git a/lib/libc/locale/wcsrtombs.c b/lib/libc/locale/wcsrtombs.c
index ea3354b..4fa5ff8 100644
--- a/lib/libc/locale/wcsrtombs.c
+++ b/lib/libc/locale/wcsrtombs.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002 Tim J. Robbins.
+ * Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
@@ -35,8 +34,10 @@ __FBSDID("$FreeBSD$");
size_t
wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len,
- mbstate_t * __restrict ps __unused)
+ mbstate_t * __restrict ps)
{
+ static mbstate_t mbs;
+ mbstate_t mbsbak;
char buf[MB_LEN_MAX];
const wchar_t *s;
size_t nbytes;
@@ -45,9 +46,11 @@ wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len,
s = *src;
nbytes = 0;
+ if (ps == NULL)
+ ps = &mbs;
if (dst == NULL) {
for (;;) {
- if ((nb = (int)wcrtomb(buf, *s, NULL)) < 0)
+ if ((nb = (int)wcrtomb(buf, *s, ps)) < 0)
/* Invalid character - wcrtomb() sets errno. */
return ((size_t)-1);
else if (*s == L'\0')
@@ -61,19 +64,28 @@ wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len,
while (len > 0) {
if (len > (size_t)MB_CUR_MAX) {
/* Enough space to translate in-place. */
- if ((nb = (int)wcrtomb(dst, *s, NULL)) < 0) {
+ if ((nb = (int)wcrtomb(dst, *s, ps)) < 0) {
*src = s;
return ((size_t)-1);
}
} else {
- /* May not be enough space; use temp. buffer. */
- if ((nb = (int)wcrtomb(buf, *s, NULL)) < 0) {
+ /*
+ * May not be enough space; use temp. buffer.
+ *
+ * We need to save a copy of the conversion state
+ * here so we can restore it if the multibyte
+ * character is too long for the buffer.
+ */
+ mbsbak = *ps;
+ if ((nb = (int)wcrtomb(buf, *s, ps)) < 0) {
*src = s;
return ((size_t)-1);
}
- if (nb > (int)len)
+ if (nb > (int)len) {
/* MB sequence for character won't fit. */
+ *ps = mbsbak;
break;
+ }
memcpy(dst, buf, nb);
}
if (*s == L'\0') {
diff --git a/lib/libc/locale/wcstombs.c b/lib/libc/locale/wcstombs.c
index f415aed..cc5fab4 100644
--- a/lib/libc/locale/wcstombs.c
+++ b/lib/libc/locale/wcstombs.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002, 2003 Tim J. Robbins.
+ * Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,17 +28,12 @@
__FBSDID("$FreeBSD$");
#include <stdlib.h>
-#include <string.h>
#include <wchar.h>
size_t
wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
{
+ static mbstate_t mbs;
- /*
- * We pass NULL as the state pointer to wcsrtombs() because we don't
- * support state-dependent encodings and don't want to waste time
- * creating a zeroed mbstate_t that will not be used.
- */
- return (wcsrtombs(s, &pwcs, n, NULL));
+ return (wcsrtombs(s, &pwcs, n, &mbs));
}
diff --git a/lib/libc/locale/wctob.c b/lib/libc/locale/wctob.c
index da7afcf..4f4d295 100644
--- a/lib/libc/locale/wctob.c
+++ b/lib/libc/locale/wctob.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002, 2003 Tim J. Robbins.
+ * Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,20 +29,16 @@ __FBSDID("$FreeBSD$");
#include <limits.h>
#include <stdio.h>
-#include <string.h>
#include <wchar.h>
int
wctob(wint_t c)
{
+ static const mbstate_t initial;
+ mbstate_t mbs = initial;
char buf[MB_LEN_MAX];
- /*
- * We pass NULL as the state pointer to wcrtomb() because we don't
- * support state-dependent encodings and don't want to waste time
- * creating a zeroed mbstate_t that will not be used.
- */
- if (c == WEOF || wcrtomb(buf, c, NULL) != 1)
+ if (c == WEOF || wcrtomb(buf, c, &mbs) != 1)
return (EOF);
return ((unsigned char)*buf);
}
diff --git a/lib/libc/locale/wctomb.c b/lib/libc/locale/wctomb.c
index e212b96..9e6f183 100644
--- a/lib/libc/locale/wctomb.c
+++ b/lib/libc/locale/wctomb.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002, 2003 Tim J. Robbins.
+ * Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,20 +36,16 @@ __FBSDID("$FreeBSD$");
int
wctomb(char *s, wchar_t wchar)
{
- char buf[MB_LEN_MAX];
+ static const mbstate_t initial;
+ static mbstate_t mbs;
size_t rval;
- if (s == NULL)
+ if (s == NULL) {
/* No support for state dependent encodings. */
+ mbs = initial;
return (0);
- if (s == NULL)
- s = buf;
- /*
- * We pass NULL as the state pointer to wcrtomb() because we don't
- * support state-dependent encodings and don't want to waste time
- * creating a zeroed mbstate_t that will not be used.
- */
- if ((rval = wcrtomb(s, wchar, NULL)) == (size_t)-1)
+ }
+ if ((rval = wcrtomb(s, wchar, &mbs)) == (size_t)-1)
return (-1);
if (rval > INT_MAX) {
errno = ERANGE;
OpenPOWER on IntegriCloud