Permalink
Browse files

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
  • Loading branch information...
jrmarino committed Jan 31, 2013
1 parent 502584f commit ae13b2e562f462b6c2f6c72802bed9204d4cffa1
@@ -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<char>::_M_table force a particular size
// on the mask type. Because of this, we don't use an enum.
@@ -42,32 +42,66 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
ctype<char>::
is(mask __m, char __c) const
- { return _M_table[(unsigned char)(__c)] & __m; }
+ {
+ if (_M_table)
+ return _M_table[static_cast<unsigned char>(__c)] & __m;
+ else
+ return __libc_ctype_ [__c + 1] & __m;
+ }
const char*
ctype<char>::
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<unsigned char>(*__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;
}
const char*
ctype<char>::
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<unsigned char>(*__low)] & __m))
+ ++__low;
+ else
+ while (__low < __high && !this->is(__m, *__low))
+ ++__low;
return __low;
}
const char*
ctype<char>::
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<unsigned char>(*__low)] & __m) != 0)
+ ++__low;
+ else
+ while (__low < __high && this->is(__m, *__low) != 0)
+ ++__low;
return __low;
}

0 comments on commit ae13b2e

Please sign in to comment.