-/* $OpenBSD: citrus_none.c,v 1.10 2021/05/08 07:26:19 martijn Exp $ */
+/* $OpenBSD: citrus_none.c,v 1.11 2021/05/08 09:38:29 martijn Exp $ */
/* $NetBSD: citrus_none.c,v 1.18 2008/06/14 16:01:07 tnozaki Exp $ */
/*-
#include "citrus_ctype.h"
+static char wrapv(unsigned char);
+
+
+/*
+ * Convert an unsigned char value into a char value without relying on
+ * signed overflow behavior.
+ */
+static char
+wrapv(unsigned char ch)
+{
+ if (ch >= 0x80)
+ return (int)ch - 0x100;
+ else
+ return ch;
+}
+
size_t
_citrus_none_ctype_mbrtowc(wchar_t * __restrict pwc,
const char * __restrict s, size_t n)
return 0;
if (n == 0)
return -2;
- if (*s > 0x7f) {
- errno = EILSEQ;
- return -1;
- }
if (pwc != NULL)
- *pwc = (wchar_t)*s;
+ *pwc = (wchar_t)(unsigned char)*s;
return *s != '\0';
}
return strnlen(*src, nmc);
for (i = 0; i < nmc && i < len; i++)
- if ((*src)[i] > 0x7f) {
- errno = EILSEQ;
- return -1;
- }
- if ((dst[i] = (wchar_t)(*src)[i]) == L'\0') {
+ if ((dst[i] = (wchar_t)(unsigned char)(*src)[i]) == L'\0') {
*src = NULL;
return i;
}
if (s == NULL)
return 1;
- if (wc < 0 || wc > 0x7f) {
+ if (wc < 0 || wc > 0xff) {
errno = EILSEQ;
return -1;
}
- *s = (char)wc;
+ *s = wrapv(wc);
return 1;
}
if (dst == NULL) {
for (i = 0; i < nwc; i++) {
wchar_t wc = (*src)[i];
- if (wc < 0 || wc > 0x7f) {
+ if (wc < 0 || wc > 0xff) {
errno = EILSEQ;
return -1;
}
for (i = 0; i < nwc && i < len; i++) {
wchar_t wc = (*src)[i];
- if (wc < 0 || wc > 0x7f) {
+ if (wc < 0 || wc > 0xff) {
*src += i;
errno = EILSEQ;
return -1;
}
- dst[i] = (char)wc;
+ dst[i] = wrapv(wc);
if (wc == L'\0') {
*src = NULL;
return i;