+2023-03-30 Bruno Haible <bruno@clisp.org>
+
+ mbsrtowcs: Fix behaviour in the C locale.
+ * m4/mbsrtowcs.m4 (gl_FUNC_MBSRTOWCS): Invoke gl_MBRTOWC_C_LOCALE. If
+ mbrtowc is buggy in the C locale, override also mbsrtowcs.
+ * modules/mbsrtowcs (Files): Add m4/mbrtowc.m4.
+ * tests/test-mbsrtowcs.c (main): Add a test of the C locale, based on
+ tests/test-mbrtowc.c.
+ * tests/test-mbsrtowcs5.sh: New file, based on tests/test-mbrtowc5.sh.
+ * modules/mbsrtowcs-tests (Files): Add it.
+ (Makefile.am): Test it.
+ * doc/posix-functions/mbsrtowcs.texi: Mention the C locale behaviour
+ bug.
+
2023-03-30 Bruno Haible <bruno@clisp.org>
mbrlen: Add tests.
-# mbsrtowcs.m4 serial 14
+# mbsrtowcs.m4 serial 15
dnl Copyright (C) 2008-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
*yes) ;;
*) REPLACE_MBSRTOWCS=1 ;;
esac
+ if test $REPLACE_MBSRTOWCS = 0; then
+ gl_MBRTOWC_C_LOCALE
+ case "$gl_cv_func_mbrtowc_C_locale_sans_EILSEQ" in
+ *yes) ;;
+ *) REPLACE_MBSRTOWCS=1 ;;
+ esac
+ fi
fi
fi
])
}
break;
+ case '5':
+ /* C or POSIX locale. */
+ {
+ char input[] = "n/a";
+ memset (&state, '\0', sizeof (mbstate_t));
+
+ src = input;
+ temp_state = state;
+ ret = mbsrtowcs (NULL, &src, unlimited ? BUFSIZE : 1, &temp_state);
+ ASSERT (ret == 3);
+ ASSERT (src == input);
+ ASSERT (mbsinit (&state));
+
+ src = input;
+ ret = mbsrtowcs (buf, &src, unlimited ? BUFSIZE : 1, &state);
+ ASSERT (ret == (unlimited ? 3 : 1));
+ ASSERT (src == (unlimited ? NULL : input + 1));
+ ASSERT (buf[0] == 'n');
+ if (unlimited)
+ {
+ ASSERT (buf[1] == '/');
+ ASSERT (buf[2] == 'a');
+ ASSERT (buf[3] == 0);
+ ASSERT (buf[4] == (wchar_t) 0xBADFACE);
+ }
+ else
+ ASSERT (buf[1] == (wchar_t) 0xBADFACE);
+ ASSERT (mbsinit (&state));
+ }
+ {
+ int c;
+ char input[2];
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ for (c = 0; c < 0x100; c++)
+ if (c != 0)
+ {
+ /* We are testing all nonnull bytes. */
+ input[0] = c;
+ input[1] = '\0';
+
+ src = input;
+ ret = mbsrtowcs (NULL, &src, unlimited ? BUFSIZE : 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (src == input);
+ ASSERT (mbsinit (&state));
+
+ buf[0] = buf[1] = (wchar_t) 0xBADFACE;
+ src = input;
+ ret = mbsrtowcs (buf, &src, unlimited ? BUFSIZE : 1, &state);
+ /* POSIX:2018 says: "In the POSIX locale an [EILSEQ] error
+ cannot occur since all byte values are valid characters." */
+ ASSERT (ret == 1);
+ ASSERT (src == (unlimited ? NULL : input + 1));
+ if (c < 0x80)
+ /* c is an ASCII character. */
+ ASSERT (buf[0] == c);
+ else
+ /* On most platforms, the bytes 0x80..0xFF map to U+0080..U+00FF.
+ But on musl libc, the bytes 0x80..0xFF map to U+DF80..U+DFFF. */
+ ASSERT (buf[0] == (btowc (c) == 0xDF00 + c ? btowc (c) : c));
+ ASSERT (mbsinit (&state));
+ }
+ }
+ break;
+
default:
return 1;
}