diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 4f4879b71..c35e01ced 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,26 @@ +2002-04-01 Jeff Johnston + + * libc/include/sys/reent.h (_REENT_INIT_PTR): New macro for + initializing a struct _reent that has been dynamically allocated. + (_REENT_CHECK_MISC): New macro that checks _misc struct for + _REENT_SMALL and does nothing otherwise. + (_REENT_STRTOK_LAST): New macro for reentrant strtok. + (_REENT_MBLEN_STATE): New macro for reentrant mblen. + (_REENT_MBTOWC_STATE): New macro for reentrant mbtowc. + (_REENT_WCTOMB_STATE): New macro for reentrant wctomb. + [_REENT_SMALL](struct _misc_reent): New structure containing + miscellaneous reentrant areas needed by newlib. + [_REENT_SMALL](struct _reent): Add _misc pointer. + [_REENT_SMALL](_REENT_INIT_MISC): New macro. + * libc/string/strtok (strtok): Change to use _REENT_CHECK_MISC + and _REENT_STRTOK_LAST macros. + * libc/stdlib/mblen (mblen): Change to use _REENT_CHECK_MISC + and _REENT_MBLEN_STATE macros. + * libc/stdlib/mbtowc (mbtowc): Change to use _REENT_CHECK_MISC + and _REENT_MBTOWC_STATE macros. + * libc/stdlib/wctomb (wctomb): Change to use _REENT_CHECK_MISC + and _REENT_WCTOMB_STATE macros. + 2002-04-01 Till Straumann * libc/stdlib/getenv_r.c (_findenv_r): Add missing ENV_UNLOCK. diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h index 600e0b1f3..b1bf42c13 100644 --- a/newlib/libc/include/sys/reent.h +++ b/newlib/libc/include/sys/reent.h @@ -245,6 +245,16 @@ struct _mprec struct _Bigint **_freelist; }; + +struct _misc_reent +{ + /* miscellaneous reentrant data */ + char *_strtok_last; + int _mblen_state; + int _wctomb_state; + int _mbtowc_state; +}; + /* This version of _reent is layed our with "int"s in pairs, to help * ports with 16-bit int's but 32-bit pointers, align nicely. */ struct _reent @@ -289,13 +299,44 @@ struct _reent struct _glue __sglue; /* root of glue chain */ struct __sFILE *__sf; /* file descriptors */ struct __sFILE_fake __sf_fake; /* fake initial stdin/out/err */ + struct _misc_reent *_misc; /* strtok, multibyte states */ }; #define _REENT_INIT(var) \ { &var.__sf_fake, &var.__sf_fake, &var.__sf_fake, 0, 0, _NULL, 0, 0, \ "C", _NULL, _NULL, 0, 0, _NULL, _NULL, _NULL, _NULL, _NULL, \ - { 0, _NULL }, { _NULL, 0, _NULL }, 0 } + { 0, _NULL }, { _NULL, 0, _NULL }, 0, _NULL } +#define _REENT_INIT_PTR(var) \ + { var->_stdin = &var->__sf_fake; \ + var->_stdout = &var->__sf_fake; \ + var->_stderr = &var->__sf_fake; \ + var->_errno = 0; \ + var->_inc = 0; \ + var->_emergency = _NULL; \ + var->__sdidinit = 0; \ + var->_current_category = 0; \ + var->_current_locale = "C"; \ + var->_mp = _NULL; \ + var->__cleanup = _NULL; \ + var->_gamma_signgam = 0; \ + var->_cvtlen = 0; \ + var->_cvtbuf = _NULL; \ + var->_r48 = _NULL; \ + var->_localtime_buf = _NULL; \ + var->_asctime_buf = _NULL; \ + var->_sig_func = _NULL; + var->_atexit._ind = 0; \ + var->_atexit._fns = _NULL}; \ + var->__sglue._next = _NULL; \ + var->__sglue._niobs = 0; \ + var->__sglue._iobs = _NULL; \ + var->__sf = 0; \ + var->_misc = _NULL; \ + } + + /* signal info */ + void (**(_sig_func))(int); /* Only built the assert() calls if we are built with debugging. */ #if DEBUG #include @@ -347,6 +388,16 @@ struct _reent #define _REENT_CHECK_EMERGENCY(var) \ _REENT_CHECK(var, _emergency, char *, _REENT_EMERGENCY_SIZE, /* nothing */) +#define _REENT_INIT_MISC(var) do { \ + struct _reent *_r = (var); \ + _r->_misc->_strtok_last = _NULL; \ + _r->_misc->_mblen_state = 0; \ + _r->_misc->_wctomb_state = 0; \ + _r->_misc->_mbtowc_state = 0; \ +} while (0) +#define _REENT_CHECK_MISC(var) \ + _REENT_CHECK(var, _misc, struct _misc_reent *, sizeof *((var)->_misc), _REENT_INIT_MISC(var)) + #define _REENT_SIGNGAM(ptr) ((ptr)->_gamma_signgam) #define _REENT_RAND_NEXT(ptr) ((ptr)->_r48->_rand_next) #define _REENT_RAND48_SEED(ptr) ((ptr)->_r48->_seed) @@ -359,6 +410,10 @@ struct _reent #define _REENT_ASCTIME_BUF(ptr) ((ptr)->_asctime_buf) #define _REENT_TM(ptr) ((ptr)->_localtime_buf) #define _REENT_EMERGENCY(ptr) ((ptr)->_emergency) +#define _REENT_STRTOK_LAST(ptr) ((ptr)->_misc->_strtok_last) +#define _REENT_MBLEN_STATE(ptr) ((ptr)->_misc->_mblen_state) +#define _REENT_MBTOWC_STATE(ptr)((ptr)->_misc->_mbtowc_state) +#define _REENT_WCTOMB_STATE(ptr)((ptr)->_misc->_wctomb_state) #else /* !_REENT_SMALL */ @@ -396,12 +451,15 @@ struct _reent struct { unsigned int _unused_rand; - char * _unused_strtok_last; + char * _strtok_last; char _asctime_buf[26]; struct __tm _localtime_buf; int _gamma_signgam; __extension__ unsigned long long _rand_next; struct _rand48 _r48; + int _mblen_state; + int _mbtowc_state; + int _wctomb_state; } _reent; /* Two next two fields were once used by malloc. They are no longer used. They are used to preserve the space used before so as to @@ -433,13 +491,55 @@ struct _reent 0, _NULL, _NULL, 0, _NULL, _NULL, 0, _NULL, { {0, _NULL, "", \ { 0,0,0,0,0,0,0,0}, 0, 1, \ {{_RAND48_SEED_0, _RAND48_SEED_1, _RAND48_SEED_2}, \ - {_RAND48_MULT_0, _RAND48_MULT_1, _RAND48_MULT_2}, _RAND48_ADD}} } } + {_RAND48_MULT_0, _RAND48_MULT_1, _RAND48_MULT_2}, _RAND48_ADD}, \ + 0, 0, 0} } } + +#define _REENT_INIT_PTR(var) \ + { int i; \ + char *tmp_ptr; \ + var->_errno = 0; \ + var->_stdin = &var->__sf[0]; \ + var->_stdout = &var->__sf[1]; \ + var->_stderr = &var->__sf[2]; \ + var->_inc = 0; \ + for (i = 0; i < _REENT_EMERGENCY_SIZE; ++i) \ + var->_emergency[i] = 0; \ + var->_current_category = 0; \ + var->_current_locale = "C"; \ + var->__sdidinit = 0; \ + var->__cleanup = _NULL; \ + var->_result = _NULL; \ + var->_result_k = 0; \ + var->_p5s = _NULL; \ + var->_freelist = _NULL; \ + var->_cvtlen = 0; \ + var->_cvtbuf = _NULL; \ + var->_new._reent._unused_rand = 0; \ + var->_new._reent._strtok_last = _NULL; \ + var->_new._reent._asctime_buf[0] = 0; \ + tmp_ptr = (char *)&var->_new._reent._localtime_buf; \ + for (i = 0; i < sizeof(struct __tm); ++i) \ + tmp_ptr[i] = 0; \ + var->_new._reent._gamma_signgam = 0; \ + var->_new._reent._rand_next = 1; \ + var->_new._reent._r48._seed[0] = _RAND48_SEED_0; \ + var->_new._reent._r48._seed[1] = _RAND48_SEED_1; \ + var->_new._reent._r48._seed[2] = _RAND48_SEED_2; \ + var->_new._reent._r48._mult[0] = _RAND48_MULT_0; \ + var->_new._reent._r48._mult[1] = _RAND48_MULT_1; \ + var->_new._reent._r48._mult[2] = _RAND48_MULT_2; \ + var->_new._reent._r48._add = _RAND48_ADD; \ + var->_new._reent._mblen_state = 0; \ + var->_new._reent._mbtowc_state = 0; \ + var->_new._reent._wctomb_state = 0; \ + } #define _REENT_CHECK_RAND48(ptr) /* nothing */ #define _REENT_CHECK_MP(ptr) /* nothing */ #define _REENT_CHECK_TM(ptr) /* nothing */ #define _REENT_CHECK_ASCTIME_BUF(ptr) /* nothing */ #define _REENT_CHECK_EMERGENCY(ptr) /* nothing */ +#define _REENT_CHECK_MISC(ptr) /* nothing */ #define _REENT_SIGNGAM(ptr) ((ptr)->_new._reent._gamma_signgam) #define _REENT_RAND_NEXT(ptr) ((ptr)->_new._reent._rand_next) @@ -453,6 +553,10 @@ struct _reent #define _REENT_ASCTIME_BUF(ptr) (&(ptr)->_new._reent._asctime_buf) #define _REENT_TM(ptr) (&(ptr)->_new._reent._localtime_buf) #define _REENT_EMERGENCY(ptr) ((ptr)->_emergency) +#define _REENT_STRTOK_LAST(ptr) ((ptr)->_new._reent._strtok_last) +#define _REENT_MBLEN_STATE(ptr) ((ptr)->_new._reent._mblen_state) +#define _REENT_MBTOWC_STATE(ptr)((ptr)->_new._reent._mbtowc_state) +#define _REENT_WCTOMB_STATE(ptr)((ptr)->_new._reent._wctomb_state) #endif /* !_REENT_SMALL */ @@ -475,7 +579,7 @@ void _reclaim_reent _PARAMS ((struct _reent *)); #ifndef _REENT_ONLY #define _REENT _impure_ptr -#endif +#endif /* !_REENT_ONLY */ #ifdef __cplusplus } diff --git a/newlib/libc/stdlib/mblen.c b/newlib/libc/stdlib/mblen.c index d9b774e45..c85a6a734 100644 --- a/newlib/libc/stdlib/mblen.c +++ b/newlib/libc/stdlib/mblen.c @@ -51,9 +51,9 @@ _DEFUN (mblen, (s, n), size_t n) { #ifdef MB_CAPABLE - static int state; + _REENT_CHECK_MISC(_REENT); - return _mbtowc_r (_REENT, NULL, s, n, &state); + return _mbtowc_r (_REENT, NULL, s, n, &(_REENT_MBLEN_STATE(_REENT))); #else /* not MB_CAPABLE */ if (s == NULL || *s == '\0') return 0; diff --git a/newlib/libc/stdlib/mbtowc.c b/newlib/libc/stdlib/mbtowc.c index 5e34fe366..0d16f0d9d 100644 --- a/newlib/libc/stdlib/mbtowc.c +++ b/newlib/libc/stdlib/mbtowc.c @@ -60,9 +60,9 @@ _DEFUN (mbtowc, (pwc, s, n), size_t n) { #ifdef MB_CAPABLE - static int state; + _REENT_CHECK_MISC(_REENT); - return _mbtowc_r (_REENT, pwc, s, n, &state); + return _mbtowc_r (_REENT, pwc, s, n, &(_REENT_MBTOWC_STATE(_REENT))); #else /* not MB_CAPABLE */ if (s == NULL) return 0; diff --git a/newlib/libc/stdlib/wctomb.c b/newlib/libc/stdlib/wctomb.c index a6812508f..5cff10fff 100644 --- a/newlib/libc/stdlib/wctomb.c +++ b/newlib/libc/stdlib/wctomb.c @@ -54,9 +54,9 @@ _DEFUN (wctomb, (s, wchar), wchar_t wchar) { #ifdef MB_CAPABLE - static int state; + _REENT_CHECK_MISC(_REENT); - return _wctomb_r (_REENT, s, wchar, &state); + return _wctomb_r (_REENT, s, wchar, &(_REENT_WCTOMB_STATE(_REENT))); #else /* not MB_CAPABLE */ if (s == NULL) return 0; diff --git a/newlib/libc/string/strtok.c b/newlib/libc/string/strtok.c index 17228d223..292c16743 100644 --- a/newlib/libc/string/strtok.c +++ b/newlib/libc/string/strtok.c @@ -73,7 +73,7 @@ _DEFUN (strtok, (s, delim), register char *s _AND register const char *delim) { - static char *last; - return strtok_r (s, delim, &last); + _REENT_CHECK_MISC(_REENT); + return strtok_r (s, delim, &(_REENT_STRTOK_LAST(_REENT))); } #endif