Skip to content

Commit 817dcd3

Browse files
committed
Get Cygwin linking again
User-readable type name printing for GCC [SVN r19236]
1 parent 25bfd3c commit 817dcd3

File tree

7 files changed

+148
-27
lines changed

7 files changed

+148
-27
lines changed

include/boost/python/detail/config.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
# define BOOST_PYTHON_NO_TEMPLATE_EXPORT
7272
#endif
7373

74-
#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32)
74+
#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32) || defined(__CYGWIN__)
7575
# if defined(BOOST_PYTHON_SOURCE)
7676
# define BOOST_PYTHON_DECL __declspec(dllexport)
7777
# define BOOST_PYTHON_BUILD_DLL

include/boost/python/scope.hpp

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,15 @@
1313

1414
namespace boost { namespace python {
1515

16-
class BOOST_PYTHON_DECL scope
17-
: public object
16+
namespace detail
17+
{
18+
// Making this a namespace-scope variable to avoid Cygwin issues.
19+
// Use a PyObject* to avoid problems with static destruction after Py_Finalize
20+
extern BOOST_PYTHON_DECL PyObject* current_scope;
21+
}
22+
23+
class scope
24+
: public object
1825
{
1926
public:
2027
inline scope(scope const&);
@@ -27,32 +34,27 @@ class BOOST_PYTHON_DECL scope
2734

2835
private: // unimplemented functions
2936
void operator=(scope const&);
30-
31-
private: // static members
32-
33-
// Use a PyObject* to avoid problems with static destruction after Py_Finalize
34-
static PyObject* current_scope;
3537
};
3638

3739
inline scope::scope(object const& new_scope)
3840
: object(new_scope)
39-
, m_previous_scope(current_scope)
41+
, m_previous_scope(detail::current_scope)
4042
{
41-
current_scope = python::incref(new_scope.ptr());
43+
detail::current_scope = python::incref(new_scope.ptr());
4244
}
4345

4446
inline scope::scope()
4547
: object(detail::borrowed_reference(
46-
current_scope ? current_scope : Py_None
48+
detail::current_scope ? detail::current_scope : Py_None
4749
))
48-
, m_previous_scope(python::xincref(current_scope))
50+
, m_previous_scope(python::xincref(detail::current_scope))
4951
{
5052
}
5153

5254
inline scope::~scope()
5355
{
54-
python::xdecref(current_scope);
55-
current_scope = m_previous_scope;
56+
python::xdecref(detail::current_scope);
57+
detail::current_scope = m_previous_scope;
5658
}
5759

5860
namespace converter
@@ -67,9 +69,9 @@ namespace converter
6769
// Placing this after the specialization above suppresses a CWPro8.3 bug
6870
inline scope::scope(scope const& new_scope)
6971
: object(new_scope)
70-
, m_previous_scope(current_scope)
72+
, m_previous_scope(detail::current_scope)
7173
{
72-
current_scope = python::incref(new_scope.ptr());
74+
detail::current_scope = python::incref(new_scope.ptr());
7375
}
7476

7577
}} // namespace boost::python

include/boost/python/type_id.hpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515
# include <boost/static_assert.hpp>
1616
# include <boost/type_traits/same_traits.hpp>
1717

18+
# ifndef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
19+
# if defined(__GNUC__) \
20+
&& ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
21+
# define BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
22+
# endif
23+
# endif
24+
1825
namespace boost { namespace python {
1926

2027
// for this compiler at least, cross-shared-library type_info
@@ -87,7 +94,7 @@ BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long long)
8794
# undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID
8895
# endif
8996

90-
97+
//
9198
inline type_info::type_info(std::type_info const& id)
9299
: m_base_type(
93100
# ifdef BOOST_PYTHON_TYPE_ID_NAME
@@ -117,12 +124,26 @@ inline bool type_info::operator==(type_info const& rhs) const
117124
# endif
118125
}
119126

127+
# ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
128+
namespace detail
129+
{
130+
BOOST_PYTHON_DECL char const* gcc_demangle(char const*);
131+
}
132+
# endif
133+
120134
inline char const* type_info::name() const
121135
{
122-
# ifdef BOOST_PYTHON_TYPE_ID_NAME
123-
return m_base_type;
136+
char const* raw_name
137+
= m_base_type
138+
# ifndef BOOST_PYTHON_TYPE_ID_NAME
139+
->name()
140+
# endif
141+
;
142+
143+
# ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
144+
return detail::gcc_demangle(raw_name);
124145
# else
125-
return m_base_type->name();
146+
return raw_name;
126147
# endif
127148
}
128149

src/converter/from_python.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
#include <boost/python/detail/raw_pyobject.hpp>
1515
#include <boost/python/cast.hpp>
1616

17-
#include <boost/lexical_cast.hpp>
18-
1917
#include <vector>
2018
#include <algorithm>
2119

src/converter/registry.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
#include <boost/python/converter/registrations.hpp>
88
#include <boost/python/converter/builtin_converters.hpp>
99

10-
#include <boost/lexical_cast.hpp>
11-
1210
#include <set>
1311
#include <stdexcept>
1412

@@ -25,7 +23,7 @@ BOOST_PYTHON_DECL PyTypeObject* registration::get_class_object() const
2523
::PyErr_Format(
2624
PyExc_TypeError
2725
, const_cast<char*>("No Python class registered for C++ class %s")
28-
, target_type.name());
26+
, this->target_type.name());
2927

