tests/libc: Add 0042-mbsrtowc - scc - simple c99 compiler | |
git clone git://git.simple-cc.org/scc | |
Log | |
Files | |
Refs | |
Submodules | |
README | |
LICENSE | |
--- | |
commit 36606c7df70f2465a4305395c529e7ea1add693f | |
parent 01921365fc084e3b592c00bdd090d0d457502904 | |
Author: Roberto E. Vargas Caballero <[email protected]> | |
Date: Fri, 21 Mar 2025 19:23:17 +0100 | |
tests/libc: Add 0042-mbsrtowc | |
Diffstat: | |
M src/libc/wchar/mbsrtowcs.c | 26 +++++++++++++++++++++----- | |
M tests/libc/execute/.gitignore | 1 + | |
A tests/libc/execute/0042-mbsrtowcs.c | 126 +++++++++++++++++++++++++++++… | |
M tests/libc/execute/libc-tests.lst | 1 + | |
4 files changed, 149 insertions(+), 5 deletions(-) | |
--- | |
diff --git a/src/libc/wchar/mbsrtowcs.c b/src/libc/wchar/mbsrtowcs.c | |
@@ -1,4 +1,5 @@ | |
#include <limits.h> | |
+#include <string.h> | |
#include <wchar.h> | |
#undef mbsrtowcs | |
@@ -8,24 +9,39 @@ mbsrtowcs(wchar_t *restrict dest, const char **restrict src, … | |
mbstate_t *restrict ps) | |
{ | |
wchar_t wc; | |
+ const char *s = *src; | |
size_t cnt, n; | |
+ static mbstate_t st; | |
+ | |
+ if (!ps) | |
+ ps = &st; | |
for (n = 0; ; n++) { | |
- cnt = mbrtowc(&wc, *src, MB_LEN_MAX, ps); | |
+ cnt = mbrtowc(&wc, s, MB_LEN_MAX, ps); | |
+ if (cnt == (size_t) -2) { | |
+ s += MB_LEN_MAX; | |
+ continue; | |
+ } | |
if (cnt == (size_t) -1) | |
return -1; | |
if (dest) { | |
- if (n == len) | |
+ if (n == len) { | |
+ *src = s; | |
return n; | |
+ } | |
*dest++ = wc; | |
} | |
- *src += cnt; | |
+ s += cnt; | |
- if (wc == L'\0') | |
+ if (wc == 0) | |
break; | |
} | |
- *src = NULL; | |
+ | |
+ if (dest) { | |
+ memset(ps, 0, sizeof(mbstate_t)); | |
+ *src = NULL; | |
+ } | |
return n; | |
} | |
diff --git a/tests/libc/execute/.gitignore b/tests/libc/execute/.gitignore | |
@@ -39,6 +39,7 @@ | |
0039-mbrtowc | |
0040-wcrtomb | |
0041-mbrlen | |
+0042-mbsrtowcs | |
0044-wcslen | |
0045-wcscmp | |
0046-wcsncmp | |
diff --git a/tests/libc/execute/0042-mbsrtowcs.c b/tests/libc/execute/0042-mbsr… | |
@@ -0,0 +1,126 @@ | |
+#include <assert.h> | |
+#include <errno.h> | |
+#include <stdio.h> | |
+#include <stdlib.h> | |
+#include <string.h> | |
+#include <wchar.h> | |
+ | |
+/* | |
+output: | |
+testing | |
+testing mbsrtowcs1 | |
+testing mbsrtowcs2 | |
+testing mbstowcs | |
+done | |
+end: | |
+*/ | |
+ | |
+#define NELEM(x) (sizeof(x)/sizeof(x[0])) | |
+ | |
+static char str[20]; | |
+static wchar_t wcs[20]; | |
+static struct mbstests { | |
+ char *s; | |
+ char *sexp; | |
+ | |
+ wchar_t *wcs; | |
+ wchar_t *wcsexp; | |
+ | |
+ size_t n; | |
+ int r; | |
+ int syserr; | |
+ int mbstate; | |
+} tests[] = { | |
+ /* s sexp wcs wcsexp n r syserr mbst… | |
+ {"\0", NULL, wcs, (wchar_t[]) {0}, 1, 0, 0, … | |
+ {"\0", str, wcs, (wchar_t[]) {0}, 0, 0, 0, … | |
+ {"\0", str, NULL, (wchar_t[]) {0}, 1, 0, 0, … | |
+ {"\0", str, NULL, (wchar_t[]) {0}, 0, 0, 0, … | |
+ | |
+ {"\x31", NULL, wcs, (wchar_t[]) {0x31, 0}, 2, 1, 0, … | |
+ {"\x31", str+1, wcs, (wchar_t[]) {0x31, 0}, 1, 1, 0, … | |
+ {"\x31", str, NULL, (wchar_t[]) {0x31, 0}, 1, 1, 0, … | |
+ {"\x31", str, NULL, (wchar_t[]) {0x31, 0}, 0, 1, 0, … | |
+ | |
+ {"\x21\xc2\xa1\xe2\x80\x94\xf0\x9f\x92\xa9", | |
+ NULL, wcs, | |
+ (wchar_t[]) {0x21,0xa1,0x2014,0x1f4A9}, 20, 4, 0, 1}, | |
+ | |
+ {"\xf0\x9f",str, wcs, NULL, 20,-1, EILSEQ, … | |
+}; | |
+ | |
+void | |
+tests_mbsrtowcs(void) | |
+{ | |
+ int r; | |
+ const char *s; | |
+ mbstate_t st; | |
+ struct mbstests *tp; | |
+ | |
+ puts("testing mbsrtowcs1"); | |
+ for (tp = tests; tp < &tests[NELEM(tests)]; ++tp) { | |
+ errno = 0; | |
+ if (tp->s != NULL) | |
+ s = strcpy(str, tp->s); | |
+ memset(wcs, -1, sizeof(wcs)); | |
+ | |
+ r = mbsrtowcs(tp->wcs, &s, tp->n, NULL); | |
+ assert(tp->r == r); | |
+ assert(tp->syserr == errno); | |
+ if (tp->r >= 0) { | |
+ assert(s == tp->sexp); | |
+ if (tp->wcs) | |
+ assert(!wcsncmp(tp->wcsexp, tp->wcs, tp->r)); | |
+ } | |
+ } | |
+ | |
+ puts("testing mbsrtowcs2"); | |
+ for (tp = tests; tp < &tests[NELEM(tests)]; ++tp) { | |
+ errno = 0; | |
+ if (tp->s != NULL) | |
+ s = strcpy(str, tp->s); | |
+ memset(wcs, -1, sizeof(wcs)); | |
+ memset(&st, 0, sizeof(st)); | |
+ | |
+ r = mbsrtowcs(tp->wcs, &s, tp->n, &st); | |
+ assert(tp->r == r); | |
+ assert(tp->syserr == errno); | |
+ if (tp->r >= 0) { | |
+ assert(s == tp->sexp); | |
+ if (tp->wcs) | |
+ assert(!wcsncmp(tp->wcsexp, tp->wcs, tp->r)); | |
+ assert(mbsinit(&st) != 0 == tp->mbstate); | |
+ } | |
+ } | |
+} | |
+ | |
+void | |
+tests_mbstowcs(void) | |
+{ | |
+ int r; | |
+ struct mbstests *tp; | |
+ | |
+ puts("testing mbstowcs"); | |
+ for (tp = tests; tp < &tests[NELEM(tests)]; ++tp) { | |
+ errno = 0; | |
+ memset(wcs, -1, sizeof(wcs)); | |
+ | |
+ r = mbstowcs(tp->wcs, tp->s, tp->n); | |
+ assert(tp->r == r); | |
+ assert(tp->syserr == errno); | |
+ if (tp->r >= 0) { | |
+ if (tp->wcs) | |
+ assert(!wcsncmp(tp->wcsexp, tp->wcs, tp->r)); | |
+ } | |
+ } | |
+} | |
+ | |
+int | |
+main(void) | |
+{ | |
+ puts("testing"); | |
+ tests_mbsrtowcs(); | |
+ tests_mbstowcs(); | |
+ puts("done"); | |
+ return 0; | |
+} | |
diff --git a/tests/libc/execute/libc-tests.lst b/tests/libc/execute/libc-tests.… | |
@@ -38,6 +38,7 @@ | |
0039-mbrtowc | |
0040-wcrtomb | |
0041-mbrlen | |
+0042-mbsrtowcs | |
0044-wcslen | |
0045-wcscmp | |
0046-wcsncmp |