1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
#ifndef ___WCHAR_H__
#define ___WCHAR_H__
#include <wchar.h>
#include <stdlib.h>
#include "_safety.h"
#include "locale/_locale.h"
extern struct __wchar_h {
wchar_t **wcstok;
size_t nwcstok;
} __wchar_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
|