From ae13b2e562f462b6c2f6c72802bed9204d4cffa1 Mon Sep 17 00:00:00 2001 From: John Marino Date: Thu, 31 Jan 2013 16:58:59 +0100 Subject: [PATCH] libstdc++47: Fix iostream bug 2478 c++ iostreams were segfaulting -- apparently _M_table isn't defined in all cases. Fix inspired from FreeBSD configuration files. https://bugs.dragonflybsd.org/issues/2478 --- .../config/os/bsd/dragonfly/ctype_base.h | 2 +- .../config/os/bsd/dragonfly/ctype_inline.h | 48 +++++++++++++++++--- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/contrib/gcc-4.7/libstdc++-v3/config/os/bsd/dragonfly/ctype_base.h b/contrib/gcc-4.7/libstdc++-v3/config/os/bsd/dragonfly/ctype_base.h index 1eeb193..bcbf553 100644 --- a/contrib/gcc-4.7/libstdc++-v3/config/os/bsd/dragonfly/ctype_base.h +++ b/contrib/gcc-4.7/libstdc++-v3/config/os/bsd/dragonfly/ctype_base.h @@ -38,7 +38,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct ctype_base { // Non-standard typedefs. - typedef const unsigned char* __to_type; + typedef const int* __to_type; // NB: Offsets into ctype::_M_table force a particular size // on the mask type. Because of this, we don't use an enum. diff --git a/contrib/gcc-4.7/libstdc++-v3/config/os/bsd/dragonfly/ctype_inline.h b/contrib/gcc-4.7/libstdc++-v3/config/os/bsd/dragonfly/ctype_inline.h index 96257c8..c6e4ffe 100644 --- a/contrib/gcc-4.7/libstdc++-v3/config/os/bsd/dragonfly/ctype_inline.h +++ b/contrib/gcc-4.7/libstdc++-v3/config/os/bsd/dragonfly/ctype_inline.h @@ -42,14 +42,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool ctype:: is(mask __m, char __c) const - { return _M_table[(unsigned char)(__c)] & __m; } + { + if (_M_table) + return _M_table[static_cast(__c)] & __m; + else + return __libc_ctype_ [__c + 1] & __m; + } const char* ctype:: is(const char* __low, const char* __high, mask* __vec) const { - while (__low < __high) - *__vec++ = _M_table[*__low++]; + if (_M_table) + while (__low < __high) + *__vec++ = _M_table[static_cast(*__low++)]; + else + for (;__low < __high; ++__vec, ++__low) + { + mask __m = 0; + if (this->is(upper, *__low)) __m |= upper; + if (this->is(lower, *__low)) __m |= lower; + if (this->is(alpha, *__low)) __m |= alpha; + if (this->is(digit, *__low)) __m |= digit; + if (this->is(xdigit, *__low)) __m |= xdigit; + if (this->is(space, *__low)) __m |= space; + if (this->is(print, *__low)) __m |= print; + if (this->is(graph, *__low)) __m |= graph; + if (this->is(cntrl, *__low)) __m |= cntrl; + if (this->is(punct, *__low)) __m |= punct; + // Do not include explicit line for alnum mask since it is a + // pure composite of masks on DragonFly. + *__vec = __m; + } return __high; } @@ -57,8 +81,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ctype:: scan_is(mask __m, const char* __low, const char* __high) const { - while (__low < __high && !this->is(__m, *__low)) - ++__low; + if (_M_table) + while (__low < __high + && !(_M_table[static_cast(*__low)] & __m)) + ++__low; + else + while (__low < __high && !this->is(__m, *__low)) + ++__low; return __low; } @@ -66,8 +95,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ctype:: scan_not(mask __m, const char* __low, const char* __high) const { - while (__low < __high && this->is(__m, *__low) != 0) - ++__low; + if (_M_table) + while (__low < __high + && (_M_table[static_cast(*__low)] & __m) != 0) + ++__low; + else + while (__low < __high && this->is(__m, *__low) != 0) + ++__low; return __low; } -- 1.7.7.2