summaryrefslogtreecommitdiff
path: root/lib/mbrtowc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mbrtowc.c')
-rw-r--r--lib/mbrtowc.c63
1 files changed, 34 insertions, 29 deletions
diff --git a/lib/mbrtowc.c b/lib/mbrtowc.c
index dff12962d..2e5a0b6aa 100644
--- a/lib/mbrtowc.c
+++ b/lib/mbrtowc.c
@@ -1,5 +1,5 @@
/* Convert multibyte character to wide character.
- Copyright (C) 1999-2002, 2005-2014 Free Software Foundation, Inc.
+ Copyright (C) 1999-2002, 2005-2016 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2008.
This program is free software: you can redistribute it and/or modify
@@ -20,6 +20,11 @@
/* Specification. */
#include <wchar.h>
+#if C_LOCALE_MAYBE_EILSEQ
+# include "hard-locale.h"
+# include <locale.h>
+#endif
+
#if GNULIB_defined_mbstate_t
/* Implement mbrtowc() on top of mbtowc(). */
@@ -328,7 +333,10 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
size_t
rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
{
-# if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG
+ size_t ret;
+ wchar_t wc;
+
+# if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG || MBRTOWC_EMPTY_INPUT_BUG
if (s == NULL)
{
pwc = NULL;
@@ -337,6 +345,14 @@ rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
}
# endif
+# if MBRTOWC_EMPTY_INPUT_BUG
+ if (n == 0)
+ return (size_t) -2;
+# endif
+
+ if (! pwc)
+ pwc = &wc;
+
# if MBRTOWC_RETVAL_BUG
{
static mbstate_t internal_state;
@@ -352,8 +368,7 @@ rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
size_t count = 0;
for (; n > 0; s++, n--)
{
- wchar_t wc;
- size_t ret = mbrtowc (&wc, s, 1, ps);
+ ret = mbrtowc (&wc, s, 1, ps);
if (ret == (size_t)(-1))
return (size_t)(-1);
@@ -361,8 +376,7 @@ rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
if (ret != (size_t)(-2))
{
/* The multibyte character has been completed. */
- if (pwc != NULL)
- *pwc = wc;
+ *pwc = wc;
return (wc == 0 ? 0 : count);
}
}
@@ -371,32 +385,23 @@ rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
}
# endif
-# if MBRTOWC_NUL_RETVAL_BUG
- {
- wchar_t wc;
- size_t ret = mbrtowc (&wc, s, n, ps);
-
- if (ret != (size_t)(-1) && ret != (size_t)(-2))
- {
- if (pwc != NULL)
- *pwc = wc;
- if (wc == 0)
- ret = 0;
- }
- return ret;
- }
-# else
- {
-# if MBRTOWC_NULL_ARG1_BUG
- wchar_t dummy;
+ ret = mbrtowc (pwc, s, n, ps);
- if (pwc == NULL)
- pwc = &dummy;
-# endif
+# if MBRTOWC_NUL_RETVAL_BUG
+ if (ret < (size_t) -2 && !*pwc)
+ return 0;
+# endif
- return mbrtowc (pwc, s, n, ps);
- }
+# if C_LOCALE_MAYBE_EILSEQ
+ if ((size_t) -2 <= ret && n != 0 && ! hard_locale (LC_CTYPE))
+ {
+ unsigned char uc = *s;
+ *pwc = uc;
+ return 1;
+ }
# endif
+
+ return ret;
}
#endif