diff options
Diffstat (limited to 'src/wchar/_wchar.h')
-rw-r--r-- | src/wchar/_wchar.h | 53 |
1 files changed, 53 insertions, 0 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 |