diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wchar/_wchar.h | 53 | ||||
-rw-r--r-- | src/wchar/mbrlen.c | 10 | ||||
-rw-r--r-- | src/wchar/mbrtowc.c | 24 | ||||
-rw-r--r-- | src/wchar/mbsinit.c | 13 | ||||
-rw-r--r-- | src/wchar/mbsrtowcs.c | 24 | ||||
-rw-r--r-- | src/wchar/mbstate_t.h | 2 | ||||
-rw-r--r-- | src/wchar/wcrtomb.c | 19 | ||||
-rw-r--r-- | src/wchar/wcsrtombs.c | 22 |
8 files changed, 122 insertions, 45 deletions
diff --git a/src/wchar/_wchar.h b/src/wchar/_wchar.h new file mode 100644 index 00000000..e5d87c7e --- /dev/null +++ b/src/wchar/_wchar.h @@ -0,0 +1,53 @@ +#ifndef ___WCHAR_H__ +#define ___WCHAR_H__ + +#include <wchar.h> +#include <stdlib.h> +#include "_safety.h" +#include "locale/_locale.h" + +struct __mbstate_t { + unsigned int ctype_epoch; + enum { NONE, WTOMB, MBTOW } dir; + const char *mbs; + const wchar_t *wcs; +}; + +/* use mbstate_t: mbrlen, mbrtowc, wcrtomb, mbsrtowcs, wcsrtombs */ +/* TODO: save a pool of reusable struct __mbstate_t objects to avoid massive leakage */ +#define SET_MBSTATE(__m, __d, __s, __w) do { \ + if (__m->__impl == NULL) { \ + __m->__impl = malloc(sizeof(*__m->__impl)); \ + } \ + __m->__impl->ctype_epoch = __get_locale()->ctype_epoch; \ + __m->__impl->dir = __d; \ + __m->__impl->mbs = __s; \ + __m->__impl->wcs = __w; \ +} while (0) + +#ifndef NDEBUG +#define ASSERT_MBSTATE(__m, __d, __s, __w) do { \ + if (__m != NULL && __m->__impl != NULL) { \ + struct __mbstate_t *_m = __m->__impl; \ + if (_m->ctype_epoch != 0 && _m->ctype_epoch != __get_locale()->ctype_epoch) { \ + UNDEFINED("LC_CTYPE has changed since last intermediate use of %s", #__m); \ + } \ + if (_m->dir == WTOMB && __d == MBTOW) { \ + UNDEFINED("%s is tracking wide to multi-byte conversion", #__m); \ + } \ + if (_m->dir == MBTOW && __d == WTOMB) { \ + UNDEFINED("%s is tracking multi-byte to wide conversion", #__m); \ + } \ + if (_m->dir == MBTOW && _m->mbs != (const char *) __s) { \ + UNDEFINED("%s is tracking a different multi-byte string", #__m); \ + } \ + if (_m->dir == WTOMB && _m->wcs != (const wchar_t *) __w) { \ + UNDEFINED("%s is tracking a different wide character string", #__m); \ + } \ + } \ +} while (0) +#else +#define ASSERT_MBSTATE(__m, __d, __s, __w) (void)(__m) +#endif + +#endif diff --git a/src/wchar/mbrlen.c b/src/wchar/mbrlen.c index 135a56b2..06caa81b 100644 --- a/src/wchar/mbrlen.c +++ b/src/wchar/mbrlen.c @@ -1,20 +1,16 @@ -#if 0 - #include <wchar.h> +#include "_wchar.h" size_t mbrlen(const char * restrict s, size_t n, mbstate_t * restrict ps) { - + static mbstate_t internal = {0}; SIGNAL_SAFE(0); + ASSERT_MBSTATE(ps, MBTOW, NULL, NULL); /* TODO: overlap */ - static mbstate_t internal = 0; return mbrtowc(NULL, s, n, ps != NULL ? ps : &internal); } /* STDC(199409) */ - - -#endif diff --git a/src/wchar/mbrtowc.c b/src/wchar/mbrtowc.c index 16e2a937..aa7c4803 100644 --- a/src/wchar/mbrtowc.c +++ b/src/wchar/mbrtowc.c @@ -1,27 +1,29 @@ -#if 0 - #include <wchar.h> +#include "_wchar.h" +GCC_SSE_HACK size_t mbrtowc(wchar_t * restrict pwc, const char * restrict s, size_t n, mbstate_t * restrict ps) { + static struct __mbstate_t internal = { 0 }; + static mbstate_t ip = { &internal }; + + if (ps == NULL) { + ps = &ip; + } + SIGNAL_SAFE(0); + ASSERT_MBSTATE(ps, MBTOW, s, pwc); /* TODO: overlap */ - (void)ps; (void)pwc; (void)n; - if (s == NULL) { - s = ""; - n = 1; + return mbrtowc(NULL, "", 1, ps); } - /* TODO */ + SET_MBSTATE(ps, MBTOW, s, pwc); - return 0; + return n; } /* STDC(199409) */ - - -#endif diff --git a/src/wchar/mbsinit.c b/src/wchar/mbsinit.c index 52640483..9b41e2a2 100644 --- a/src/wchar/mbsinit.c +++ b/src/wchar/mbsinit.c @@ -1,12 +1,16 @@ -#if 0 - #include <wchar.h> +#include "_wchar.h" int mbsinit(const mbstate_t * ps) { SIGNAL_SAFE(0); - if (ps == NULL || *ps == 0) { + if (ps == NULL || ps->__impl == NULL) { + return 1; + } + + struct __mbstate_t *m = ps->__impl; + if (m->ctype_epoch == 0 && m->dir == NONE && m->mbs == NULL && m->wcs == NULL) { return 1; } @@ -16,6 +20,3 @@ int mbsinit(const mbstate_t * ps) /* STDC(199409) */ - - -#endif diff --git a/src/wchar/mbsrtowcs.c b/src/wchar/mbsrtowcs.c index 2f273598..a23402b3 100644 --- a/src/wchar/mbsrtowcs.c +++ b/src/wchar/mbsrtowcs.c @@ -1,19 +1,27 @@ -#if 0 - #include <wchar.h> +#include "_wchar.h" -size_t mbsrtowcs(wchar_t * restrict dst, const char * restrict src, size_t len, mbstate_t * restrict ps) +GCC_SSE_HACK +size_t mbsrtowcs(wchar_t * restrict dst, const char ** restrict src, size_t len, mbstate_t * restrict ps) { + static struct __mbstate_t internal = { 0 }; + static mbstate_t ip = { &internal }; + + if (ps == NULL) { + ps = &ip; + } + SIGNAL_SAFE(0); + ASSERT_MBSTATE(ps, MBTOW, *src, dst); /* TODO: overlap */ - (void)dst; (void)src; (void)len; (void)ps; - return 0; + SET_MBSTATE(ps, MBTOW, *src, dst); + + /* TODO: implement */ + + return len; } /* STDC(199409) */ - - -#endif diff --git a/src/wchar/mbstate_t.h b/src/wchar/mbstate_t.h index d29ecfa5..a0185f99 100644 --- a/src/wchar/mbstate_t.h +++ b/src/wchar/mbstate_t.h @@ -1,5 +1,5 @@ #include <wchar.h> -typedef int mbstate_t; +typedef struct { struct __mbstate_t *__impl; } mbstate_t; /* STDC(199409) diff --git a/src/wchar/wcrtomb.c b/src/wchar/wcrtomb.c index 20cbe235..c73cdce8 100644 --- a/src/wchar/wcrtomb.c +++ b/src/wchar/wcrtomb.c @@ -1,18 +1,27 @@ #include <wchar.h> #include <limits.h> -#include "_safety.h" +#include "_wchar.h" +GCC_SSE_HACK size_t wcrtomb(char * restrict s, wchar_t wc, mbstate_t * restrict ps) { + static struct __mbstate_t internal = { 0 }; + static mbstate_t ip = { &internal }; + + if (ps == NULL) { + ps = &ip; + } + SIGNAL_SAFE(0); + ASSERT_MBSTATE(ps, WTOMB, s, &wc); /* TODO: overlap */ - char buf[MB_LEN_MAX+1]; if (s == NULL) { - s = buf; - wc = L'\0'; + char buf[MB_LEN_MAX+1]; + return wcrtomb(buf, L'\0', ps); } - (void)wc; (void)ps; + + SET_MBSTATE(ps, WTOMB, s, &wc); /* do stuff */ return 0; diff --git a/src/wchar/wcsrtombs.c b/src/wchar/wcsrtombs.c index 9a3c6c87..c094de80 100644 --- a/src/wchar/wcsrtombs.c +++ b/src/wchar/wcsrtombs.c @@ -1,19 +1,27 @@ -#if 0 - #include <wchar.h> +#include "_wchar.h" +GCC_SSE_HACK size_t wcsrtombs(char * restrict dst, const wchar_t ** restrict src, size_t len, mbstate_t * restrict ps) { + static struct __mbstate_t internal = { 0 }; + static mbstate_t ip = { &internal }; + + if (ps == NULL) { + ps = &ip; + } + SIGNAL_SAFE(0); + ASSERT_MBSTATE(ps, WTOMB, dst, src); /* TODO: overlap */ - (void)dst; (void)src; (void)len; (void)ps; - return 0; + SET_MBSTATE(ps, WTOMB, dst, *src); + + /* TODO: conversion */ + + return len; } /* STDC(199409) */ - - -#endif |