Make multibyte result constants public.
The magic numbers that C defines are obnoxious. We had partial
definitions for these internally. Add the missing one and move them to
a public header for anyone else that may want to use them.
Bug: None
Test: None
Change-Id: Ia6b8cff4310bcccb23078c52216528db668ac966
diff --git a/libc/bionic/c32rtomb.cpp b/libc/bionic/c32rtomb.cpp
index 4fa76ff..a7cd207 100644
--- a/libc/bionic/c32rtomb.cpp
+++ b/libc/bionic/c32rtomb.cpp
@@ -78,7 +78,7 @@
length = 4;
} else {
errno = EILSEQ;
- return __MB_ERR_ILLEGAL_SEQUENCE;
+ return BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE;
}
// Output the octets representing the character in chunks
diff --git a/libc/bionic/iconv.cpp b/libc/bionic/iconv.cpp
index 79a429c..5bff50a 100644
--- a/libc/bionic/iconv.cpp
+++ b/libc/bionic/iconv.cpp
@@ -160,9 +160,9 @@
case UTF_8:
src_bytes_used = mbrtoc32(&wc, *src_buf, *src_bytes_left, &ps);
- if (src_bytes_used == __MB_ERR_ILLEGAL_SEQUENCE) {
+ if (src_bytes_used == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
break; // EILSEQ already set.
- } else if (src_bytes_used == __MB_ERR_INCOMPLETE_SEQUENCE) {
+ } else if (src_bytes_used == BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
errno = EINVAL;
return false;
}
@@ -235,9 +235,9 @@
case UTF_8:
dst_bytes_used = c32rtomb(buf, wc, &ps);
- if (dst_bytes_used == __MB_ERR_ILLEGAL_SEQUENCE) {
+ if (dst_bytes_used == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
break; // EILSEQ already set.
- } else if (dst_bytes_used == __MB_ERR_INCOMPLETE_SEQUENCE) {
+ } else if (dst_bytes_used == BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
errno = EINVAL;
return false;
}
diff --git a/libc/bionic/mbrtoc32.cpp b/libc/bionic/mbrtoc32.cpp
index d37ca66..c26dd71 100644
--- a/libc/bionic/mbrtoc32.cpp
+++ b/libc/bionic/mbrtoc32.cpp
@@ -109,7 +109,7 @@
mbstate_set_byte(state, bytes_so_far + i, *s++);
}
if (i < bytes_wanted) {
- return __MB_ERR_INCOMPLETE_SEQUENCE;
+ return BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE;
}
// Decode the octet sequence representing the character in chunks
diff --git a/libc/bionic/wchar.cpp b/libc/bionic/wchar.cpp
index bb97b3e..b8c4432 100644
--- a/libc/bionic/wchar.cpp
+++ b/libc/bionic/wchar.cpp
@@ -27,10 +27,10 @@
*/
#include <errno.h>
-#include <sys/param.h>
#include <string.h>
-#include <wchar.h>
+#include <sys/param.h>
#include <uchar.h>
+#include <wchar.h>
#include "private/bionic_mbstate.h"
@@ -88,10 +88,10 @@
r = 1;
} else {
r = mbrtowc(nullptr, *src + i, nmc - i, state);
- if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
+ if (r == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
return mbstate_reset_and_return_illegal(EILSEQ, state);
}
- if (r == __MB_ERR_INCOMPLETE_SEQUENCE) {
+ if (r == BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if (r == 0) {
@@ -114,11 +114,11 @@
}
} else {
r = mbrtowc(dst + o, *src + i, nmc - i, state);
- if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
+ if (r == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
*src += i;
return mbstate_reset_and_return_illegal(EILSEQ, state);
}
- if (r == __MB_ERR_INCOMPLETE_SEQUENCE) {
+ if (r == BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
*src += nmc;
return mbstate_reset_and_return_illegal(EILSEQ, state);
}
@@ -166,7 +166,7 @@
r = 1;
} else {
r = wcrtomb(buf, wc, state);
- if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
+ if (r == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
return r;
}
}
@@ -187,14 +187,14 @@
} else if (len - o >= sizeof(buf)) {
// Enough space to translate in-place.
r = wcrtomb(dst + o, wc, state);
- if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
+ if (r == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
*src += i;
return r;
}
} else {
// May not be enough space; use temp buffer.
r = wcrtomb(buf, wc, state);
- if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
+ if (r == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
*src += i;
return r;
}
diff --git a/libc/include/bits/bionic_multibyte_result.h b/libc/include/bits/bionic_multibyte_result.h
new file mode 100644
index 0000000..0d5cf21
--- /dev/null
+++ b/libc/include/bits/bionic_multibyte_result.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+/**
+ * @file bits/bionic_multibyte_result.h
+ * @brief Named values for the magic number return values of multibyte
+ * conversion APIs defined by C.
+ */
+
+#include <stddef.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/**
+ * @brief The error values defined by C for multibyte conversion APIs.
+ *
+ * Refer to C23 7.30.1 Restartable multibyte/wide character conversion functions
+ * for more details.
+ */
+enum : size_t {
+ /// @brief An encoding error occurred. The bytes read are not a valid unicode
+ /// character, nor are they a partially valid character.
+ BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE = -1UL,
+#define BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE
+
+ /// @brief The bytes read may produce a valid unicode character, but the
+ /// sequence is incomplete. Future calls may complete the character.
+ BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE = -2UL,
+#define BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE
+
+ /// @brief The output of the call was the result of a previous successful
+ /// decoding. No new bytes were consumed.
+ ///
+ /// The common case for this return value is when mbrtoc16 returns the low
+ /// surrogate of a pair.
+ BIONIC_MULTIBYTE_RESULT_NO_BYTES_CONSUMED = -3UL,
+#define BIONIC_MULTIBYTE_RESULT_NO_BYTES_CONSUMED BIONIC_MULTIBYTE_RESULT_NO_BYTES_CONSUMED
+};
+
+__END_DECLS
diff --git a/libc/include/uchar.h b/libc/include/uchar.h
index 0c7424d..626372a 100644
--- a/libc/include/uchar.h
+++ b/libc/include/uchar.h
@@ -35,6 +35,8 @@
#include <stddef.h>
#include <sys/cdefs.h>
+
+#include <bits/bionic_multibyte_result.h>
#include <bits/mbstate_t.h>
__BEGIN_DECLS
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index 2671580..c4e9679 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -37,6 +37,7 @@
#include <time.h>
#include <xlocale.h>
+#include <bits/bionic_multibyte_result.h>
#include <bits/mbstate_t.h>
#include <bits/wchar_limits.h>
#include <bits/wctype.h>
diff --git a/libc/private/bionic_mbstate.h b/libc/private/bionic_mbstate.h
index 243b220..b041a3d 100644
--- a/libc/private/bionic_mbstate.h
+++ b/libc/private/bionic_mbstate.h
@@ -34,15 +34,9 @@
__BEGIN_DECLS
-/*
- * These return values are specified by POSIX for multibyte conversion
- * functions.
- */
-#define __MB_ERR_ILLEGAL_SEQUENCE static_cast<size_t>(-1)
-#define __MB_ERR_INCOMPLETE_SEQUENCE static_cast<size_t>(-2)
-
-#define __MB_IS_ERR(rv) (rv == __MB_ERR_ILLEGAL_SEQUENCE || \
- rv == __MB_ERR_INCOMPLETE_SEQUENCE)
+#define __MB_IS_ERR(rv) \
+ (rv == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE || \
+ rv == BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE)
static inline __wur bool mbstate_is_initial(const mbstate_t* ps) {
return *(reinterpret_cast<const uint32_t*>(ps->__seq)) == 0;
@@ -66,7 +60,7 @@
static inline __wur size_t mbstate_reset_and_return_illegal(int _errno, mbstate_t* ps) {
errno = _errno;
*(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
- return __MB_ERR_ILLEGAL_SEQUENCE;
+ return BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE;
}
static inline __wur size_t mbstate_reset_and_return(int _return, mbstate_t* ps) {
diff --git a/libc/stdio/vfscanf.cpp b/libc/stdio/vfscanf.cpp
index 3133f1f..3607995 100644
--- a/libc/stdio/vfscanf.cpp
+++ b/libc/stdio/vfscanf.cpp
@@ -327,12 +327,12 @@
fp->_r--;
memset(&mbs, 0, sizeof(mbs));
nconv = mbrtowc(wcp, buf, bytes, &mbs);
- if (nconv == __MB_ERR_ILLEGAL_SEQUENCE) {
+ if (nconv == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
fp->_flags |= __SERR;
goto input_failure;
}
if (nconv == 0 && !(flags & SUPPRESS)) *wcp = L'\0';
- if (nconv != __MB_ERR_INCOMPLETE_SEQUENCE) {
+ if (nconv != BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
nread += bytes;
width--;
if (!(flags & SUPPRESS)) wcp++;
@@ -417,11 +417,11 @@
wchar_t wc = L'\0';
memset(&mbs, 0, sizeof(mbs));
nconv = mbrtowc(&wc, buf, bytes, &mbs);
- if (nconv == __MB_ERR_ILLEGAL_SEQUENCE) {
+ if (nconv == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
fp->_flags |= __SERR;
goto input_failure;
}
- if (nconv != __MB_ERR_INCOMPLETE_SEQUENCE) {
+ if (nconv != BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
if ((c == CT_CCL && wctob(wc) != EOF && !ccltab[wctob(wc)]) || (c == CT_STRING && iswspace(wc))) {
while (bytes != 0) {
bytes--;