diff --git a/dtool/pptempl/Global.pp b/dtool/pptempl/Global.pp index 2276a7b640..176be2f960 100644 --- a/dtool/pptempl/Global.pp +++ b/dtool/pptempl/Global.pp @@ -621,7 +621,7 @@ #defer get_igatescan \ $[if $[and $[run_interrogate],$[IGATESCAN]], \ $[if $[eq $[IGATESCAN], all], \ - $[filter-out %.I %.T %.lxx %.yxx %.N %_src.cxx,$[get_sources]], \ + $[filter-out %.I %.T %.lxx %.yxx %.N %_src.cxx,$[get_sources]] $[filter %_ext.I,$[get_sources]], \ $[IGATESCAN]]] // This variable returns the name of the interrogate database file diff --git a/dtool/src/dtoolbase/dtoolbase.h b/dtool/src/dtoolbase/dtoolbase.h index b6fe152dba..22d3e8da0d 100644 --- a/dtool/src/dtoolbase/dtoolbase.h +++ b/dtool/src/dtoolbase/dtoolbase.h @@ -326,14 +326,11 @@ #define BLOCKING __blocking #define MAKE_SEQ(seq_name, num_name, element_name) __make_seq(seq_name, num_name, element_name) #undef USE_STL_ALLOCATOR /* Don't try to parse these template classes in interrogate. */ -#define EXTENSION(x) __extension x; +#define EXTENSION(x) __extension x #define EXTEND __extension #define EXT_FUNC(func) ::func() #define EXT_FUNC_ARGS(func, ...) ::func(__VA_ARGS__) -#define EXT_METHOD(cl, m) cl::m() -#define EXT_METHOD_ARGS(cl, m, ...) cl::m(__VA_ARGS__) -#define EXT_CONST_METHOD(cl, m) cl::m() const -#define EXT_CONST_METHOD_ARGS(cl, m, ...) cl::m(__VA_ARGS__) const +#define CALL_EXT_FUNC(func, ...) ::func (__VA_ARGS__) #else #define BEGIN_PUBLISH #define END_PUBLISH @@ -341,13 +338,11 @@ #define MAKE_SEQ(seq_name, num_name, element_name) #define EXTENSION(x) #define EXTEND -/* If you change this, don't forget to also change it in interrogate itself. */ -#define EXT_FUNC(cl, m) _ext__ ## m () -#define EXT_FUNC_ARGS(cl, m, ...) _ext__ ## m (__VA_ARGS__) -#define EXT_METHOD(cl, m) _ext_ ## cl ## _ ## m (cl * _ext_this) -#define EXT_METHOD_ARGS(cl, m, ...) _ext_ ## cl ## _ ## m (cl * _ext_this, __VA_ARGS__) -#define EXT_CONST_METHOD(cl, m) _ext_ ## cl ## _ ## m (const cl * _ext_this) -#define EXT_CONST_METHOD_ARGS(cl, m, ...) _ext_ ## cl ## _ ## m (const cl * _ext_this, __VA_ARGS__) +/* If you change these, don't forget to also change it in interrogate itself. */ +#define _EXT_FUNC(func) _ext__ ## func +#define EXT_FUNC(func) _EXT_FUNC(func) () +#define EXT_FUNC_ARGS(func, ...) _EXT_FUNC(func) (__VA_ARGS__) +#define CALL_EXT_FUNC(func, ...) _EXT_METHOD(cl, m) (__VA_ARGS__) #endif #ifdef __cplusplus diff --git a/dtool/src/dtoolbase/dtoolbase_cc.h b/dtool/src/dtoolbase/dtoolbase_cc.h index ac8408381b..56eccb4c10 100644 --- a/dtool/src/dtoolbase/dtoolbase_cc.h +++ b/dtool/src/dtoolbase/dtoolbase_cc.h @@ -215,5 +215,32 @@ private: #endif // USE_TAU +#ifdef CPPPARSER +#define EXT_METHOD(cl, m) cl::m() +#define EXT_METHOD_ARGS(cl, m, ...) cl::m(__VA_ARGS__) +#define EXT_CONST_METHOD(cl, m) cl::m() const +#define EXT_CONST_METHOD_ARGS(cl, m, ...) cl::m(__VA_ARGS__) const +#define EXT_NESTED_METHOD(cl1, cl2, m) cl1::cl2::m() +#define EXT_NESTED_METHOD_ARGS(cl1, cl2, m, ...) cl1::cl2::m(__VA_ARGS__) +#define EXT_NESTED_CONST_METHOD(cl1, cl2, m) cl1::cl2::m() const +#define EXT_NESTED_CONST_METHOD_ARGS(cl1, cl2, m, ...) cl1::cl2::m(__VA_ARGS__) const +#define CALL_EXT_METHOD(cl, m, obj, ...) (obj)-> m(__VA_ARGS__) +#else +/* If you change these, don't forget to also change it in interrogate itself. */ +#define __EXT_METHOD(cl, m) _ext_ ## cl ## _ ## m +#define _EXT_METHOD(cl, m) __EXT_METHOD(cl, m) +#define __EXT_NEST(cl1, cl2) cl1 ## __ ## cl2 +#define _EXT_NEST(cl1, cl2) __EXT_NEST(cl1, cl2) +#define EXT_METHOD(cl, m) _EXT_METHOD(cl, m) (cl * _ext_this) +#define EXT_METHOD_ARGS(cl, m, ...) _EXT_METHOD(cl, m) (cl * _ext_this, __VA_ARGS__) +#define EXT_CONST_METHOD(cl, m) _EXT_METHOD(cl, m) (const cl * _ext_this) +#define EXT_CONST_METHOD_ARGS(cl, m, ...) _EXT_METHOD(cl, m) (const cl * _ext_this, __VA_ARGS__) +#define EXT_NESTED_METHOD(cl1, cl2, m) _EXT_METHOD(_EXT_NEST(cl1, cl2), m) (cl1::cl2 * _ext_this) +#define EXT_NESTED_METHOD_ARGS(cl1, cl2, m, ...) _EXT_METHOD(_EXT_NEST(cl1, cl2), m) (cl1::cl2 * _ext_this, __VA_ARGS__) +#define EXT_NESTED_CONST_METHOD(cl1, cl2, m) _EXT_METHOD(_EXT_NEST(cl1, cl2), m) (const cl1::cl2 * _ext_this) +#define EXT_NESTED_CONST_METHOD_ARGS(cl1, cl2, m, ...) _EXT_METHOD(_EXT_NEST(cl1, cl2), m) (const cl1::cl2 * _ext_this, __VA_ARGS__) +#define CALL_EXT_METHOD(cl, m, ...) _EXT_METHOD(cl, m) (__VA_ARGS__) +#endif + #endif // __cplusplus #endif diff --git a/dtool/src/interrogate/functionRemap.cxx b/dtool/src/interrogate/functionRemap.cxx index c58c80db1f..09e7c225c4 100644 --- a/dtool/src/interrogate/functionRemap.cxx +++ b/dtool/src/interrogate/functionRemap.cxx @@ -396,8 +396,16 @@ get_call_str(const string &container, const vector_string &pexprs) const { // function has to match the EXT_IMPL definition in dtoolbase.h. if (_extension) { if (_cpptype != NULL) { - call << "_ext_" << _cpptype->get_local_name() + // Fix nested classes by replacing :: with __ + char* nested_name = strdup(_cpptype->get_local_name(&parser).c_str()); + for (int i = 0; i < strlen(nested_name); ++i) { + if (nested_name[i] == ':') { + nested_name[i] = '_'; + } + } + call << "_ext_" << nested_name << "_" << _cppfunc->get_local_name() << "("; + delete[] nested_name; } else { call << "_ext__" << _cppfunc->get_local_name() << "("; } diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 7cd2f3acb4..e0286e2d6a 100755 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -1580,7 +1580,10 @@ write_module_class(ostream &out, Object *obj) { out << " return NULL;\n"; out << " };\n"; out << " ostringstream os;\n"; - if (need_repr == 2) { + if (need_repr == 3) { + out << " _ext_" << ClassName << "_python_repr(local_this, os, \"" + << classNameFromCppName(ClassName) << "\");\n"; + } else if (need_repr == 2) { out << " local_this->output(os);\n"; } else { out << " local_this->python_repr(os, \"" @@ -3651,6 +3654,9 @@ NeedsAStrFunction(const InterrogateType &itype_class) { // Returns 1 if the class defines python_repr(ostream, string). // // Returns 2 if the class defines output(ostream). +// +// Returns 3 if the class defines an extension +// function for python_repr(ostream, string). //////////////////////////////////////////////////////////////////// int InterfaceMakerPythonNative:: NeedsAReprFunction(const InterrogateType &itype_class) { @@ -3681,7 +3687,11 @@ NeedsAReprFunction(const InterrogateType &itype_class) { if (TypeManager::is_string(inst1->_type) || TypeManager::is_char_pointer(inst1->_type)) { // python_repr(ostream, string) - return 1; + if ((cppinst->_storage_class & CPPInstance::SC_extension) != 0) { + return 3; + } else { + return 1; + } } } }