3028
throw_error_already_set();
3129
}
@@ -40,7 +38,9 @@ BOOST_PYTHON_DECL PyObject* registration::to_python(void const volatile* source)
4038
handle<> msg(
4139
::PyString_FromFormat(
4240
"No to_python (by-value) converter found for C++ type: %s"
43-
, this->target_type.name()));
41+
, this->target_type.name()
42+
)
43+
);
4444

4545
PyErr_SetObject(PyExc_TypeError, msg.get());
4646

src/converter/type_id.cpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,111 @@
66

77
#include <boost/python/type_id.hpp>
88
#include <boost/python/detail/decorated_type_id.hpp>
9+
#include <utility>
10+
#include <vector>
11+
#include <algorithm>
12+
#include <memory>
13+
#include <cstdlib>
14+
#include <cstring>
15+
916
#if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT
1017
# include <ostream>
1118
#else
1219
# include <ostream.h>
1320
#endif
1421

22+
23+
# ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
24+
# if defined(__GNUC__) && __GNUC__ >= 3
25+
# include <cxxabi.h>
26+
# endif
27+
#include <iostream>
28+
# endif
29+
1530
namespace boost { namespace python {
1631

32+
# ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
33+
# ifdef __GNUC__
34+
# if __GNUC__ < 3
35+
36+
namespace cxxabi = :: ;
37+
# else
38+
namespace cxxabi = ::abi; // GCC 3.1 and later
39+
# endif
40+
# endif
41+
42+
namespace
43+
{
44+
struct compare_first_cstring
45+
{
46+
template <class T>
47+
bool operator()(T const& x, T const& y)
48+
{
49+
return std::strcmp(x.first,y.first) < 0;
50+
}
51+
};
52+
53+
struct free_mem
54+
{
55+
free_mem(char*p)
56+
: p(p) {}
57+
58+
~free_mem()
59+
{
60+
std::free(p);
61+
}
62+
char* p;
63+
};
64+
}
65+
66+
namespace detail
67+
{
68+
BOOST_PYTHON_DECL char const* gcc_demangle(char const* mangled)
69+
{
70+
typedef std::vector<
71+
std::pair<char const*, char const*>
72+
> mangling_map;
73+
74+
static mangling_map demangler;
75+
mangling_map::iterator p
76+
= std::lower_bound(
77+
demangler.begin(), demangler.end()
78+
, std::make_pair(mangled, (char const*)0)
79+
, compare_first_cstring());
80+
81+
if (p == demangler.end() || strcmp(p->first, mangled))
82+
{
83+
int status;
84+
free_mem keeper(
85+
cxxabi::__cxa_demangle(mangled, 0, 0, &status)
86+
);
87+
88+
assert(status != -3); // invalid argument error
89+
90+
if (status == -1)
91+
{
92+
throw std::bad_alloc();
93+
}
94+
else
95+
{
96+
char const* demangled
97+
= status == -2
98+
// Invalid mangled name. Best we can do is to
99+
// return it intact.
100+
? mangled
101+
: keeper.p;
102+
103+
std::cout << "demangled name: " << mangled << " as " << demangled << std::endl;
104+
p = demangler.insert(p, std::make_pair(mangled, demangled));
105+
keeper.p = 0;
106+
}
107+
}
108+
109+
return p->second;
110+
}
111+
}
112+
# endif
113+
17114
BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_info const& x)
18115
{
19116
return os << x.name();

src/module.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ BOOST_PYTHON_DECL void init_module(char const* name, void(*init_function)())
4747

4848
namespace boost { namespace python {
4949

50-
BOOST_PYTHON_DECL PyObject* scope::current_scope = 0;
50+
namespace detail
51+
{
52+
BOOST_PYTHON_DECL PyObject* current_scope = 0;
53+
}
5154

5255
}}

0 commit comments

Comments
 (0)