mirror of
https://github.com/panda3d/panda3d.git
synced 2026-03-20 19:10:50 -05:00
remove dead code
This commit is contained in:
@@ -5,11 +5,8 @@
|
||||
#begin bin_target
|
||||
#define TARGET interrogate
|
||||
|
||||
// While I'm working on this, I'll temporarily take out the composite
|
||||
// build.
|
||||
// #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
#define SOURCES \
|
||||
classBuilder.h classBuilderPythonObj.h \
|
||||
functionRemap.h \
|
||||
functionWriter.h \
|
||||
functionWriterPtrFromPython.h functionWriterPtrToPython.h \
|
||||
@@ -28,12 +25,9 @@
|
||||
parameterRemapReferenceToConcrete.h \
|
||||
parameterRemapReferenceToPointer.h parameterRemapThis.h \
|
||||
parameterRemapToString.h parameterRemapUnchanged.h \
|
||||
typeManager.h wrapperBuilder.h wrapperBuilderC.h \
|
||||
wrapperBuilderPython.h wrapperBuilderPythonObj.h
|
||||
typeManager.h
|
||||
|
||||
// #define INCLUDED_SOURCES \
|
||||
#define SOURCES $[SOURCES] \
|
||||
classBuilder.cxx classBuilderPythonObj.cxx \
|
||||
#define INCLUDED_SOURCES \
|
||||
functionRemap.cxx \
|
||||
functionWriter.cxx \
|
||||
functionWriterPtrFromPython.cxx functionWriterPtrToPython.cxx \
|
||||
@@ -52,8 +46,7 @@
|
||||
parameterRemapReferenceToConcrete.cxx \
|
||||
parameterRemapReferenceToPointer.cxx parameterRemapThis.cxx \
|
||||
parameterRemapToString.cxx parameterRemapUnchanged.cxx \
|
||||
typeManager.cxx wrapperBuilder.cxx wrapperBuilderC.cxx \
|
||||
wrapperBuilderPython.cxx wrapperBuilderPythonObj.cxx
|
||||
typeManager.cxx
|
||||
|
||||
#end bin_target
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
// Filename: classBuilder.cxx
|
||||
// Created by: drose (17Sep01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "classBuilder.h"
|
||||
#include "interrogate.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClassBuilder::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ClassBuilder::
|
||||
ClassBuilder() {
|
||||
_struct_type = (CPPStructType *)NULL;
|
||||
_type_index = -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClassBuilder::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ClassBuilder::
|
||||
~ClassBuilder() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClassBuilder::set_class
|
||||
// Access: Public, Virtual
|
||||
// Description: Sets the class that will be generated by this
|
||||
// ClassBuilder. Returns true on success, false if the
|
||||
// class cannot be output for some reason.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ClassBuilder::
|
||||
set_class(TypeIndex type_index, CPPStructType *struct_type) {
|
||||
_type_index = type_index;
|
||||
_struct_type = struct_type;
|
||||
return true;
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
// Filename: classBuilder.h
|
||||
// Created by: drose (17Sep01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef CLASSBUILDER_H
|
||||
#define CLASSBUILDER_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
#include "interrogate_interface.h"
|
||||
|
||||
class CPPScope;
|
||||
class CPPStructType;
|
||||
class InterrogateType;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ClassBuilder
|
||||
// Description : Similar to WrapperBuilder, this contains all the
|
||||
// information needed to generate whatever source code
|
||||
// might be associated with a complete class definition
|
||||
// (as opposed to the source code associated with each
|
||||
// function).
|
||||
//
|
||||
// This is an abstract class, and is implemented
|
||||
// separately for each kind of generated output. Most
|
||||
// kinds do not need to write anything special for the
|
||||
// class definition, so do not implement this class. At
|
||||
// the present, only ClassBuilderPythonObj is necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class ClassBuilder {
|
||||
public:
|
||||
ClassBuilder();
|
||||
virtual ~ClassBuilder();
|
||||
|
||||
virtual bool set_class(TypeIndex type_index, CPPStructType *struct_type);
|
||||
|
||||
virtual void write_prototype(ostream &out) const=0;
|
||||
virtual void write_code(ostream &out) const=0;
|
||||
|
||||
protected:
|
||||
CPPStructType *_struct_type;
|
||||
TypeIndex _type_index;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,104 +0,0 @@
|
||||
// Filename: classBuilderPythonObj.cxx
|
||||
// Created by: drose (17Sep01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "classBuilderPythonObj.h"
|
||||
#include "cppStructType.h"
|
||||
#include "interrogateBuilder.h"
|
||||
#include "interrogate.h"
|
||||
|
||||
#include "interrogateType.h"
|
||||
#include "interrogateDatabase.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClassBuilderPythonObj::set_class
|
||||
// Access: Public, Virtual
|
||||
// Description: Sets the class that will be generated by this
|
||||
// ClassBuilder. Returns true on success, false if the
|
||||
// class cannot be output for some reason.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ClassBuilderPythonObj::
|
||||
set_class(TypeIndex type_index, CPPStructType *struct_type) {
|
||||
if (!ClassBuilder::set_class(type_index, struct_type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_name = get_builder_name(_struct_type);
|
||||
|
||||
InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
|
||||
const InterrogateType &itype = idb->get_type(_type_index);
|
||||
int num_methods = itype.number_of_methods();
|
||||
cerr << " // index = " << _type_index << " methods = " << num_methods
|
||||
<< " type = " << itype.get_name() << "\n";
|
||||
for (int i = 0; i < num_methods; i++) {
|
||||
FunctionIndex fi = itype.get_method(i);
|
||||
const InterrogateFunction &func = idb->get_function(fi);
|
||||
|
||||
cerr << " // " << func.get_name() << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClassBuilderPythonObj::write_prototype
|
||||
// Access: Public, Virtual
|
||||
// Description: Generates prototypes for whatever functions will be
|
||||
// generated by write_code().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ClassBuilderPythonObj::
|
||||
write_prototype(ostream &out) const {
|
||||
out << "PyObject *" << _name << "();\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClassBuilderPythonObj::write_code
|
||||
// Access: Public, Virtual
|
||||
// Description: Generates whatever code is appropriate for this
|
||||
// class.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ClassBuilderPythonObj::
|
||||
write_code(ostream &out) const {
|
||||
out << "PyObject *\n"
|
||||
<< _name << "() {\n"
|
||||
<< " static PyObject *wrapper = (PyObject *)NULL;\n"
|
||||
<< " static PyMethodDef methods[] = {\n";
|
||||
|
||||
out << " };\n"
|
||||
<< " if (wrapper == (PyObject *)NULL) {\n"
|
||||
<< " PyObject *bases = PyTuple_New(0);\n"
|
||||
<< " PyObject *dict = PyDict_New();\n"
|
||||
<< " PyObject *name = PyString_FromString(\""
|
||||
<< InterrogateBuilder::clean_identifier(_struct_type->get_simple_name())
|
||||
<< "\");\n"
|
||||
<< " wrapper = PyClass_New(bases, dict, name);\n"
|
||||
<< " }\n"
|
||||
<< " return wrapper;\n"
|
||||
<< "}\n\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClassBuilderPythonObj::get_builder_name
|
||||
// Access: Public, Static
|
||||
// Description: Returns the name of the ClassBuilder function
|
||||
// generated for the indicated struct type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string ClassBuilderPythonObj::
|
||||
get_builder_name(CPPType *struct_type) {
|
||||
return "get_python_class_" +
|
||||
InterrogateBuilder::clean_identifier(struct_type->get_local_name(&parser));
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
// Filename: classBuilderPythonObj.h
|
||||
// Created by: drose (17Sep01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef CLASSBUILDERPYTHONOBJ_H
|
||||
#define CLASSBUILDERPYTHONOBJ_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
#include "classBuilder.h"
|
||||
|
||||
class CPPType;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ClassBuilderPythonObj
|
||||
// Description : A specialization on ClassBuilder that builds
|
||||
// actual Python class objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class ClassBuilderPythonObj : public ClassBuilder {
|
||||
public:
|
||||
virtual bool set_class(TypeIndex type_index, CPPStructType *struct_type);
|
||||
|
||||
virtual void write_prototype(ostream &out) const;
|
||||
virtual void write_code(ostream &out) const;
|
||||
|
||||
static string get_builder_name(CPPType *struct_type);
|
||||
|
||||
private:
|
||||
string _name;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -24,10 +24,9 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : FunctionWriter
|
||||
// Description : This is an abstract class that can be used by the
|
||||
// various WrapperBuilders to indicate a static helper
|
||||
// various InterfaceMakers to indicate a generic helper
|
||||
// function or variable that needs to be written to the
|
||||
// generated source file before the code for the
|
||||
// WrapperBuilders.
|
||||
// generated source file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class FunctionWriter {
|
||||
public:
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : FunctionWriters
|
||||
// Description : A set of zero or more FunctionWriter pointers
|
||||
// accumulated by the various WrapperBuilder objects
|
||||
// accumulated by the various InterfaceMaker objects
|
||||
// that are generating code for one particular output
|
||||
// source file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -18,12 +18,6 @@
|
||||
|
||||
#include "interrogateBuilder.h"
|
||||
#include "interrogate.h"
|
||||
#include "wrapperBuilder.h"
|
||||
#include "wrapperBuilderC.h"
|
||||
#include "wrapperBuilderPython.h"
|
||||
#include "wrapperBuilderPythonObj.h"
|
||||
#include "classBuilder.h"
|
||||
#include "classBuilderPythonObj.h"
|
||||
#include "parameterRemap.h"
|
||||
#include "typeManager.h"
|
||||
#include "functionWriters.h"
|
||||
@@ -1603,248 +1597,6 @@ get_function(CPPInstance *function, string description,
|
||||
return index;
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////
|
||||
// // Function: InterrogateBuilder::get_wrapper_builder_c
|
||||
// // Access: Private
|
||||
// // Description: Returns a WrapperBuilder object suitable for wrapping
|
||||
// // the indicated function. This may either be a
|
||||
// // newly-allocated object, or a previously-allocated one
|
||||
// // if function overloading of multiple functions is to
|
||||
// // be implemented within the WrapperBuilder.
|
||||
// ////////////////////////////////////////////////////////////////////
|
||||
// WrapperBuilder *InterrogateBuilder::
|
||||
// get_wrapper_builder_c(const InterrogateFunction &) {
|
||||
// return new WrapperBuilderC;
|
||||
// }
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////
|
||||
// // Function: InterrogateBuilder::get_wrapper_builder_python
|
||||
// // Access: Private
|
||||
// // Description: Returns a WrapperBuilder object suitable for wrapping
|
||||
// // the indicated function. This may either be a
|
||||
// // newly-allocated object, or a previously-allocated one
|
||||
// // if function overloading of multiple functions is to
|
||||
// // be implemented within the WrapperBuilder.
|
||||
// ////////////////////////////////////////////////////////////////////
|
||||
// WrapperBuilder *InterrogateBuilder::
|
||||
// get_wrapper_builder_python(const InterrogateFunction &) {
|
||||
// return new WrapperBuilderPython;
|
||||
// }
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////
|
||||
// // Function: InterrogateBuilder::get_wrapper_builder_python_obj
|
||||
// // Access: Private
|
||||
// // Description: Returns a WrapperBuilder object suitable for wrapping
|
||||
// // the indicated function. This may either be a
|
||||
// // newly-allocated object, or a previously-allocated one
|
||||
// // if function overloading of multiple functions is to
|
||||
// // be implemented within the WrapperBuilder.
|
||||
// ////////////////////////////////////////////////////////////////////
|
||||
// WrapperBuilder *InterrogateBuilder::
|
||||
// get_wrapper_builder_python_obj(const InterrogateFunction &ifunction) {
|
||||
// string scoped_name = ifunction.get_scoped_name();
|
||||
// OverloadedWrappers::iterator wi;
|
||||
// wi = _python_obj_wrappers.find(scoped_name);
|
||||
// if (wi == _python_obj_wrappers.end()) {
|
||||
// wi = _python_obj_wrappers.insert(OverloadedWrappers::value_type(scoped_name, new WrapperBuilderPythonObj)).first;
|
||||
// }
|
||||
// return (*wi).second;
|
||||
// }
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////
|
||||
// // Function: InterrogateBuilder::make_wrappers
|
||||
// // Access: Private
|
||||
// // Description: Makes the wrappers for all of the newly-defined
|
||||
// // functions. This might result in the definition of a
|
||||
// // few new incidental types necessary to support the
|
||||
// // wrappers' parameters.
|
||||
// ////////////////////////////////////////////////////////////////////
|
||||
// void InterrogateBuilder::
|
||||
// make_wrappers() {
|
||||
// while (!_new_functions.empty()) {
|
||||
// // Make a copy of the new_functions list, and iterate through the
|
||||
// // copy. This is just in case we end up defining a few *more*
|
||||
// // functions while we do this.
|
||||
// NewFunctions new_functions;
|
||||
// new_functions.swap(_new_functions);
|
||||
|
||||
// NewFunctions::iterator ni;
|
||||
// for (ni = new_functions.begin(); ni != new_functions.end(); ++ni) {
|
||||
// const NewFunction &nf = (*ni);
|
||||
// int num_default_parameters = nf._ftype->get_num_default_parameters();
|
||||
|
||||
// InterrogateFunction &ifunction =
|
||||
// InterrogateDatabase::get_ptr()->update_function(nf._function_index);
|
||||
|
||||
// if (build_c_wrappers) {
|
||||
// // Make the C wrapper(s).
|
||||
// for (int dp = 0; dp <= num_default_parameters; dp++) {
|
||||
// FunctionWrapperIndex wrapper =
|
||||
// get_wrapper(nf._function_index, get_wrapper_builder_c(ifunction),
|
||||
// nf._function, nf._description,
|
||||
// nf._struct_type, nf._scope,
|
||||
// nf._wtype, nf._expression, dp);
|
||||
// if (wrapper != 0) {
|
||||
// ifunction._c_wrappers.push_back(wrapper);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (build_python_wrappers) {
|
||||
// // Make the Python C-style function wrapper.
|
||||
// for (int dp = 0; dp <= num_default_parameters; dp++) {
|
||||
// FunctionWrapperIndex wrapper =
|
||||
// get_wrapper(nf._function_index, get_wrapper_builder_python(ifunction),
|
||||
// nf._function, nf._description,
|
||||
// nf._struct_type, nf._scope,
|
||||
// nf._wtype, nf._expression, dp);
|
||||
// if (wrapper != 0) {
|
||||
// ifunction._python_wrappers.push_back(wrapper);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (build_python_obj_wrappers) {
|
||||
// // Make the Python C++-style method wrapper. This style
|
||||
// // wrapper does not need to be recorded in the database,
|
||||
// // because it can be executed directly by Python.
|
||||
// WrapperBuilder *wbuilder = get_wrapper_builder_python_obj(ifunction);
|
||||
// for (int dp = num_default_parameters; dp >= 0; dp--) {
|
||||
// get_wrapper(nf._function_index, wbuilder,
|
||||
// nf._function, nf._description,
|
||||
// nf._struct_type, nf._scope,
|
||||
// nf._wtype, nf._expression, dp);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////
|
||||
// // Function: InterrogateBuilder::get_wrapper
|
||||
// // Access: Private
|
||||
// // Description: Defines a particular wrapper for the given function.
|
||||
// // wbuilder is a newly-allocated WrapperBuilder of the
|
||||
// // appropriate type.
|
||||
// ////////////////////////////////////////////////////////////////////
|
||||
// FunctionWrapperIndex InterrogateBuilder::
|
||||
// get_wrapper(FunctionIndex function_index, WrapperBuilder *wbuilder,
|
||||
// CPPInstance *function, string description,
|
||||
// CPPStructType *struct_type,
|
||||
// CPPScope *scope, WrapperBuilder::Type wtype,
|
||||
// const string &expression,
|
||||
// int num_default_parameters) {
|
||||
|
||||
// string function_signature =
|
||||
// TypeManager::get_function_signature(function, num_default_parameters);
|
||||
|
||||
// if (description.empty()) {
|
||||
// // Make up a description string if we weren't given one.
|
||||
// ostringstream desc;
|
||||
// function->output(desc, 0, &parser, false, num_default_parameters);
|
||||
// desc << ";";
|
||||
// description = desc.str();
|
||||
// }
|
||||
|
||||
// int def_index =
|
||||
// wbuilder->add_function(function, description, struct_type, scope,
|
||||
// function_signature, wtype,
|
||||
// expression, num_default_parameters);
|
||||
// if (def_index < 0) {
|
||||
// // This function can't be exported for some reason.
|
||||
|
||||
// // We can't safely delete this, because it might be shared.
|
||||
// // delete wbuilder;
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// assert(def_index >= 0 && def_index < (int)wbuilder->_def.size());
|
||||
// WrapperBuilder::FunctionDef *def = wbuilder->_def[def_index];
|
||||
|
||||
// if (def_index == 0) {
|
||||
// // If this is the first definition for this particular wrapper,
|
||||
// // assign a new wrapper index and hash number.
|
||||
// FunctionWrapperIndex index =
|
||||
// InterrogateDatabase::get_ptr()->get_next_index();
|
||||
// wbuilder->_wrapper_index = index;
|
||||
|
||||
// hash_function_signature(wbuilder);
|
||||
// }
|
||||
|
||||
// InterrogateFunctionWrapper iwrapper;
|
||||
|
||||
// iwrapper._function = function_index;
|
||||
|
||||
// // We do assume that two different libraries will not hash to the
|
||||
// // same name. This is pretty unlikely, although there could be big
|
||||
// // problems if it ever happens. If it does, we'll probably need to
|
||||
// // add an interface so the user can specify a hash offset on a
|
||||
// // per-library basis or something like that.
|
||||
// iwrapper._unique_name = _library_hash_name + wbuilder->_hash;
|
||||
|
||||
// WrapperBuilder::Parameters::const_iterator pi;
|
||||
// for (pi = def->_parameters.begin();
|
||||
// pi != def->_parameters.end();
|
||||
// ++pi) {
|
||||
// InterrogateFunctionWrapper::Parameter param;
|
||||
// param._parameter_flags = 0;
|
||||
// if ((*pi)._remap->new_type_is_atomic_string()) {
|
||||
// param._type = get_atomic_string_type();
|
||||
// } else {
|
||||
// param._type = get_type((*pi)._remap->get_new_type(), false);
|
||||
// }
|
||||
// param._name = (*pi)._name;
|
||||
// if ((*pi)._has_name) {
|
||||
// param._parameter_flags |= InterrogateFunctionWrapper::PF_has_name;
|
||||
// }
|
||||
// iwrapper._parameters.push_back(param);
|
||||
// }
|
||||
|
||||
// if (def->_has_this) {
|
||||
// // If one of the parameters is "this", it must be the first one.
|
||||
// assert(!iwrapper._parameters.empty());
|
||||
// iwrapper._parameters.front()._parameter_flags |=
|
||||
// InterrogateFunctionWrapper::PF_is_this;
|
||||
// }
|
||||
|
||||
// if (def->_return_type->new_type_is_atomic_string()) {
|
||||
// iwrapper._return_type = get_atomic_string_type();
|
||||
// } else {
|
||||
// iwrapper._return_type =
|
||||
// get_type(def->_return_type->get_new_type(), false);
|
||||
// }
|
||||
|
||||
// if (!def->_void_return) {
|
||||
// iwrapper._flags |= InterrogateFunctionWrapper::F_has_return;
|
||||
|
||||
// if (def->_return_value_needs_management) {
|
||||
// iwrapper._flags |= InterrogateFunctionWrapper::F_caller_manages;
|
||||
// int destructor = def->_return_value_destructor;
|
||||
|
||||
// if (destructor != 0) {
|
||||
// iwrapper._return_value_destructor = destructor;
|
||||
|
||||
// } else {
|
||||
// // We don't need to report this warning, since the FFI code
|
||||
// // understands that if the destructor function is zero, it
|
||||
// // should use the regular class destructor.
|
||||
|
||||
// // nout << "Warning! Destructor for "
|
||||
// // << *def->_return_type->get_orig_type()
|
||||
// // << " is unavailable.\n"
|
||||
// // << " Cannot manage return value for:\n "
|
||||
// // << description << "\n";
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (def_index == 0) {
|
||||
// InterrogateDatabase::get_ptr()->add_wrapper(wbuilder->_wrapper_index, iwrapper);
|
||||
// }
|
||||
// return wbuilder->_wrapper_index;
|
||||
// }
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateBuilder::get_atomic_string_type
|
||||
// Access: Private
|
||||
@@ -2299,31 +2051,8 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
|
||||
0);
|
||||
itype._flags |= InterrogateType::F_implicit_destructor;
|
||||
}
|
||||
|
||||
// Finally, generate any ClassBuilder objects appropriate to this
|
||||
// type.
|
||||
// make_class_builders(type_index, cpptype);
|
||||
}
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateBuilder::make_class_builders
|
||||
// Access: Private
|
||||
// Description: Creates whatever ClassBuilder objects might be
|
||||
// required for the indicated class type and stores them
|
||||
// in the InterrogateBuilder object for later generation
|
||||
// of code.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterrogateBuilder::
|
||||
make_class_builders(TypeIndex type_index, CPPStructType *cpptype) {
|
||||
if (build_python_obj_wrappers) {
|
||||
ClassBuilder *cbuilder = new ClassBuilderPythonObj;
|
||||
cbuilder->set_class(type_index, cpptype);
|
||||
_class_builders.push_back(cbuilder);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateBuilder::update_method_comment
|
||||
// Access: Private
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
#include "interrogate_interface.h"
|
||||
#include "interrogate_request.h"
|
||||
#include "wrapperBuilder.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
@@ -45,7 +44,6 @@ class CPPNameComponent;
|
||||
class CPPManifest;
|
||||
class InterrogateType;
|
||||
class InterrogateFunction;
|
||||
class ClassBuilder;
|
||||
class FunctionRemap;
|
||||
class InterfaceMaker;
|
||||
|
||||
@@ -109,20 +107,6 @@ private:
|
||||
CPPStructType *struct_type, CPPScope *scope,
|
||||
int flags, const string &expression = string());
|
||||
|
||||
/*
|
||||
WrapperBuilder *get_wrapper_builder_c(const InterrogateFunction &ifunction);
|
||||
WrapperBuilder *get_wrapper_builder_python(const InterrogateFunction &ifunction);
|
||||
WrapperBuilder *get_wrapper_builder_python_obj(const InterrogateFunction &ifunction);
|
||||
|
||||
void make_wrappers();
|
||||
FunctionWrapperIndex
|
||||
get_wrapper(FunctionIndex function_index,
|
||||
WrapperBuilder *wbuilder, CPPInstance *function,
|
||||
string description, CPPStructType *struct_type, CPPScope *scope,
|
||||
WrapperBuilder::Type wtype, const string &expression,
|
||||
int num_default_parameters);
|
||||
*/
|
||||
|
||||
TypeIndex get_atomic_string_type();
|
||||
TypeIndex get_type(CPPType *type, bool global);
|
||||
|
||||
@@ -131,7 +115,6 @@ private:
|
||||
void define_wrapped_type(InterrogateType &itype, CPPConstType *cpptype);
|
||||
void define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
|
||||
TypeIndex type_index, bool forced);
|
||||
void make_class_builders(TypeIndex type_index, CPPStructType *cpptype);
|
||||
void update_method_comment(CPPInstance *function, CPPStructType *struct_type,
|
||||
CPPScope *scope);
|
||||
void define_method(CPPFunctionGroup *fgroup, InterrogateType &itype,
|
||||
@@ -144,31 +127,12 @@ private:
|
||||
|
||||
static string trim_blanks(const string &str);
|
||||
|
||||
/*
|
||||
class NewFunction {
|
||||
public:
|
||||
CPPInstance *_function;
|
||||
string _description;
|
||||
CPPFunctionType *_ftype;
|
||||
CPPStructType *_struct_type;
|
||||
CPPScope *_scope;
|
||||
WrapperBuilder::Type _wtype;
|
||||
string _expression;
|
||||
int _function_index;
|
||||
};
|
||||
typedef vector<NewFunction> NewFunctions;
|
||||
NewFunctions _new_functions;
|
||||
*/
|
||||
|
||||
typedef map<string, TypeIndex> TypesByName;
|
||||
typedef map<string, FunctionIndex> FunctionsByName;
|
||||
|
||||
TypesByName _types_by_name;
|
||||
FunctionsByName _functions_by_name;
|
||||
|
||||
typedef vector<ClassBuilder *> ClassBuilders;
|
||||
ClassBuilders _class_builders;
|
||||
|
||||
typedef map<string, char> IncludeFiles;
|
||||
IncludeFiles _include_files;
|
||||
|
||||
@@ -182,9 +146,6 @@ private:
|
||||
|
||||
string _library_hash_name;
|
||||
|
||||
typedef map<string, WrapperBuilder *> OverloadedWrappers;
|
||||
OverloadedWrappers _python_obj_wrappers;
|
||||
|
||||
friend class FunctionRemap;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
|
||||
#include "interrogateBuilder.cxx"
|
||||
#include "functionRemap.cxx"
|
||||
#include "functionWriter.cxx"
|
||||
#include "functionWriterPtrFromPython.cxx"
|
||||
#include "functionWriterPtrToPython.cxx"
|
||||
#include "functionWriters.cxx"
|
||||
#include "interfaceMaker.cxx"
|
||||
#include "interfaceMakerC.cxx"
|
||||
#include "interfaceMakerPython.cxx"
|
||||
#include "interfaceMakerPythonObj.cxx"
|
||||
#include "interfaceMakerPythonSimple.cxx"
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
|
||||
#include "interrogate.cxx"
|
||||
#include "typeManager.cxx"
|
||||
#include "wrapperBuilder.cxx"
|
||||
#include "wrapperBuilderC.cxx"
|
||||
#include "wrapperBuilderPython.cxx"
|
||||
#include "parameterRemap.cxx"
|
||||
#include "parameterRemapBasicStringRefToString.cxx"
|
||||
#include "parameterRemapBasicStringToString.cxx"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "parameterRemapBasicStringToString.h"
|
||||
#include "wrapperBuilder.h"
|
||||
#include "interfaceMaker.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParameterRemapBasicStringToString::Constructor
|
||||
@@ -53,7 +53,7 @@ pass_parameter(ostream &out, const string &variable_name) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string ParameterRemapBasicStringToString::
|
||||
prepare_return_expr(ostream &out, int indent_level, const string &expression) {
|
||||
WrapperBuilder::indent(out, indent_level)
|
||||
InterfaceMaker::indent(out, indent_level)
|
||||
<< "static basic_string<char> string_holder = " << expression << ";\n";
|
||||
return "string_holder";
|
||||
}
|
||||
|
||||
@@ -1,817 +0,0 @@
|
||||
// Filename: wrapperBuilder.cxx
|
||||
// Created by: drose (01Aug00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "wrapperBuilder.h"
|
||||
#include "interrogate.h"
|
||||
#include "parameterRemap.h"
|
||||
#include "parameterRemapThis.h"
|
||||
#include "parameterRemapUnchanged.h"
|
||||
#include "parameterRemapReferenceToPointer.h"
|
||||
#include "parameterRemapConcreteToPointer.h"
|
||||
#include "parameterRemapEnumToInt.h"
|
||||
#include "parameterRemapConstToNonConst.h"
|
||||
#include "parameterRemapReferenceToConcrete.h"
|
||||
#include "parameterRemapCharStarToString.h"
|
||||
#include "parameterRemapBasicStringToString.h"
|
||||
#include "parameterRemapBasicStringRefToString.h"
|
||||
#include "parameterRemapPTToPointer.h"
|
||||
#include "interrogateBuilder.h"
|
||||
#include "typeManager.h"
|
||||
|
||||
#include <interrogateDatabase.h>
|
||||
#include <cppInstance.h>
|
||||
#include <cppFunctionType.h>
|
||||
#include <cppParameterList.h>
|
||||
#include <cppStructType.h>
|
||||
#include <cppReferenceType.h>
|
||||
#include <notify.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::FunctionDef::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WrapperBuilder::FunctionDef::
|
||||
FunctionDef() {
|
||||
_return_type = (ParameterRemap *)NULL;
|
||||
_void_return = true;
|
||||
_has_this = false;
|
||||
_is_method = false;
|
||||
_type = T_normal;
|
||||
|
||||
_function = (CPPInstance *)NULL;
|
||||
_struct_type = (CPPStructType *)NULL;
|
||||
_scope = (CPPScope *)NULL;
|
||||
_ftype = (CPPFunctionType *)NULL;
|
||||
_num_default_parameters = 0;
|
||||
|
||||
_return_value_needs_management = false;
|
||||
_return_value_destructor = 0;
|
||||
_manage_reference_count = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::FunctionDef::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WrapperBuilder::FunctionDef::
|
||||
~FunctionDef() {
|
||||
Parameters::iterator pi;
|
||||
for (pi = _parameters.begin(); pi != _parameters.end(); ++pi) {
|
||||
delete (*pi)._remap;
|
||||
}
|
||||
_parameters.clear();
|
||||
|
||||
if (_return_type != (ParameterRemap *)NULL) {
|
||||
delete _return_type;
|
||||
_return_type = (ParameterRemap *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::FunctionDef::Copy constructor
|
||||
// Access: Private
|
||||
// Description: These are not designed to be copied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WrapperBuilder::FunctionDef::
|
||||
FunctionDef(const FunctionDef &) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::FunctionDef::Copy assignment operator
|
||||
// Access: Private
|
||||
// Description: These are not designed to be copied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilder::FunctionDef::
|
||||
operator = (const FunctionDef &) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WrapperBuilder::
|
||||
WrapperBuilder() {
|
||||
_wrapper_index = 0;
|
||||
_is_valid = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WrapperBuilder::
|
||||
~WrapperBuilder() {
|
||||
Def::iterator di;
|
||||
for (di = _def.begin(); di != _def.end(); ++di) {
|
||||
delete (*di);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::add_function
|
||||
// Access: Public
|
||||
// Description: Sets up the builder according to the indicated
|
||||
// function. The value of num_default_parameters
|
||||
// represents the number of parameters on the end to
|
||||
// assign to their default values for this particular
|
||||
// wrapper.
|
||||
//
|
||||
// If this is called only once, then the WrapperBuilder
|
||||
// will generate a wrapper that only calls the
|
||||
// particular C++ function. Otherwise, if this is
|
||||
// called multiple times (and the WrapperBuilder type
|
||||
// supports this), it will generate a wrapper that can
|
||||
// handle overloading, and will call the appropriate
|
||||
// C++ function based on the input parameters.
|
||||
//
|
||||
// Returns the definition index if successful, or -1 if
|
||||
// the function cannot be wrapped for some reason.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int WrapperBuilder::
|
||||
add_function(CPPInstance *function, const string &description,
|
||||
CPPStructType *struct_type,
|
||||
CPPScope *scope, const string &function_signature,
|
||||
WrapperBuilder::Type type,
|
||||
const string &expression,
|
||||
int num_default_parameters) {
|
||||
_is_valid = true;
|
||||
int def_index = (int)_def.size();
|
||||
FunctionDef *def = new FunctionDef;
|
||||
_def.push_back(def);
|
||||
|
||||
def->_function = function;
|
||||
def->_description = description;
|
||||
def->_struct_type = struct_type;
|
||||
def->_scope = scope;
|
||||
def->_function_signature = function_signature;
|
||||
def->_expression = expression;
|
||||
def->_num_default_parameters = num_default_parameters;
|
||||
def->_parameters.clear();
|
||||
|
||||
def->_ftype = def->_function->_type->resolve_type(scope, &parser)->as_function_type();
|
||||
assert(def->_ftype != (CPPFunctionType *)NULL);
|
||||
|
||||
def->_has_this = false;
|
||||
def->_is_method = false;
|
||||
def->_type = type;
|
||||
|
||||
if ((def->_ftype->_flags & CPPFunctionType::F_constructor) != 0) {
|
||||
def->_type = T_constructor;
|
||||
|
||||
} else if ((def->_ftype->_flags & CPPFunctionType::F_destructor) != 0) {
|
||||
def->_type = T_destructor;
|
||||
|
||||
} else if ((def->_ftype->_flags & CPPFunctionType::F_operator_typecast) != 0) {
|
||||
def->_type = T_typecast_method;
|
||||
}
|
||||
|
||||
if (def->_struct_type != (CPPStructType *)NULL &&
|
||||
((function->_storage_class & CPPInstance::SC_static) == 0) &&
|
||||
def->_type != T_constructor) {
|
||||
|
||||
// If this is a method, but not a static method, and not a
|
||||
// constructor, then we may need to synthesize a "this" parameter.
|
||||
def->_is_method = true;
|
||||
|
||||
if (synthesize_this_parameter()) {
|
||||
Parameter param;
|
||||
param._name = "this";
|
||||
param._has_name = true;
|
||||
bool is_const = (def->_ftype->_flags & CPPFunctionType::F_const_method) != 0;
|
||||
param._remap = new ParameterRemapThis(def->_struct_type, is_const);
|
||||
def->_parameters.push_back(param);
|
||||
def->_has_this = true;
|
||||
}
|
||||
|
||||
// Also check the name of the function. If it's one of the
|
||||
// assignment-style operators, flag it as such.
|
||||
string fname = def->_function->get_simple_name();
|
||||
if (fname == "operator =" ||
|
||||
fname == "operator *=" ||
|
||||
fname == "operator /=" ||
|
||||
fname == "operator %=" ||
|
||||
fname == "operator +=" ||
|
||||
fname == "operator -=" ||
|
||||
fname == "operator |=" ||
|
||||
fname == "operator &=" ||
|
||||
fname == "operator ^=" ||
|
||||
fname == "operator <<=" ||
|
||||
fname == "operator >>=") {
|
||||
def->_type = T_assignment_method;
|
||||
}
|
||||
}
|
||||
|
||||
const CPPParameterList::Parameters ¶ms =
|
||||
def->_ftype->_parameters->_parameters;
|
||||
for (int i = 0; i < (int)params.size() - num_default_parameters; i++) {
|
||||
CPPType *type = params[i]->_type->resolve_type(&parser, def->_scope);
|
||||
Parameter param;
|
||||
param._has_name = true;
|
||||
param._name = params[i]->get_simple_name();
|
||||
|
||||
if (param._name.empty()) {
|
||||
// If the parameter has no name, record it as being nameless,
|
||||
// but also synthesize one in case someone asks anyway.
|
||||
param._has_name = false;
|
||||
ostringstream param_name;
|
||||
param_name << "param" << i;
|
||||
param._name = param_name.str();
|
||||
}
|
||||
|
||||
param._remap = make_remap(def_index, type);
|
||||
param._remap->set_default_value(params[i]->_initializer);
|
||||
|
||||
if (!param._remap->is_valid()) {
|
||||
_is_valid = false;
|
||||
}
|
||||
|
||||
def->_parameters.push_back(param);
|
||||
}
|
||||
|
||||
if (def->_type == T_constructor) {
|
||||
// Constructors are a special case. These appear to return void
|
||||
// as seen by the parser, but we know they actually return a new
|
||||
// concrete instance.
|
||||
|
||||
if (def->_struct_type == (CPPStructType *)NULL) {
|
||||
nout << "Method " << *def->_function << " has no struct type\n";
|
||||
_is_valid = false;
|
||||
} else {
|
||||
def->_return_type = make_remap(def_index, def->_struct_type);
|
||||
def->_void_return = false;
|
||||
}
|
||||
|
||||
} else if (def->_type == T_assignment_method) {
|
||||
// Assignment-type methods are also a special case. We munge
|
||||
// these to return *this, which is a semi-standard C++ convention
|
||||
// anyway. We just enforce it.
|
||||
|
||||
if (def->_struct_type == (CPPStructType *)NULL) {
|
||||
nout << "Method " << *def->_function << " has no struct type\n";
|
||||
_is_valid = false;
|
||||
} else {
|
||||
CPPType *ref_type = CPPType::new_type(new CPPReferenceType(def->_struct_type));
|
||||
def->_return_type = make_remap(def_index, ref_type);
|
||||
def->_void_return = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
// The normal case.
|
||||
CPPType *rtype = def->_ftype->_return_type->resolve_type(&parser, def->_scope);
|
||||
def->_return_type = make_remap(def_index, rtype);
|
||||
def->_void_return = TypeManager::is_void(rtype);
|
||||
}
|
||||
|
||||
if (!def->_return_type->is_valid()) {
|
||||
_is_valid = false;
|
||||
}
|
||||
|
||||
// Do we need to manage the return value?
|
||||
def->_return_value_needs_management =
|
||||
def->_return_type->return_value_needs_management();
|
||||
def->_return_value_destructor =
|
||||
def->_return_type->get_return_value_destructor();
|
||||
|
||||
// Should we manage a reference count?
|
||||
CPPType *return_type = def->_return_type->get_new_type();
|
||||
CPPType *return_meat_type = TypeManager::unwrap_pointer(return_type);
|
||||
|
||||
if (manage_reference_counts &&
|
||||
TypeManager::is_reference_count_pointer(return_type) &&
|
||||
!TypeManager::has_protected_destructor(return_meat_type)) {
|
||||
// Yes!
|
||||
def->_manage_reference_count = true;
|
||||
def->_return_value_needs_management = true;
|
||||
|
||||
// This is problematic, because we might not have the class in
|
||||
// question fully defined here, particularly if the class is
|
||||
// defined in some other library.
|
||||
def->_return_value_destructor = builder.get_destructor_for(return_meat_type);
|
||||
}
|
||||
|
||||
if (!_is_valid) {
|
||||
// Invalid function wrapper. Too bad.
|
||||
_def.pop_back();
|
||||
delete def;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return def_index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::get_function_writers
|
||||
// Access: Public, Virtual
|
||||
// Description: Adds whatever list of FunctionWriters might be needed
|
||||
// for this particular WrapperBuilder. These will be
|
||||
// generated to the output source file before
|
||||
// write_wrapper() is called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilder::
|
||||
get_function_writers(FunctionWriters &) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::synthesize_this_parameter
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if this particular wrapper type requires
|
||||
// an explicit "this" parameter to be added to the
|
||||
// function parameter list when appropriate, or false if
|
||||
// the "this" pointer will come through a different
|
||||
// channel.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool WrapperBuilder::
|
||||
synthesize_this_parameter() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::make_remap
|
||||
// Access: Protected, Virtual
|
||||
// Description: Allocates a new ParameterRemap object suitable to the
|
||||
// indicated type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ParameterRemap *WrapperBuilder::
|
||||
make_remap(int def_index, CPPType *orig_type) {
|
||||
assert(def_index >= 0 && def_index < (int)_def.size());
|
||||
const FunctionDef *def = _def[def_index];
|
||||
|
||||
if (convert_strings) {
|
||||
if (TypeManager::is_char_pointer(orig_type)) {
|
||||
return new ParameterRemapCharStarToString(orig_type);
|
||||
}
|
||||
|
||||
// If we're exporting a method of basic_string<char> itself, don't
|
||||
// convert basic_string<char>'s to atomic strings.
|
||||
|
||||
if (def->_struct_type == (CPPStructType *)NULL ||
|
||||
!TypeManager::is_basic_string_char(def->_struct_type)) {
|
||||
if (TypeManager::is_basic_string_char(orig_type)) {
|
||||
return new ParameterRemapBasicStringToString(orig_type);
|
||||
|
||||
} else if (TypeManager::is_const_ref_to_basic_string_char(orig_type)) {
|
||||
return new ParameterRemapBasicStringRefToString(orig_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (manage_reference_counts) {
|
||||
if (TypeManager::is_pointer_to_base(orig_type) ||
|
||||
TypeManager::is_const_ref_to_pointer_to_base(orig_type)) {
|
||||
CPPType *pt_type = TypeManager::unwrap_reference(orig_type);
|
||||
|
||||
// Don't convert PointerTo<>'s to pointers for methods of the
|
||||
// PointerTo itself!
|
||||
if (def->_struct_type == (CPPStructType *)NULL ||
|
||||
!(pt_type->get_local_name(&parser) == def->_struct_type->get_local_name(&parser))) {
|
||||
return new ParameterRemapPTToPointer(orig_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TypeManager::is_reference(orig_type)) {
|
||||
return new ParameterRemapReferenceToPointer(orig_type);
|
||||
|
||||
} else if (TypeManager::is_struct(orig_type)) {
|
||||
return new ParameterRemapConcreteToPointer(orig_type);
|
||||
|
||||
/*
|
||||
} else if (TypeManager::is_enum(orig_type) || TypeManager::is_const_ref_to_enum(orig_type)) {
|
||||
return new ParameterRemapEnumToInt(orig_type);
|
||||
*/
|
||||
|
||||
} else if (TypeManager::is_const_simple(orig_type)) {
|
||||
return new ParameterRemapConstToNonConst(orig_type);
|
||||
|
||||
} else if (TypeManager::is_const_ref_to_simple(orig_type)) {
|
||||
return new ParameterRemapReferenceToConcrete(orig_type);
|
||||
|
||||
} else if (TypeManager::is_pointer(orig_type) || TypeManager::is_simple(orig_type)) {
|
||||
return new ParameterRemapUnchanged(orig_type);
|
||||
|
||||
} else {
|
||||
// Here's something we have a problem with.
|
||||
_is_valid = false;
|
||||
return new ParameterRemapUnchanged(orig_type);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::manage_return_value
|
||||
// Access: Protected
|
||||
// Description: Does any additional processing that we might want to
|
||||
// do on the return value for the function, just before
|
||||
// we return it. Returns the string representing the
|
||||
// new return value after processing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string WrapperBuilder::
|
||||
manage_return_value(int def_index,
|
||||
ostream &out, int indent_level,
|
||||
const string &return_expr) const {
|
||||
assert(def_index >= 0 && def_index < (int)_def.size());
|
||||
const FunctionDef *def = _def[def_index];
|
||||
if (def->_manage_reference_count) {
|
||||
// If we're managing reference counts, and we're about to return a
|
||||
// reference countable object, then increment its count.
|
||||
if (return_expr == "return_value") {
|
||||
// If the expression is just a variable name, we can just ref it
|
||||
// directly.
|
||||
output_ref(def_index, out, indent_level, return_expr);
|
||||
return return_expr;
|
||||
|
||||
} else {
|
||||
// Otherwise, we should probably assign it to a temporary first,
|
||||
// so we don't invoke the function twice or something.
|
||||
CPPType *type = def->_return_type->get_temporary_type();
|
||||
indent(out, indent_level);
|
||||
type->output_instance(out, "refcount", &parser);
|
||||
out << " = " << return_expr << ";\n";
|
||||
|
||||
indent(out, indent_level)
|
||||
<< "if (" << return_expr << " != ("
|
||||
<< def->_return_type->get_new_type()->get_local_name(&parser) << ")0) {\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< return_expr << "->ref();\n";
|
||||
indent(out, indent_level)
|
||||
<< "}\n";
|
||||
output_ref(def_index, out, indent_level, "refcount");
|
||||
return def->_return_type->temporary_to_return("refcount");
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, just return the expression unchanged.
|
||||
return return_expr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::output_ref
|
||||
// Access: Protected
|
||||
// Description: Outputs the code to increment the reference count for
|
||||
// the indicated variable name.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilder::
|
||||
output_ref(int def_index, ostream &out, int indent_level, const string &varname) const {
|
||||
assert(def_index >= 0 && def_index < (int)_def.size());
|
||||
const FunctionDef *def = _def[def_index];
|
||||
if (def->_type == T_constructor || def->_type == T_typecast) {
|
||||
// In either of these cases, we can safely assume the pointer will
|
||||
// never be NULL.
|
||||
indent(out, indent_level)
|
||||
<< varname << "->ref();\n";
|
||||
|
||||
} else {
|
||||
// However, in the general case, we have to check for that before
|
||||
// we attempt to ref it.
|
||||
|
||||
indent(out, indent_level)
|
||||
<< "if (" << varname << " != ("
|
||||
<< def->_return_type->get_new_type()->get_local_name(&parser) << ")0) {\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< varname << "->ref();\n";
|
||||
indent(out, indent_level)
|
||||
<< "}\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::get_parameter_name
|
||||
// Access: Protected
|
||||
// Description: Returns a suitable name for the nth parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string WrapperBuilder::
|
||||
get_parameter_name(int n) const {
|
||||
/*
|
||||
if (_has_this) {
|
||||
if (n == 0) {
|
||||
return "container";
|
||||
}
|
||||
n--;
|
||||
}
|
||||
*/
|
||||
|
||||
ostringstream str;
|
||||
str << "param" << n;
|
||||
return str.str();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::get_parameter_expr
|
||||
// Access: Protected
|
||||
// Description: Returns a string that represents the expression
|
||||
// associated with the nth parameter. This is just the
|
||||
// nth element of pexprs if it is nonempty, or the name
|
||||
// of the nth parameter is it is empty.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string WrapperBuilder::
|
||||
get_parameter_expr(int n, const vector_string &pexprs) const {
|
||||
if (n < (int)pexprs.size()) {
|
||||
return pexprs[n];
|
||||
}
|
||||
return get_parameter_name(n);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::get_call_str
|
||||
// Access: Protected
|
||||
// Description: Returns a string suitable for calling the wrapped
|
||||
// function. If pexprs is nonempty, it represents
|
||||
// the list of expressions that will evaluate to each
|
||||
// parameter value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string WrapperBuilder::
|
||||
get_call_str(int def_index,
|
||||
const string &container, const vector_string &pexprs) const {
|
||||
assert(def_index >= 0 && def_index < (int)_def.size());
|
||||
const FunctionDef *def = _def[def_index];
|
||||
|
||||
// Build up the call to the actual function.
|
||||
ostringstream call;
|
||||
|
||||
// Getters and setters are a special case.
|
||||
if (def->_type == T_getter) {
|
||||
if (!container.empty()) {
|
||||
call << "(" << container << ")->" << def->_expression;
|
||||
} else {
|
||||
call << def->_expression;
|
||||
}
|
||||
assert(def->_parameters.empty());
|
||||
|
||||
} else if (def->_type == T_setter) {
|
||||
if (!container.empty()) {
|
||||
call << "(" << container << ")->" << def->_expression;
|
||||
} else {
|
||||
call << def->_expression;
|
||||
}
|
||||
|
||||
call << " = ";
|
||||
assert(def->_parameters.size() == 1);
|
||||
def->_parameters[0]._remap->pass_parameter(call, get_parameter_expr(0, pexprs));
|
||||
|
||||
} else {
|
||||
int pn = 0;
|
||||
if (def->_type == T_constructor) {
|
||||
// Constructors are called differently.
|
||||
call << def->_struct_type->get_local_name(&parser);
|
||||
|
||||
} else if (!container.empty()) {
|
||||
// If we have a "this" parameter, the calling convention is also
|
||||
// a bit different.
|
||||
call << "(" << container << ")->" << def->_function->get_local_name();
|
||||
if (def->_has_this) {
|
||||
pn++;
|
||||
}
|
||||
|
||||
} else {
|
||||
call << def->_function->get_local_name(&parser);
|
||||
}
|
||||
|
||||
call << "(";
|
||||
if (pn < (int)def->_parameters.size()) {
|
||||
def->_parameters[pn]._remap->pass_parameter(call, get_parameter_expr(pn, pexprs));
|
||||
pn++;
|
||||
while (pn < (int)def->_parameters.size()) {
|
||||
call << ", ";
|
||||
def->_parameters[pn]._remap->pass_parameter(call, get_parameter_expr(pn, pexprs));
|
||||
pn++;
|
||||
}
|
||||
}
|
||||
call << ")";
|
||||
}
|
||||
|
||||
return call.str();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::call_function
|
||||
// Access: Protected
|
||||
// Description: Writes a sequence of commands to the given output
|
||||
// stream to call the wrapped function. The parameter
|
||||
// values are taken from pexprs, if it is nonempty, or
|
||||
// are assumed to be simply the names of the parameters,
|
||||
// if it is empty.
|
||||
//
|
||||
// The return value is the expression to return, if we
|
||||
// are returning a value, or the empty string if we
|
||||
// return nothing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string WrapperBuilder::
|
||||
call_function(int def_index,
|
||||
ostream &out, int indent_level, bool convert_result,
|
||||
const string &container, const vector_string &pexprs) const {
|
||||
assert(def_index >= 0 && def_index < (int)_def.size());
|
||||
const FunctionDef *def = _def[def_index];
|
||||
|
||||
string return_expr;
|
||||
|
||||
if (def->_type == T_destructor) {
|
||||
// A destructor wrapper is just a wrapper around the delete operator.
|
||||
assert(!container.empty());
|
||||
assert(def->_struct_type != (CPPStructType *)NULL);
|
||||
|
||||
if (TypeManager::is_reference_count(def->_struct_type)) {
|
||||
// Except for a reference-count type object, in which case the
|
||||
// destructor is a wrapper around unref_delete().
|
||||
indent(out, indent_level)
|
||||
<< "unref_delete(" << container << ");\n";
|
||||
} else {
|
||||
indent(out, indent_level)
|
||||
<< "delete " << container << ";\n";
|
||||
}
|
||||
|
||||
} else if (def->_type == T_typecast_method) {
|
||||
// A typecast method can be invoked implicitly.
|
||||
string cast_expr =
|
||||
"(" + def->_return_type->get_orig_type()->get_local_name(&parser) +
|
||||
")(*" + container + ")";
|
||||
|
||||
if (!convert_result) {
|
||||
return_expr = cast_expr;
|
||||
} else {
|
||||
string new_str =
|
||||
def->_return_type->prepare_return_expr(out, indent_level, cast_expr);
|
||||
return_expr = def->_return_type->get_return_expr(new_str);
|
||||
}
|
||||
|
||||
} else if (def->_type == T_typecast) {
|
||||
// A regular typecast converts from a pointer type to another
|
||||
// pointer type. (This is different from the typecast method,
|
||||
// above, which converts from the concrete type to some other
|
||||
// type.)
|
||||
assert(!container.empty());
|
||||
string cast_expr =
|
||||
"(" + def->_return_type->get_orig_type()->get_local_name(&parser) +
|
||||
")" + container;
|
||||
|
||||
if (!convert_result) {
|
||||
return_expr = cast_expr;
|
||||
} else {
|
||||
string new_str =
|
||||
def->_return_type->prepare_return_expr(out, indent_level, cast_expr);
|
||||
return_expr = def->_return_type->get_return_expr(new_str);
|
||||
}
|
||||
|
||||
} else if (def->_type == T_constructor) {
|
||||
// A special case for constructors.
|
||||
return_expr = "new " + get_call_str(def_index, container, pexprs);
|
||||
|
||||
} else if (def->_type == T_assignment_method) {
|
||||
// Another special case for assignment operators.
|
||||
assert(!container.empty());
|
||||
indent(out, indent_level)
|
||||
<< get_call_str(def_index, container, pexprs) << ";\n";
|
||||
|
||||
string this_expr = container;
|
||||
string ref_expr = "*" + this_expr;
|
||||
|
||||
if (!convert_result) {
|
||||
return_expr = ref_expr;
|
||||
} else {
|
||||
string new_str =
|
||||
def->_return_type->prepare_return_expr(out, indent_level, ref_expr);
|
||||
return_expr = def->_return_type->get_return_expr(new_str);
|
||||
|
||||
// Now a simple special-case test. Often, we will have converted
|
||||
// the reference-returning assignment operator to a pointer. In
|
||||
// this case, we might inadventent generate code like "return
|
||||
// &(*this)", when "return this" would do. We check for this here
|
||||
// and undo it as a special case.
|
||||
|
||||
// There's no real good reason to do this, other than that it
|
||||
// feels more satisfying to a casual perusal of the generated
|
||||
// code. It *is* conceivable that some broken compilers wouldn't
|
||||
// like "&(*this)", though.
|
||||
|
||||
if (return_expr == "&(" + ref_expr + ")" ||
|
||||
return_expr == "&" + ref_expr) {
|
||||
return_expr = this_expr;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (def->_void_return) {
|
||||
indent(out, indent_level)
|
||||
<< get_call_str(def_index, container, pexprs) << ";\n";
|
||||
|
||||
} else {
|
||||
string call = get_call_str(def_index, container, pexprs);
|
||||
|
||||
if (!convert_result) {
|
||||
return_expr = get_call_str(def_index, container, pexprs);
|
||||
|
||||
} else {
|
||||
if (def->_return_type->return_value_should_be_simple()) {
|
||||
// We have to assign the result to a temporary first; this makes
|
||||
// it a bit easier on poor old VC++.
|
||||
indent(out, indent_level);
|
||||
def->_return_type->get_orig_type()->output_instance(out, "result",
|
||||
&parser);
|
||||
out << " = " << call << ";\n";
|
||||
|
||||
string new_str =
|
||||
def->_return_type->prepare_return_expr(out, indent_level, "result");
|
||||
return_expr = def->_return_type->get_return_expr(new_str);
|
||||
|
||||
} else {
|
||||
// This should be simple enough that we can return it directly.
|
||||
string new_str =
|
||||
def->_return_type->prepare_return_expr(out, indent_level, call);
|
||||
return_expr = def->_return_type->get_return_expr(new_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return return_expr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::write_spam_message
|
||||
// Access: Protected
|
||||
// Description: Generates the lines of code at the beginning of the
|
||||
// wrapper function that output a message when the
|
||||
// wrapper is called. This is output only if -spam is
|
||||
// specified on the command line.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilder::
|
||||
write_spam_message(int def_index, ostream &out) const {
|
||||
assert(def_index >= 0 && def_index < (int)_def.size());
|
||||
const FunctionDef *def = _def[def_index];
|
||||
|
||||
if (generate_spam) {
|
||||
out << "#ifndef NDEBUG\n"
|
||||
<< " if (in_" << library_name << "_cat.is_spam()) {\n"
|
||||
<< " in_" << library_name << "_cat.spam()\n"
|
||||
<< " << \"";
|
||||
write_quoted_string(out, def->_description);
|
||||
out << "\\n\";\n"
|
||||
<< " }\n"
|
||||
<< "#endif\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::write_quoted_string
|
||||
// Access: Protected
|
||||
// Description: Writes the string to the given output stream, as if
|
||||
// it were quoted within double quotes in a C program.
|
||||
// Specifically, this escapes characters that need to be
|
||||
// escaped, and otherwise leaves the string unchanged.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilder::
|
||||
write_quoted_string(ostream &out, const string &str) const {
|
||||
string::const_iterator si;
|
||||
for (si = str.begin(); si != str.end(); ++si) {
|
||||
switch (*si) {
|
||||
case '\n':
|
||||
out << "\\n";
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
out << "\\t";
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
case '"':
|
||||
out << '\\';
|
||||
// fall through
|
||||
|
||||
default:
|
||||
out << *si;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilder::indent
|
||||
// Access: Public, Static
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ostream &WrapperBuilder::
|
||||
indent(ostream &out, int indent_level) {
|
||||
for (int i = 0; i < indent_level; i++) {
|
||||
out << ' ';
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
// Filename: wrapperBuilder.h
|
||||
// Created by: drose (01Aug00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef WRAPPERBUILDER_H
|
||||
#define WRAPPERBUILDER_H
|
||||
|
||||
#include <dtoolbase.h>
|
||||
|
||||
#include <interrogate_interface.h>
|
||||
#include <vector_string.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
class CPPInstance;
|
||||
class CPPScope;
|
||||
class CPPStructType;
|
||||
class CPPType;
|
||||
class CPPFunctionType;
|
||||
class ParameterRemap;
|
||||
class FunctionWriters;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : WrapperBuilder
|
||||
// Description : Contains all the information necessary to synthesize
|
||||
// a wrapper around a particular function. This
|
||||
// includes choosing appropriate parameter types to
|
||||
// remap from the C++ function's parameter types, as
|
||||
// well as actually generating wrapper code.
|
||||
//
|
||||
// This can wrap just one particular function signature,
|
||||
// or several different function signatures with the
|
||||
// same function name (e.g. function overloading). In
|
||||
// the simple kinds of wrappers, like WrapperBuilderC
|
||||
// and WrapperBuilderPython, this is only intended to
|
||||
// wrap one function signature per wrapper, but wrappers
|
||||
// that can implement function overloading directly
|
||||
// (like WrapperBuilderPythonObj) will store multiple
|
||||
// function signatures and implement all of them within
|
||||
// the same wrapper.
|
||||
//
|
||||
// This is an abstract class; it doesn't actually know
|
||||
// how to choose parameter types and synthesize
|
||||
// wrappers; see WrapperBuilderC and
|
||||
// WrapperBuilderPython.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class WrapperBuilder {
|
||||
public:
|
||||
enum Type {
|
||||
T_normal,
|
||||
T_constructor,
|
||||
T_destructor,
|
||||
T_typecast_method,
|
||||
T_assignment_method,
|
||||
T_typecast,
|
||||
T_getter,
|
||||
T_setter
|
||||
};
|
||||
|
||||
WrapperBuilder();
|
||||
virtual ~WrapperBuilder();
|
||||
|
||||
int add_function(CPPInstance *function, const string &description,
|
||||
CPPStructType *struct_type, CPPScope *scope,
|
||||
const string &function_signature, Type type,
|
||||
const string &expression,
|
||||
int num_default_parameters);
|
||||
|
||||
virtual void get_function_writers(FunctionWriters &writers);
|
||||
|
||||
virtual void
|
||||
write_prototype(ostream &out, const string &wrapper_name) const=0;
|
||||
|
||||
virtual void
|
||||
write_wrapper(ostream &out, const string &wrapper_name) const=0;
|
||||
|
||||
virtual string
|
||||
get_wrapper_name(const string &library_hash_name) const=0;
|
||||
|
||||
virtual bool supports_atomic_strings() const=0;
|
||||
virtual bool synthesize_this_parameter() const;
|
||||
|
||||
enum CallingConvention {
|
||||
CC_c,
|
||||
CC_python,
|
||||
CC_python_obj,
|
||||
};
|
||||
|
||||
virtual CallingConvention get_calling_convention() const=0;
|
||||
|
||||
class Parameter {
|
||||
public:
|
||||
bool _has_name;
|
||||
string _name;
|
||||
ParameterRemap *_remap;
|
||||
};
|
||||
|
||||
typedef vector<Parameter> Parameters;
|
||||
|
||||
class FunctionDef {
|
||||
public:
|
||||
FunctionDef();
|
||||
~FunctionDef();
|
||||
private:
|
||||
FunctionDef(const FunctionDef ©);
|
||||
void operator = (const FunctionDef ©);
|
||||
|
||||
public:
|
||||
Parameters _parameters;
|
||||
ParameterRemap *_return_type;
|
||||
bool _void_return;
|
||||
bool _has_this;
|
||||
bool _is_method;
|
||||
Type _type;
|
||||
|
||||
CPPInstance *_function;
|
||||
string _description;
|
||||
CPPStructType *_struct_type;
|
||||
CPPScope *_scope;
|
||||
CPPFunctionType *_ftype;
|
||||
string _function_signature;
|
||||
string _expression;
|
||||
int _num_default_parameters;
|
||||
|
||||
bool _return_value_needs_management;
|
||||
FunctionIndex _return_value_destructor;
|
||||
bool _manage_reference_count;
|
||||
};
|
||||
|
||||
typedef vector<FunctionDef *> Def;
|
||||
Def _def;
|
||||
|
||||
string _hash;
|
||||
int _wrapper_index;
|
||||
bool _is_valid;
|
||||
|
||||
protected:
|
||||
virtual ParameterRemap *make_remap(int def_index, CPPType *orig_type);
|
||||
string manage_return_value(int def_index,
|
||||
ostream &out, int indent_level,
|
||||
const string &return_expr) const;
|
||||
void output_ref(int def_index, ostream &out, int indent_level, const string &varname) const;
|
||||
|
||||
string get_parameter_name(int n) const;
|
||||
string get_parameter_expr(int n, const vector_string &pexprs) const;
|
||||
|
||||
string get_call_str(int def_index,
|
||||
const string &container,
|
||||
const vector_string &pexprs) const;
|
||||
string call_function(int def_index,
|
||||
ostream &out, int indent_level,
|
||||
bool convert_result, const string &container,
|
||||
const vector_string &pexprs = vector_string()) const;
|
||||
|
||||
void write_spam_message(int def_index, ostream &out) const;
|
||||
void write_quoted_string(ostream &out, const string &str) const;
|
||||
|
||||
public:
|
||||
static ostream &indent(ostream &out, int indent_level);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,171 +0,0 @@
|
||||
// Filename: wrapperBuilderC.cxx
|
||||
// Created by: drose (06Aug00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "wrapperBuilderC.h"
|
||||
#include "interrogate.h"
|
||||
#include "parameterRemap.h"
|
||||
|
||||
#include <interrogateDatabase.h>
|
||||
#include <cppInstance.h>
|
||||
#include <cppFunctionType.h>
|
||||
#include <cppParameterList.h>
|
||||
#include <cppConstType.h>
|
||||
#include <cppReferenceType.h>
|
||||
#include <cppPointerType.h>
|
||||
#include <cppSimpleType.h>
|
||||
#include <cppStructType.h>
|
||||
#include <notify.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderC::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WrapperBuilderC::
|
||||
WrapperBuilderC() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderC::write_prototype
|
||||
// Access: Public, Virtual
|
||||
// Description: Generates the prototype for the wrapper function(s).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilderC::
|
||||
write_prototype(ostream &out, const string &wrapper_name) const {
|
||||
for (int def_index = 0; def_index < (int)_def.size(); ++def_index) {
|
||||
const FunctionDef *def = _def[def_index];
|
||||
|
||||
if (!output_function_names) {
|
||||
// If we're not saving the function names, don't export it from
|
||||
// the library.
|
||||
out << "static ";
|
||||
} else {
|
||||
out << "extern \"C\" ";
|
||||
}
|
||||
|
||||
if (def->_void_return) {
|
||||
out << "void " << wrapper_name;
|
||||
} else {
|
||||
def->_return_type->get_new_type()->output_instance(out, wrapper_name, &parser);
|
||||
}
|
||||
|
||||
out << "(";
|
||||
int pn = 0;
|
||||
if (pn < (int)def->_parameters.size()) {
|
||||
def->_parameters[pn]._remap->get_new_type()->
|
||||
output_instance(out, get_parameter_name(pn), &parser);
|
||||
pn++;
|
||||
while (pn < (int)def->_parameters.size()) {
|
||||
out << ", ";
|
||||
def->_parameters[pn]._remap->get_new_type()->
|
||||
output_instance(out, get_parameter_name(pn), &parser);
|
||||
pn++;
|
||||
}
|
||||
}
|
||||
out << ");\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderC::write_wrapper
|
||||
// Access: Public, Virtual
|
||||
// Description: Generates a wrapper function to the indicated output
|
||||
// stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilderC::
|
||||
write_wrapper(ostream &out, const string &wrapper_name) const {
|
||||
for (int def_index = 0; def_index < (int)_def.size(); ++def_index) {
|
||||
const FunctionDef *def = _def[def_index];
|
||||
|
||||
out << "/*\n"
|
||||
<< " * C wrapper for\n"
|
||||
<< " * " << def->_description << "\n"
|
||||
<< " */\n";
|
||||
|
||||
if (!output_function_names) {
|
||||
// If we're not saving the function names, don't export it from
|
||||
// the library.
|
||||
out << "static ";
|
||||
}
|
||||
|
||||
if (def->_void_return) {
|
||||
out << "void\n";
|
||||
} else {
|
||||
out << def->_return_type->get_new_type()->get_local_name(&parser) << "\n";
|
||||
}
|
||||
|
||||
out << wrapper_name << "(";
|
||||
int pn = 0;
|
||||
if (pn < (int)def->_parameters.size()) {
|
||||
def->_parameters[pn]._remap->get_new_type()->
|
||||
output_instance(out, get_parameter_name(pn), &parser);
|
||||
pn++;
|
||||
while (pn < (int)def->_parameters.size()) {
|
||||
out << ", ";
|
||||
def->_parameters[pn]._remap->get_new_type()->
|
||||
output_instance(out, get_parameter_name(pn), &parser);
|
||||
pn++;
|
||||
}
|
||||
}
|
||||
out << ") {\n";
|
||||
|
||||
write_spam_message(def_index, out);
|
||||
|
||||
string return_expr = call_function(def_index, out, 2, true, "param0");
|
||||
return_expr = manage_return_value(def_index, out, 2, return_expr);
|
||||
if (!return_expr.empty()) {
|
||||
out << " return " << return_expr << ";\n";
|
||||
}
|
||||
|
||||
out << "}\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderC::get_wrapper_name
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the callable name for this wrapper function.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string WrapperBuilderC::
|
||||
get_wrapper_name(const string &library_hash_name) const {
|
||||
return "_inC" + library_hash_name + _hash;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderC::supports_atomic_strings
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if this kind of wrapper can support true
|
||||
// atomic string objects (and not have to fiddle with
|
||||
// char *).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool WrapperBuilderC::
|
||||
supports_atomic_strings() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderC::get_calling_convention
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns an indication of what kind of function we are
|
||||
// building.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WrapperBuilder::CallingConvention WrapperBuilderC::
|
||||
get_calling_convention() const {
|
||||
return CC_c;
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
// Filename: wrapperBuilderC.h
|
||||
// Created by: drose (06Aug00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef WRAPPERBUILDERC_H
|
||||
#define WRAPPERBUILDERC_H
|
||||
|
||||
#include <dtoolbase.h>
|
||||
|
||||
#include "wrapperBuilder.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : WrapperBuilderC
|
||||
// Description : A specialization on WrapperBuilder that builds
|
||||
// C-style wrapper functions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class WrapperBuilderC : public WrapperBuilder {
|
||||
public:
|
||||
WrapperBuilderC();
|
||||
|
||||
virtual void
|
||||
write_prototype(ostream &out, const string &wrapper_name) const;
|
||||
|
||||
virtual void
|
||||
write_wrapper(ostream &out, const string &wrapper_name) const;
|
||||
|
||||
virtual string
|
||||
get_wrapper_name(const string &library_hash_name) const;
|
||||
|
||||
virtual bool supports_atomic_strings() const;
|
||||
virtual CallingConvention get_calling_convention() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,330 +0,0 @@
|
||||
// Filename: wrapperBuilderPython.cxx
|
||||
// Created by: drose (07Aug00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "wrapperBuilderPython.h"
|
||||
#include "interrogate.h"
|
||||
#include "parameterRemap.h"
|
||||
#include "typeManager.h"
|
||||
|
||||
#include <interrogateDatabase.h>
|
||||
#include <cppInstance.h>
|
||||
#include <cppFunctionType.h>
|
||||
#include <cppParameterList.h>
|
||||
#include <cppConstType.h>
|
||||
#include <cppReferenceType.h>
|
||||
#include <cppPointerType.h>
|
||||
#include <cppSimpleType.h>
|
||||
#include <cppStructType.h>
|
||||
#include <cppExpression.h>
|
||||
#include <notify.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPython::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WrapperBuilderPython::
|
||||
WrapperBuilderPython() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPython::write_prototype
|
||||
// Access: Public, Virtual
|
||||
// Description: Generates the prototype for the wrapper function(s).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilderPython::
|
||||
write_prototype(ostream &out, const string &wrapper_name) const {
|
||||
if (!output_function_names) {
|
||||
// If we're not saving the function names, don't export it from
|
||||
// the library.
|
||||
out << "static ";
|
||||
} else {
|
||||
out << "extern \"C\" ";
|
||||
}
|
||||
|
||||
out << "PyObject *"
|
||||
<< wrapper_name << "(PyObject *, PyObject *args);\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPython::write_wrapper
|
||||
// Access: Public, Virtual
|
||||
// Description: Generates a wrapper function to the indicated output
|
||||
// stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilderPython::
|
||||
write_wrapper(ostream &out, const string &wrapper_name) const {
|
||||
for (int def_index = 0; def_index < (int)_def.size(); ++def_index) {
|
||||
const FunctionDef *def = _def[def_index];
|
||||
|
||||
out << "/*\n"
|
||||
<< " * Python simple wrapper for\n"
|
||||
<< " * " << def->_description << "\n"
|
||||
<< " */\n";
|
||||
|
||||
if (!output_function_names) {
|
||||
// If we're not saving the function names, don't export it from
|
||||
// the library.
|
||||
out << "static ";
|
||||
}
|
||||
|
||||
out << "PyObject *\n"
|
||||
<< wrapper_name << "(PyObject *, PyObject *args) {\n";
|
||||
|
||||
write_spam_message(def_index, out);
|
||||
|
||||
int pn;
|
||||
|
||||
string format_specifiers;
|
||||
string parameter_list;
|
||||
string container;
|
||||
vector_string pexprs;
|
||||
|
||||
// Make one pass through the parameter list. We will output a
|
||||
// one-line temporary variable definition for each parameter, while
|
||||
// simultaneously building the ParseTuple() function call and also
|
||||
// the parameter expression list for call_function().
|
||||
for (pn = 0; pn < (int)def->_parameters.size(); pn++) {
|
||||
out << " ";
|
||||
CPPType *orig_type = def->_parameters[pn]._remap->get_orig_type();
|
||||
CPPType *type = def->_parameters[pn]._remap->get_new_type();
|
||||
|
||||
// This is the string to convert our local variable to the
|
||||
// appropriate C++ type. Normally this is just a cast.
|
||||
string pexpr_string =
|
||||
"(" + type->get_local_name(&parser) + ")" + get_parameter_name(pn);
|
||||
|
||||
if (def->_parameters[pn]._remap->new_type_is_atomic_string()) {
|
||||
if (TypeManager::is_char_pointer(orig_type)) {
|
||||
out << "char *" << get_parameter_name(pn);
|
||||
format_specifiers += "s";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
|
||||
} else {
|
||||
out << "char *" << get_parameter_name(pn)
|
||||
<< "_str; int " << get_parameter_name(pn) << "_len";
|
||||
format_specifiers += "s#";
|
||||
parameter_list += ", &" + get_parameter_name(pn)
|
||||
+ "_str, &" + get_parameter_name(pn) + "_len";
|
||||
pexpr_string = "basic_string<char>(" +
|
||||
get_parameter_name(pn) + "_str, " +
|
||||
get_parameter_name(pn) + "_len)";
|
||||
}
|
||||
|
||||
} else if (TypeManager::is_bool(type)) {
|
||||
out << "PyObject *" << get_parameter_name(pn);
|
||||
format_specifiers += "O";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
pexpr_string = "(PyObject_IsTrue(" + get_parameter_name(pn) + ")!=0)";
|
||||
|
||||
} else if (TypeManager::is_integer(type)) {
|
||||
out << "int " << get_parameter_name(pn);
|
||||
format_specifiers += "i";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
|
||||
} else if (TypeManager::is_float(type)) {
|
||||
out << "double " << get_parameter_name(pn);
|
||||
format_specifiers += "d";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
|
||||
} else if (TypeManager::is_char_pointer(type)) {
|
||||
out << "char *" << get_parameter_name(pn);
|
||||
format_specifiers += "s";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
|
||||
} else if (TypeManager::is_pointer(type)) {
|
||||
out << "int " << get_parameter_name(pn);
|
||||
format_specifiers += "i";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
|
||||
} else {
|
||||
// Ignore a parameter.
|
||||
out << "PyObject *" << get_parameter_name(pn);
|
||||
format_specifiers += "O";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
}
|
||||
|
||||
out << ";\n";
|
||||
if (def->_has_this && pn == 0) {
|
||||
// The "this" parameter gets passed in separately.
|
||||
container = pexpr_string;
|
||||
}
|
||||
pexprs.push_back(pexpr_string);
|
||||
}
|
||||
|
||||
out << " if (PyArg_ParseTuple(args, \"" << format_specifiers
|
||||
<< "\"" << parameter_list << ")) {\n";
|
||||
|
||||
if (track_interpreter) {
|
||||
out << " in_interpreter = 0;\n";
|
||||
}
|
||||
|
||||
if (def->_return_type->new_type_is_atomic_string()) {
|
||||
// Treat strings as a special case. We don't want to format the
|
||||
// return expression.
|
||||
string return_expr = call_function(def_index,
|
||||
out, 4, false, container, pexprs);
|
||||
|
||||
CPPType *type = def->_return_type->get_orig_type();
|
||||
out << " ";
|
||||
type->output_instance(out, "return_value", &parser);
|
||||
out << " = " << return_expr << ";\n";
|
||||
|
||||
if (track_interpreter) {
|
||||
out << " in_interpreter = 1;\n";
|
||||
}
|
||||
|
||||
return_expr = manage_return_value(def_index, out, 4, "return_value");
|
||||
test_assert(out, 4);
|
||||
pack_return_value(def_index, out, return_expr);
|
||||
|
||||
} else {
|
||||
string return_expr = call_function(def_index,
|
||||
out, 4, true, container, pexprs);
|
||||
if (return_expr.empty()) {
|
||||
if (track_interpreter) {
|
||||
out << " in_interpreter = 1;\n";
|
||||
}
|
||||
test_assert(out, 4);
|
||||
out << " return Py_BuildValue(\"\");\n";
|
||||
|
||||
} else {
|
||||
CPPType *type = def->_return_type->get_temporary_type();
|
||||
out << " ";
|
||||
type->output_instance(out, "return_value", &parser);
|
||||
out << " = " << return_expr << ";\n";
|
||||
if (track_interpreter) {
|
||||
out << " in_interpreter = 1;\n";
|
||||
}
|
||||
|
||||
return_expr = manage_return_value(def_index, out, 4, "return_value");
|
||||
test_assert(out, 4);
|
||||
pack_return_value(def_index, out, def->_return_type->temporary_to_return(return_expr));
|
||||
}
|
||||
}
|
||||
|
||||
out << " }\n";
|
||||
|
||||
out << " return (PyObject *)NULL;\n";
|
||||
out << "}\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPython::get_wrapper_name
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the callable name for this wrapper function.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string WrapperBuilderPython::
|
||||
get_wrapper_name(const string &library_hash_name) const {
|
||||
return "_inP" + library_hash_name + _hash;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPython::supports_atomic_strings
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if this kind of wrapper can support true
|
||||
// atomic string objects (and not have to fiddle with
|
||||
// char *).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool WrapperBuilderPython::
|
||||
supports_atomic_strings() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPython::get_calling_convention
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns an indication of what kind of function we are
|
||||
// building.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WrapperBuilder::CallingConvention WrapperBuilderPython::
|
||||
get_calling_convention() const {
|
||||
return CC_python;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPython::test_assert
|
||||
// Access: Protected
|
||||
// Description: Outputs code to check to see if an assertion has
|
||||
// failed while the C++ code was executing, and report
|
||||
// this failure back to Python.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilderPython::
|
||||
test_assert(ostream &out, int indent_level) const {
|
||||
if (watch_asserts) {
|
||||
out << "#ifndef NDEBUG\n";
|
||||
indent(out, indent_level)
|
||||
<< "Notify *notify = Notify::ptr();\n";
|
||||
indent(out, indent_level)
|
||||
<< "if (notify->has_assert_failed()) {\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< "PyErr_SetString(PyExc_AssertionError, notify->get_assert_error_message().c_str());\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< "notify->clear_assert_failed();\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< "return (PyObject *)NULL;\n";
|
||||
indent(out, indent_level)
|
||||
<< "}\n";
|
||||
out << "#endif\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPython::pack_return_value
|
||||
// Access: Protected
|
||||
// Description: Outputs a command to pack the indicated expression,
|
||||
// of the return_type type, as a Python return value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilderPython::
|
||||
pack_return_value(int def_index, ostream &out, string return_expr) const {
|
||||
assert(def_index >= 0 && def_index < (int)_def.size());
|
||||
const FunctionDef *def = _def[def_index];
|
||||
|
||||
CPPType *orig_type = def->_return_type->get_orig_type();
|
||||
CPPType *type = def->_return_type->get_new_type();
|
||||
|
||||
out << " return Py_BuildValue(";
|
||||
|
||||
if (def->_return_type->new_type_is_atomic_string()) {
|
||||
if (TypeManager::is_char_pointer(orig_type)) {
|
||||
out << "\"s\", " << return_expr;
|
||||
|
||||
} else {
|
||||
out << "\"s#\", " << return_expr << ".data(), "
|
||||
<< return_expr << ".length()";
|
||||
}
|
||||
|
||||
} else if (TypeManager::is_integer(type)) {
|
||||
out << "\"i\", (int)(" << return_expr << ")";
|
||||
|
||||
} else if (TypeManager::is_float(type)) {
|
||||
out << "\"d\", (double)(" << return_expr << ")";
|
||||
|
||||
} else if (TypeManager::is_char_pointer(type)) {
|
||||
out << "\"s\", " << return_expr;
|
||||
|
||||
} else if (TypeManager::is_pointer(type)) {
|
||||
out << "\"i\", (int)" << return_expr;
|
||||
|
||||
} else {
|
||||
// Return None.
|
||||
out << "\"\"";
|
||||
}
|
||||
out << ");\n";
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
// Filename: wrapperBuilderPython.h
|
||||
// Created by: drose (07Aug00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef WRAPPERBUILDERPYTHON_H
|
||||
#define WRAPPERBUILDERPYTHON_H
|
||||
|
||||
#include <dtoolbase.h>
|
||||
|
||||
#include "wrapperBuilder.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : WrapperBuilderPython
|
||||
// Description : A specialization on WrapperBuilder that builds
|
||||
// simple Python wrapper functions, simple functions
|
||||
// that call C++ methods directly given a handle and a
|
||||
// set of parameters.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class WrapperBuilderPython : public WrapperBuilder {
|
||||
public:
|
||||
WrapperBuilderPython();
|
||||
|
||||
virtual void
|
||||
write_prototype(ostream &out, const string &wrapper_name) const;
|
||||
|
||||
virtual void
|
||||
write_wrapper(ostream &out, const string &wrapper_name) const;
|
||||
|
||||
virtual string
|
||||
get_wrapper_name(const string &library_hash_name) const;
|
||||
|
||||
virtual bool supports_atomic_strings() const;
|
||||
virtual CallingConvention get_calling_convention() const;
|
||||
|
||||
protected:
|
||||
void test_assert(ostream &out, int indent_level) const;
|
||||
void pack_return_value(int def_index, ostream &out, string return_expr) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,458 +0,0 @@
|
||||
// Filename: wrapperBuilderPythonObj.cxx
|
||||
// Created by: drose (11Sep01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "wrapperBuilderPythonObj.h"
|
||||
#include "interrogate.h"
|
||||
#include "parameterRemap.h"
|
||||
#include "typeManager.h"
|
||||
#include "functionWriterPtrFromPython.h"
|
||||
#include "functionWriterPtrToPython.h"
|
||||
#include "functionWriters.h"
|
||||
|
||||
#include <interrogateDatabase.h>
|
||||
#include <cppInstance.h>
|
||||
#include <cppFunctionType.h>
|
||||
#include <cppParameterList.h>
|
||||
#include <cppConstType.h>
|
||||
#include <cppReferenceType.h>
|
||||
#include <cppPointerType.h>
|
||||
#include <cppSimpleType.h>
|
||||
#include <cppStructType.h>
|
||||
#include <cppExpression.h>
|
||||
#include <notify.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPythonObj::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WrapperBuilderPythonObj::
|
||||
WrapperBuilderPythonObj() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPythonObj::get_function_writers
|
||||
// Access: Public, Virtual
|
||||
// Description: Adds whatever list of FunctionWriters might be needed
|
||||
// for this particular WrapperBuilder. These will be
|
||||
// generated to the output source file before
|
||||
// write_wrapper() is called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilderPythonObj::
|
||||
get_function_writers(FunctionWriters &writers) {
|
||||
for (int def_index = 0; def_index < (int)_def.size(); ++def_index) {
|
||||
const FunctionDef *def = _def[def_index];
|
||||
|
||||
if (def->_is_method) {
|
||||
FunctionWriterPtrFromPython *writer =
|
||||
new FunctionWriterPtrFromPython(def->_struct_type);
|
||||
writers.add_writer(writer);
|
||||
}
|
||||
|
||||
int pn;
|
||||
for (pn = 0; pn < (int)def->_parameters.size(); pn++) {
|
||||
CPPType *type = def->_parameters[pn]._remap->get_new_type();
|
||||
|
||||
if (def->_parameters[pn]._remap->new_type_is_atomic_string()) {
|
||||
} else if (TypeManager::is_bool(type)) {
|
||||
} else if (TypeManager::is_integer(type)) {
|
||||
} else if (TypeManager::is_float(type)) {
|
||||
} else if (TypeManager::is_char_pointer(type)) {
|
||||
|
||||
} else if (TypeManager::is_pointer(type)) {
|
||||
FunctionWriterPtrFromPython *writer =
|
||||
new FunctionWriterPtrFromPython(type);
|
||||
writers.add_writer(writer);
|
||||
}
|
||||
}
|
||||
|
||||
CPPType *type = def->_return_type->get_new_type();
|
||||
if (def->_return_type->new_type_is_atomic_string()) {
|
||||
} else if (TypeManager::is_integer(type)) {
|
||||
} else if (TypeManager::is_float(type)) {
|
||||
} else if (TypeManager::is_char_pointer(type)) {
|
||||
|
||||
} else if (TypeManager::is_pointer(type)) {
|
||||
FunctionWriterPtrToPython *writer =
|
||||
new FunctionWriterPtrToPython(type);
|
||||
writers.add_writer(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPythonObj::write_prototype
|
||||
// Access: Public, Virtual
|
||||
// Description: Generates the prototype for the wrapper function(s).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilderPythonObj::
|
||||
write_prototype(ostream &out, const string &wrapper_name) const {
|
||||
if (!output_function_names) {
|
||||
// If we're not saving the function names, don't export it from
|
||||
// the library.
|
||||
out << "static ";
|
||||
} else {
|
||||
out << "extern \"C\" ";
|
||||
}
|
||||
|
||||
out << "PyObject *"
|
||||
<< wrapper_name << "(PyObject *self, PyObject *args);\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPythonObj::write_wrapper
|
||||
// Access: Public, Virtual
|
||||
// Description: Generates a wrapper function to the indicated output
|
||||
// stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilderPythonObj::
|
||||
write_wrapper(ostream &out, const string &wrapper_name) const {
|
||||
bool any_is_method = false;
|
||||
|
||||
out << "/*\n"
|
||||
<< " * Python object wrapper for\n";
|
||||
|
||||
int def_index;
|
||||
for (def_index = 0; def_index < (int)_def.size(); ++def_index) {
|
||||
const FunctionDef *def = _def[def_index];
|
||||
out << " * " << def->_description << "\n";
|
||||
if (def->_is_method) {
|
||||
any_is_method = true;
|
||||
}
|
||||
}
|
||||
out << " */\n";
|
||||
|
||||
if (!output_function_names) {
|
||||
// If we're not saving the function names, don't export it from
|
||||
// the library.
|
||||
out << "static ";
|
||||
}
|
||||
|
||||
if (any_is_method) {
|
||||
out << "PyObject *\n"
|
||||
<< wrapper_name << "(PyObject *self, PyObject *args) {\n";
|
||||
} else {
|
||||
out << "PyObject *\n"
|
||||
<< wrapper_name << "(PyObject *, PyObject *args) {\n";
|
||||
}
|
||||
|
||||
write_spam_message(0, out);
|
||||
string expected_params = "Arguments must match one of:";
|
||||
|
||||
for (def_index = 0; def_index < (int)_def.size(); ++def_index) {
|
||||
const FunctionDef *def = _def[def_index];
|
||||
out << " {\n"
|
||||
<< " /* " << def->_description << " */\n"
|
||||
<< "\n";
|
||||
|
||||
string thisptr;
|
||||
if (def->_is_method) {
|
||||
// Declare a "thisptr" variable.
|
||||
thisptr = "thisptr";
|
||||
FunctionWriterPtrFromPython *writer =
|
||||
new FunctionWriterPtrFromPython(def->_struct_type);
|
||||
out << " ";
|
||||
writer->get_pointer_type()->output_instance(out, thisptr, &parser);
|
||||
out << ";\n"
|
||||
<< " if (!" << writer->get_name() << "(self, &thisptr)) {\n"
|
||||
<< " return (PyObject *)NULL;\n"
|
||||
<< " }\n";
|
||||
delete writer;
|
||||
}
|
||||
|
||||
string format_specifiers;
|
||||
string parameter_list;
|
||||
vector_string pexprs;
|
||||
|
||||
// Make one pass through the parameter list. We will output a
|
||||
// one-line temporary variable definition for each parameter, while
|
||||
// simultaneously building the ParseTuple() function call and also
|
||||
// the parameter expression list for call_function().
|
||||
|
||||
expected_params += "\\n ";
|
||||
expected_params += _def[0]->_function->get_simple_name();
|
||||
expected_params += "(";
|
||||
|
||||
int pn;
|
||||
for (pn = 0; pn < (int)def->_parameters.size(); pn++) {
|
||||
if (pn != 0) {
|
||||
expected_params += ", ";
|
||||
}
|
||||
|
||||
out << " ";
|
||||
CPPType *orig_type = def->_parameters[pn]._remap->get_orig_type();
|
||||
CPPType *type = def->_parameters[pn]._remap->get_new_type();
|
||||
|
||||
// This is the string to convert our local variable to the
|
||||
// appropriate C++ type. Normally this is just a cast.
|
||||
string pexpr_string =
|
||||
"(" + type->get_local_name(&parser) + ")" + get_parameter_name(pn);
|
||||
|
||||
if (def->_parameters[pn]._remap->new_type_is_atomic_string()) {
|
||||
if (TypeManager::is_char_pointer(orig_type)) {
|
||||
out << "char *" << get_parameter_name(pn);
|
||||
format_specifiers += "s";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
|
||||
} else {
|
||||
out << "char *" << get_parameter_name(pn)
|
||||
<< "_str; int " << get_parameter_name(pn) << "_len";
|
||||
format_specifiers += "s#";
|
||||
parameter_list += ", &" + get_parameter_name(pn)
|
||||
+ "_str, &" + get_parameter_name(pn) + "_len";
|
||||
pexpr_string = "basic_string<char>(" +
|
||||
get_parameter_name(pn) + "_str, " +
|
||||
get_parameter_name(pn) + "_len)";
|
||||
}
|
||||
expected_params += "string";
|
||||
|
||||
} else if (TypeManager::is_bool(type)) {
|
||||
out << "PyObject *" << get_parameter_name(pn);
|
||||
format_specifiers += "O";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
pexpr_string = "(PyObject_IsTrue(" + get_parameter_name(pn) + ")!=0)";
|
||||
expected_params += "bool";
|
||||
|
||||
} else if (TypeManager::is_integer(type)) {
|
||||
out << "int " << get_parameter_name(pn);
|
||||
format_specifiers += "i";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
expected_params += "integer";
|
||||
|
||||
} else if (TypeManager::is_float(type)) {
|
||||
out << "double " << get_parameter_name(pn);
|
||||
format_specifiers += "d";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
expected_params += "float";
|
||||
|
||||
} else if (TypeManager::is_char_pointer(type)) {
|
||||
out << "char *" << get_parameter_name(pn);
|
||||
format_specifiers += "s";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
expected_params += "string";
|
||||
|
||||
} else if (TypeManager::is_pointer(type)) {
|
||||
out << "int " << get_parameter_name(pn);
|
||||
format_specifiers += "i";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
expected_params += "pointer";
|
||||
|
||||
} else {
|
||||
// Ignore a parameter.
|
||||
out << "PyObject *" << get_parameter_name(pn);
|
||||
format_specifiers += "O";
|
||||
parameter_list += ", &" + get_parameter_name(pn);
|
||||
expected_params += "ignored";
|
||||
}
|
||||
|
||||
if (def->_parameters[pn]._has_name) {
|
||||
expected_params += " " + def->_parameters[pn]._name;
|
||||
}
|
||||
|
||||
out << ";\n";
|
||||
pexprs.push_back(pexpr_string);
|
||||
}
|
||||
expected_params += ")";
|
||||
|
||||
out << " if (PyArg_ParseTuple(args, \"" << format_specifiers
|
||||
<< "\"" << parameter_list << ")) {\n";
|
||||
|
||||
if (track_interpreter) {
|
||||
out << " in_interpreter = 0;\n";
|
||||
}
|
||||
|
||||
if (def->_return_type->new_type_is_atomic_string()) {
|
||||
// Treat strings as a special case. We don't want to format the
|
||||
// return expression.
|
||||
string return_expr = call_function(def_index,
|
||||
out, 6, false, thisptr, pexprs);
|
||||
|
||||
CPPType *type = def->_return_type->get_orig_type();
|
||||
out << " ";
|
||||
type->output_instance(out, "return_value", &parser);
|
||||
out << " = " << return_expr << ";\n";
|
||||
|
||||
if (track_interpreter) {
|
||||
out << " in_interpreter = 1;\n";
|
||||
}
|
||||
|
||||
return_expr = manage_return_value(def_index, out, 6, "return_value");
|
||||
test_assert(out, 6);
|
||||
pack_return_value(def_index, out, return_expr);
|
||||
|
||||
} else {
|
||||
string return_expr = call_function(def_index,
|
||||
out, 6, true, thisptr, pexprs);
|
||||
if (return_expr.empty()) {
|
||||
if (track_interpreter) {
|
||||
out << " in_interpreter = 1;\n";
|
||||
}
|
||||
test_assert(out, 6);
|
||||
out << " return Py_BuildValue(\"\");\n";
|
||||
|
||||
} else {
|
||||
CPPType *type = def->_return_type->get_temporary_type();
|
||||
out << " ";
|
||||
type->output_instance(out, "return_value", &parser);
|
||||
out << " = " << return_expr << ";\n";
|
||||
if (track_interpreter) {
|
||||
out << " in_interpreter = 1;\n";
|
||||
}
|
||||
|
||||
return_expr = manage_return_value(def_index, out, 6, "return_value");
|
||||
test_assert(out, 6);
|
||||
pack_return_value(def_index, out, def->_return_type->temporary_to_return(return_expr));
|
||||
}
|
||||
}
|
||||
|
||||
out << " }\n"
|
||||
<< " PyErr_Clear();\n" // Clear the error generated by ParseTuple()
|
||||
<< " }\n";
|
||||
}
|
||||
|
||||
// Invalid parameters. Generate an error exception. (We don't rely
|
||||
// on the error already generated by ParseTuple(), because it only
|
||||
// reports the error for one flavor of the function, whereas we
|
||||
// might accept multiple flavors for the different overloaded
|
||||
// C++ function signatures.
|
||||
|
||||
out << " PyErr_SetString(PyExc_TypeError, \"" << expected_params << "\");\n"
|
||||
<< " return (PyObject *)NULL;\n";
|
||||
out << "}\n\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPythonObj::get_wrapper_name
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the callable name for this wrapper function.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string WrapperBuilderPythonObj::
|
||||
get_wrapper_name(const string &library_hash_name) const {
|
||||
return "_inM" + library_hash_name + _hash;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPythonObj::supports_atomic_strings
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if this kind of wrapper can support true
|
||||
// atomic string objects (and not have to fiddle with
|
||||
// char *).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool WrapperBuilderPythonObj::
|
||||
supports_atomic_strings() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPythonObj::synthesize_this_parameter
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if this particular wrapper type requires
|
||||
// an explicit "this" parameter to be added to the
|
||||
// function parameter list when appropriate, or false if
|
||||
// the "this" pointer will come through a different
|
||||
// channel.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool WrapperBuilderPythonObj::
|
||||
synthesize_this_parameter() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPythonObj::get_calling_convention
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns an indication of what kind of function we are
|
||||
// building.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WrapperBuilder::CallingConvention WrapperBuilderPythonObj::
|
||||
get_calling_convention() const {
|
||||
return CC_python_obj;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPythonObj::test_assert
|
||||
// Access: Protected
|
||||
// Description: Outputs code to check to see if an assertion has
|
||||
// failed while the C++ code was executing, and report
|
||||
// this failure back to Python.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilderPythonObj::
|
||||
test_assert(ostream &out, int indent_level) const {
|
||||
if (watch_asserts) {
|
||||
out << "#ifndef NDEBUG\n";
|
||||
indent(out, indent_level)
|
||||
<< "Notify *notify = Notify::ptr();\n";
|
||||
indent(out, indent_level)
|
||||
<< "if (notify->has_assert_failed()) {\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< "PyErr_SetString(PyExc_AssertionError, notify->get_assert_error_message().c_str());\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< "notify->clear_assert_failed();\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< "return (PyObject *)NULL;\n";
|
||||
indent(out, indent_level)
|
||||
<< "}\n";
|
||||
out << "#endif\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapperBuilderPythonObj::pack_return_value
|
||||
// Access: Protected
|
||||
// Description: Outputs a command to pack the indicated expression,
|
||||
// of the return_type type, as a Python return value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WrapperBuilderPythonObj::
|
||||
pack_return_value(int def_index, ostream &out, string return_expr) const {
|
||||
assert(def_index >= 0 && def_index < (int)_def.size());
|
||||
const FunctionDef *def = _def[def_index];
|
||||
|
||||
CPPType *orig_type = def->_return_type->get_orig_type();
|
||||
CPPType *type = def->_return_type->get_new_type();
|
||||
|
||||
if (def->_return_type->new_type_is_atomic_string()) {
|
||||
if (TypeManager::is_char_pointer(orig_type)) {
|
||||
out << " return PyString_FromString(" << return_expr << ");\n";
|
||||
|
||||
} else {
|
||||
out << " return PyString_FromStringAndSize("
|
||||
<< return_expr << ".data(), " << return_expr << ".length());\n";
|
||||
}
|
||||
|
||||
} else if (TypeManager::is_integer(type)) {
|
||||
out << " return PyInt_FromLong("
|
||||
<< return_expr << ");\n";
|
||||
|
||||
} else if (TypeManager::is_float(type)) {
|
||||
out << " return PyFloat_FromDouble("
|
||||
<< return_expr << ");\n";
|
||||
|
||||
} else if (TypeManager::is_char_pointer(type)) {
|
||||
out << " return PyString_FromString(" << return_expr << ");\n";
|
||||
|
||||
} else if (TypeManager::is_pointer(type)) {
|
||||
bool caller_manages = def->_return_value_needs_management;
|
||||
FunctionWriterPtrToPython *writer =
|
||||
new FunctionWriterPtrToPython(type);
|
||||
out << " return " << writer->get_name() << "(" << return_expr
|
||||
<< ", " << caller_manages << ");\n";
|
||||
|
||||
} else {
|
||||
// Return None.
|
||||
out << " return Py_BuildValue(\"\");\n";
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
// Filename: wrapperBuilderPythonObj.h
|
||||
// Created by: drose (11Sep01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef WRAPPERBUILDERPYTHONOBJ_H
|
||||
#define WRAPPERBUILDERPYTHONOBJ_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
#include "wrapperBuilder.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : WrapperBuilderPythonObj
|
||||
// Description : A specialization on WrapperBuilder that builds
|
||||
// sophisticated Python wrapper functions that get
|
||||
// assembled into Python methods, and make the C++
|
||||
// objects appeart directly as Python objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class WrapperBuilderPythonObj : public WrapperBuilder {
|
||||
public:
|
||||
WrapperBuilderPythonObj();
|
||||
|
||||
virtual void get_function_writers(FunctionWriters &writers);
|
||||
|
||||
virtual void
|
||||
write_prototype(ostream &out, const string &wrapper_name) const;
|
||||
|
||||
virtual void
|
||||
write_wrapper(ostream &out, const string &wrapper_name) const;
|
||||
|
||||
virtual string
|
||||
get_wrapper_name(const string &library_hash_name) const;
|
||||
|
||||
virtual bool supports_atomic_strings() const;
|
||||
virtual bool synthesize_this_parameter() const;
|
||||
virtual CallingConvention get_calling_convention() const;
|
||||
|
||||
protected:
|
||||
void test_assert(ostream &out, int indent_level) const;
|
||||
void pack_return_value(int def_index, ostream &out, string return_expr) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user