summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/LINKS1
-rw-r--r--src/TypeInfo.hpp28
-rw-r--r--tests/utils/GNUmakefile6
-rwxr-xr-xtests/utils/exec_test21
-rw-r--r--tests/utils/test1.MUST1
-rw-r--r--tests/utils/test2.MUST1
-rw-r--r--tests/utils/test2.cpp27
7 files changed, 77 insertions, 8 deletions
diff --git a/docs/LINKS b/docs/LINKS
index 7a48586..dd5f925 100644
--- a/docs/LINKS
+++ b/docs/LINKS
@@ -51,4 +51,5 @@ http://www.codeproject.com/Articles/5629/Tiny-Template-Library-implementing-type
http://www.drdobbs.com/cpp/extracting-function-parameter-and-return/240000586?pgno=2
http://sourceforge.net/projects/toast/: portable type_info.name()
http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html
+http://tombarta.wordpress.com/category/gcc/
?? name of module or typeid of derived class in module?
diff --git a/src/TypeInfo.hpp b/src/TypeInfo.hpp
index 4133ec3..dc718ff 100644
--- a/src/TypeInfo.hpp
+++ b/src/TypeInfo.hpp
@@ -4,30 +4,44 @@
#include <typeinfo>
#include <string>
#include <stdexcept>
+#include <cstdlib>
-#ifdef __GNUG__
+#if defined( __GNUG__ ) && defined( __GLIBCXX__ )
#include <cxxabi.h>
std::string demangle( const std::type_info &info )
{
enum { BUFLEN = 200 };
- char buf[BUFLEN];
+ char *buf;
std::size_t buflen = BUFLEN;
int status;
+ char *res;
- __cxxabiv1::__cxa_demangle( info.name( ), buf, &buflen, &status );
- if( status != 0 ) {
+ // pass a malloced buffer (required by cxa_demangle)
+ buf = (char *)malloc( BUFLEN );
+
+ // res may point to buf or be realloced depending on whether the
+ // demangling had enough space or not
+ res = __cxxabiv1::__cxa_demangle( info.name( ), buf, &buflen, &status );
+
+ // throw exception if this goes wrong, because we don't want to have
+ // have code reacting on failed demangling or wrong type information!
+ if( status != 0 || res == NULL ) {
throw std::runtime_error( "__cxa_demangle failed!" );
}
- return buf;
+ // construct string on stack and return it, free original buffer
+ std::string s( res );
+ free( res );
+
+ return s;
}
#else
#error "C++ demangling not ported!"
-#endif
+#endif // defined( __GNUG__ ) && defined( __GLIBCXX__ )
-#endif
+#endif // __TYPEINFO_H
diff --git a/tests/utils/GNUmakefile b/tests/utils/GNUmakefile
index e3913bd..ce6df00 100644
--- a/tests/utils/GNUmakefile
+++ b/tests/utils/GNUmakefile
@@ -10,7 +10,8 @@ INCLUDE_LDFLAGS =
INCLUDE_LIBS =
TEST_CPP_BINS = \
- test1$(EXE)
+ test1$(EXE) \
+ test2$(EXE)
OBJS =
@@ -19,7 +20,10 @@ OBJS =
local_all:
local_clean:
+ -@rm -f *.RES *.DIFF
local_distclean:
local_test:
+ @./exec_test test1 "TypeList and TypeTraits"
+ @./exec_test test2 "TypeInfo C++ demangle"
diff --git a/tests/utils/exec_test b/tests/utils/exec_test
new file mode 100755
index 0000000..b49999b
--- /dev/null
+++ b/tests/utils/exec_test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+BINARY=$1
+TITLE=$2
+PLATFORM=$3
+LINUX_DIST=$4
+LINUX_REV=$5
+
+if test "x${PLATFORM}" = "xLINUX"; then
+SPECIAL="${PLATFORM}_${LINUX_DIST}_${LINUX_REV}"
+else
+SPECIAL="${PLATFORM}"
+fi
+
+printf "$BINARY: $TITLE .. "
+./$BINARY | sed 's/\(time: .* ms\)//g' >$BINARY.RES 2>&1
+if test -f $BINARY.MUST.$SPECIAL; then
+ diff $BINARY.MUST.$SPECIAL $BINARY.RES > $BINARY.DIFF && printf "OK\n" || printf "ERROR\n"
+else
+ diff $BINARY.MUST $BINARY.RES > $BINARY.DIFF && printf "OK\n" || printf "ERROR\n"
+fi
diff --git a/tests/utils/test1.MUST b/tests/utils/test1.MUST
new file mode 100644
index 0000000..da79897
--- /dev/null
+++ b/tests/utils/test1.MUST
@@ -0,0 +1 @@
+len: 3
diff --git a/tests/utils/test2.MUST b/tests/utils/test2.MUST
new file mode 100644
index 0000000..ce03fef
--- /dev/null
+++ b/tests/utils/test2.MUST
@@ -0,0 +1 @@
+std::map<std::string, Space::Derived, std::less<std::string>, std::allocator<std::pair<std::string const, Space::Derived> > >
diff --git a/tests/utils/test2.cpp b/tests/utils/test2.cpp
new file mode 100644
index 0000000..ffd54a4
--- /dev/null
+++ b/tests/utils/test2.cpp
@@ -0,0 +1,27 @@
+#include "TypeInfo.hpp"
+
+#include <map>
+#include <iostream>
+
+namespace Space {
+
+class Base {
+};
+
+class Derived : public Base {
+};
+
+}
+
+using namespace Space;
+typedef std::map<std::string, Derived> mapType;
+
+int main( void )
+{
+ mapType m;
+
+ std::cout << demangle( typeid( m ) ) << std::endl;
+
+ return 0;
+}
+