summaryrefslogtreecommitdiff
path: root/src/cppunit/TypeInfoHelper.cpp
blob: 8c9717864913430ef4dfefd6d0bd312b35f8dcaf (plain)
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
59
60
61
62
#include <cppunit/Portability.h>
#include <cppunit/extensions/TypeInfoHelper.h>

#if CPPUNIT_HAVE_RTTI

#include <string>

#if CPPUNIT_HAVE_GCC_ABI_DEMANGLE
#include <malloc.h>
#include <cxxabi.h>
#endif


CPPUNIT_NS_BEGIN


std::string 
TypeInfoHelper::getClassName( const std::type_info &info )
{
#if defined(CPPUNIT_HAVE_GCC_ABI_DEMANGLE)  &&  CPPUNIT_HAVE_GCC_ABI_DEMANGLE

  int status = 0;
  char* c_name = 0;

  c_name = abi::__cxa_demangle( info.name(), 0, 0, &status );
  
  std::string name;
  if(c_name)
  {
      name = std::string( c_name );
      free( c_name );  
  }
  else
  {
      name = std::string( info.name() );
  }

#else   // CPPUNIT_HAVE_GCC_ABI_DEMANGLE

  static std::string classPrefix( "class " );
  std::string name( info.name() );

  // Work around gcc 3.0 bug: strip number before type name.
  unsigned int firstNotDigitIndex = 0;
  while ( firstNotDigitIndex < name.length()  &&
          name[firstNotDigitIndex] >= '0'  &&
          name[firstNotDigitIndex] <= '9' )
    ++firstNotDigitIndex;
  name = name.substr( firstNotDigitIndex );

  if ( name.substr( 0, classPrefix.length() ) == classPrefix )
    return name.substr( classPrefix.length() );

#endif  // CPPUNIT_HAVE_GCC_ABI_DEMANGLE

  return name;
}


CPPUNIT_NS_END

#endif // CPPUNIT_HAVE_RTTI