interfaceMakerPythonObj.cxx 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. // Filename: interfaceMakerPythonObj.cxx
  2. // Created by: drose (19Sep01)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://etc.cmu.edu/panda3d/docs/license/ .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #include "interfaceMakerPythonObj.h"
  19. #include "interrogateBuilder.h"
  20. #include "interrogate.h"
  21. #include "functionRemap.h"
  22. #include "parameterRemapUnchanged.h"
  23. #include "typeManager.h"
  24. #include "functionWriterPtrFromPython.h"
  25. #include "functionWriterPtrToPython.h"
  26. #include "interrogateDatabase.h"
  27. #include "interrogateType.h"
  28. #include "interrogateFunction.h"
  29. #include "cppFunctionType.h"
  30. ////////////////////////////////////////////////////////////////////
  31. // Function: InterfaceMakerPythonObj::Constructor
  32. // Access: Public
  33. // Description:
  34. ////////////////////////////////////////////////////////////////////
  35. InterfaceMakerPythonObj::
  36. InterfaceMakerPythonObj(InterrogateModuleDef *def) :
  37. InterfaceMakerPython(def)
  38. {
  39. }
  40. ////////////////////////////////////////////////////////////////////
  41. // Function: InterfaceMakerPythonObj::Destructor
  42. // Access: Public, Virtual
  43. // Description:
  44. ////////////////////////////////////////////////////////////////////
  45. InterfaceMakerPythonObj::
  46. ~InterfaceMakerPythonObj() {
  47. }
  48. ////////////////////////////////////////////////////////////////////
  49. // Function: InterfaceMakerPythonObj::write_prototypes
  50. // Access: Public, Virtual
  51. // Description: Generates the list of function prototypes
  52. // corresponding to the functions that will be output in
  53. // write_functions().
  54. ////////////////////////////////////////////////////////////////////
  55. void InterfaceMakerPythonObj::
  56. write_prototypes(ostream &out,ostream *out_h) {
  57. Functions::iterator fi;
  58. for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
  59. Function *func = (*fi);
  60. write_prototype_for(out, func);
  61. }
  62. out << "\n";
  63. InterfaceMakerPython::write_prototypes(out,out_h);
  64. }
  65. ////////////////////////////////////////////////////////////////////
  66. // Function: InterfaceMakerPythonObj::write_functions
  67. // Access: Public, Virtual
  68. // Description: Generates the list of functions that are appropriate
  69. // for this interface. This function is called *before*
  70. // write_prototypes(), above.
  71. ////////////////////////////////////////////////////////////////////
  72. void InterfaceMakerPythonObj::
  73. write_functions(ostream &out) {
  74. Functions::iterator fi;
  75. for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
  76. Function *func = (*fi);
  77. write_function_for(out, func);
  78. }
  79. InterfaceMakerPython::write_functions(out);
  80. // Finally, generate all the make-class-wrapper functions.
  81. Objects::iterator oi;
  82. for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
  83. Object *object = (*oi).second;
  84. write_class_wrapper(out, object);
  85. }
  86. }
  87. ////////////////////////////////////////////////////////////////////
  88. // Function: InterfaceMakerPythonObj::write_module
  89. // Access: Public, Virtual
  90. // Description: Generates whatever additional code is required to
  91. // support a module file.
  92. ////////////////////////////////////////////////////////////////////
  93. void InterfaceMakerPythonObj::
  94. write_module(ostream &out,ostream *out_h, InterrogateModuleDef *def) {
  95. InterfaceMakerPython::write_module(out,out_h, def);
  96. out << "static PyMethodDef python_obj_funcs[] = {\n";
  97. Objects::iterator oi;
  98. for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
  99. Object *object = (*oi).second;
  100. Functions::iterator fi;
  101. for (fi = object->_constructors.begin();
  102. fi != object->_constructors.end();
  103. ++fi) {
  104. Function *func = (*fi);
  105. out << " { \"" << func->_ifunc.get_name() << "\", &" << func->_name
  106. << ", METH_VARARGS },\n";
  107. }
  108. }
  109. out << " { NULL, NULL }\n"
  110. << "};\n\n"
  111. << "#ifdef _WIN32\n"
  112. << "extern \"C\" __declspec(dllexport) void init" << def->library_name << "();\n"
  113. << "#else\n"
  114. << "extern \"C\" void init" << def->library_name << "();\n"
  115. << "#endif\n\n"
  116. << "void init" << def->library_name << "() {\n"
  117. << " Py_InitModule(\"" << def->library_name
  118. << "\", python_obj_funcs);\n"
  119. << "}\n\n";
  120. }
  121. ////////////////////////////////////////////////////////////////////
  122. // Function: InterfaceMakerPythonObj::synthesize_this_parameter
  123. // Access: Public, Virtual
  124. // Description: This method should be overridden and redefined to
  125. // return true for interfaces that require the implicit
  126. // "this" parameter, if present, to be passed as the
  127. // first parameter to any wrapper functions.
  128. ////////////////////////////////////////////////////////////////////
  129. bool InterfaceMakerPythonObj::
  130. synthesize_this_parameter() {
  131. return true;
  132. }
  133. ////////////////////////////////////////////////////////////////////
  134. // Function: InterfaceMakerPythonObj::get_builder_name
  135. // Access: Public, Static
  136. // Description: Returns the name of the InterfaceMaker function
  137. // generated to define the Python class for the
  138. // indicated struct type.
  139. ////////////////////////////////////////////////////////////////////
  140. string InterfaceMakerPythonObj::
  141. get_builder_name(CPPType *struct_type) {
  142. return "get_python_class_" +
  143. InterrogateBuilder::clean_identifier(struct_type->get_local_name(&parser));
  144. }
  145. ////////////////////////////////////////////////////////////////////
  146. // Function: InterfaceMakerPythonObj::get_wrapper_prefix
  147. // Access: Protected, Virtual
  148. // Description: Returns the prefix string used to generate wrapper
  149. // function names.
  150. ////////////////////////////////////////////////////////////////////
  151. string InterfaceMakerPythonObj::
  152. get_wrapper_prefix() {
  153. return "wpo_";
  154. }
  155. ////////////////////////////////////////////////////////////////////
  156. // Function: InterfaceMakerPythonObj::write_class_wrapper
  157. // Access: Private
  158. // Description: Writes a function that will define the Python class.
  159. ////////////////////////////////////////////////////////////////////
  160. void InterfaceMakerPythonObj::
  161. write_class_wrapper(ostream &out, InterfaceMaker::Object *object) {
  162. CPPType *struct_type = object->_itype._cpptype;
  163. if (struct_type == (CPPType *)NULL) {
  164. return;
  165. }
  166. string name = get_builder_name(struct_type);
  167. string python_name =
  168. InterrogateBuilder::clean_identifier(struct_type->get_simple_name());
  169. out << "/*\n"
  170. << " * Generate unique Python class for "
  171. << struct_type->get_local_name(&parser) << "\n"
  172. << " */\n"
  173. << "PyObject *\n"
  174. << name << "() {\n"
  175. << " static PyObject *wrapper = (PyObject *)NULL;\n"
  176. << " static PyMethodDef methods[] = {\n";
  177. int methods_size = 0;
  178. int class_methods_size = 0;
  179. Functions::iterator fi;
  180. for (fi = object->_methods.begin(); fi != object->_methods.end(); ++fi) {
  181. Function *func = (*fi);
  182. if (func->_has_this) {
  183. out << " { \"" << func->_ifunc.get_name() << "\", &" << func->_name
  184. << ", METH_VARARGS },\n";
  185. methods_size++;
  186. }
  187. }
  188. out << " };\n"
  189. << " static const int methods_size = " << methods_size << ";\n\n"
  190. << " static PyMethodDef class_methods[] = {\n";
  191. for (fi = object->_methods.begin(); fi != object->_methods.end(); ++fi) {
  192. Function *func = (*fi);
  193. if (!func->_has_this) {
  194. out << " { \"" << func->_ifunc.get_name() << "\", &" << func->_name
  195. << ", METH_VARARGS },\n";
  196. class_methods_size++;
  197. }
  198. }
  199. out << " };\n"
  200. << " static const int class_methods_size = " << class_methods_size << ";\n\n"
  201. << " if (wrapper == (PyObject *)NULL) {\n"
  202. << " int i;\n"
  203. << " PyObject *bases = PyTuple_New(0);\n"
  204. << " PyObject *dict = PyDict_New();\n"
  205. << " PyObject *name = PyString_FromString(\""
  206. << python_name << "\");\n"
  207. << " wrapper = PyClass_New(bases, dict, name);\n"
  208. << " for (i = 0; i < methods_size; ++i) {\n"
  209. << " PyObject *function, *method;\n"
  210. << " function = PyCFunction_New(&methods[i], (PyObject *)NULL);\n"
  211. << " method = PyMethod_New(function, (PyObject *)NULL, wrapper);\n"
  212. << " PyDict_SetItemString(dict, methods[i].ml_name, method);\n"
  213. << " }\n"
  214. << " for (i = 0; i < class_methods_size; ++i) {\n"
  215. << " PyObject *function;\n"
  216. << " function = PyCFunction_New(&class_methods[i], (PyObject *)NULL);\n"
  217. << " PyDict_SetItemString(dict, class_methods[i].ml_name, function);\n"
  218. << " }\n"
  219. << " }\n"
  220. << " return wrapper;\n"
  221. << "}\n\n";
  222. }
  223. ////////////////////////////////////////////////////////////////////
  224. // Function: InterfaceMakerPythonObj::write_prototype_for
  225. // Access: Private
  226. // Description: Writes the prototype for the indicated function.
  227. ////////////////////////////////////////////////////////////////////
  228. void InterfaceMakerPythonObj::
  229. write_prototype_for(ostream &out, InterfaceMaker::Function *func) {
  230. out << "static PyObject *"
  231. << func->_name << "(PyObject *self, PyObject *args);\n";
  232. }
  233. ////////////////////////////////////////////////////////////////////
  234. // Function: InterfaceMakerPythonObj::write_function_for
  235. // Access: Private
  236. // Description: Writes the definition for a function that will call
  237. // the indicated C++ function or method.
  238. ////////////////////////////////////////////////////////////////////
  239. void InterfaceMakerPythonObj::
  240. write_function_for(ostream &out, InterfaceMaker::Function *func) {
  241. Function::Remaps::const_iterator ri;
  242. out << "/*\n"
  243. << " * Python object wrapper for\n";
  244. for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  245. FunctionRemap *remap = (*ri);
  246. out << " * ";
  247. remap->write_orig_prototype(out, 0);
  248. out << "\n";
  249. }
  250. out << " */\n";
  251. out << "static PyObject *"
  252. << func->_name << "(PyObject *, PyObject *args) {\n";
  253. // Now write out each instance of the overloaded function.
  254. string expected_params = "Arguments must match one of:";
  255. for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  256. FunctionRemap *remap = (*ri);
  257. expected_params += "\\n ";
  258. write_function_instance(out, 2, func, remap, expected_params);
  259. }
  260. // If we get here in the generated code, none of the parameters were
  261. // valid. Generate an error exception. (We don't rely on the error
  262. // already generated by ParseTuple(), because it only reports the
  263. // error for one flavor of the function, whereas we might accept
  264. // multiple flavors for the different overloaded C++ function
  265. // signatures.
  266. out << " PyErr_SetString(PyExc_TypeError, \"" << expected_params << "\");\n"
  267. << " return (PyObject *)NULL;\n";
  268. out << "}\n\n";
  269. }
  270. ////////////////////////////////////////////////////////////////////
  271. // Function: InterfaceMakerPythonObj::write_function_instance
  272. // Access: Private
  273. // Description: Writes out the part of a function that handles a
  274. // single instance of an overloaded function.
  275. ////////////////////////////////////////////////////////////////////
  276. void InterfaceMakerPythonObj::
  277. write_function_instance(ostream &out, int indent_level,
  278. InterfaceMaker::Function *func,
  279. FunctionRemap *remap, string &expected_params) {
  280. indent(out, indent_level) << "{\n";
  281. indent(out, indent_level + 2) << "/* ";
  282. remap->write_orig_prototype(out, 0);
  283. out << " */\n\n";
  284. string format_specifiers;
  285. string parameter_list;
  286. vector_string pexprs;
  287. string extra_convert;
  288. string extra_param_check;
  289. string extra_cleanup;
  290. // Make one pass through the parameter list. We will output a
  291. // one-line temporary variable definition for each parameter, while
  292. // simultaneously building the ParseTuple() function call and also
  293. // the parameter expression list for call_function().
  294. expected_params += remap->_cppfunc->get_simple_name();
  295. expected_params += "(";
  296. int pn;
  297. for (pn = 0; pn < (int)remap->_parameters.size(); pn++) {
  298. if (pn != 0) {
  299. expected_params += ", ";
  300. }
  301. indent(out, indent_level + 2);
  302. CPPType *orig_type = remap->_parameters[pn]._remap->get_orig_type();
  303. CPPType *type = remap->_parameters[pn]._remap->get_new_type();
  304. string param_name = remap->get_parameter_name(pn);
  305. // This is the string to convert our local variable to the
  306. // appropriate C++ type. Normally this is just a cast.
  307. string pexpr_string =
  308. "(" + type->get_local_name(&parser) + ")" + param_name;
  309. if (remap->_parameters[pn]._remap->new_type_is_atomic_string()) {
  310. if (TypeManager::is_char_pointer(orig_type)) {
  311. out << "char *" << param_name;
  312. format_specifiers += "s";
  313. parameter_list += ", &" + param_name;
  314. } else {
  315. out << "char *" << param_name
  316. << "_str; int " << param_name << "_len";
  317. format_specifiers += "s#";
  318. parameter_list += ", &" + param_name
  319. + "_str, &" + param_name + "_len";
  320. pexpr_string = "basic_string<char>(" +
  321. param_name + "_str, " +
  322. param_name + "_len)";
  323. }
  324. expected_params += "string";
  325. } else if (TypeManager::is_bool(type)) {
  326. out << "PyObject *" << param_name;
  327. format_specifiers += "O";
  328. parameter_list += ", &" + param_name;
  329. pexpr_string = "(PyObject_IsTrue(" + param_name + ")!=0)";
  330. expected_params += "bool";
  331. } else if (TypeManager::is_unsigned_longlong(type)) {
  332. out << "PyObject *" << param_name;
  333. format_specifiers += "O";
  334. parameter_list += ", &" + param_name;
  335. extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
  336. extra_param_check += "|| (" + param_name + "_long == NULL)";
  337. pexpr_string = "PyLong_AsUnsignedLongLong(" + param_name + "_long)";
  338. extra_cleanup += " Py_XDECREF(" + param_name + "_long);";
  339. expected_params += "long";
  340. } else if (TypeManager::is_longlong(type)) {
  341. out << "PyObject *" << param_name;
  342. format_specifiers += "O";
  343. parameter_list += ", &" + param_name;
  344. extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
  345. extra_param_check += "|| (" + param_name + "_long == NULL)";
  346. pexpr_string = "PyLong_AsLongLong(" + param_name + "_long)";
  347. extra_cleanup += " Py_XDECREF(" + param_name + "_long);";
  348. expected_params += "long";
  349. #ifndef USE_PYTHON_2_2_OR_EARLIER
  350. } else if (TypeManager::is_unsigned_integer(type)) {
  351. out << "unsigned int " << param_name;
  352. format_specifiers += "I"; // This requires Python 2.3 or better
  353. parameter_list += ", &" + param_name;
  354. #endif
  355. } else if (TypeManager::is_integer(type)) {
  356. out << "int " << param_name;
  357. format_specifiers += "i";
  358. parameter_list += ", &" + param_name;
  359. expected_params += "integer";
  360. } else if (TypeManager::is_float(type)) {
  361. out << "double " << param_name;
  362. format_specifiers += "d";
  363. parameter_list += ", &" + param_name;
  364. expected_params += "float";
  365. } else if (TypeManager::is_char_pointer(type)) {
  366. out << "char *" << param_name;
  367. format_specifiers += "s";
  368. parameter_list += ", &" + param_name;
  369. expected_params += "string";
  370. } else if (TypeManager::is_pointer(type)) {
  371. FunctionWriterPtrFromPython *writer = get_ptr_from_python(type);
  372. writer->get_pointer_type()->output_instance(out, param_name, &parser);
  373. format_specifiers += "O&";
  374. parameter_list += ", &" + writer->get_name() + ", &" + param_name;
  375. expected_params += writer->get_type()->get_preferred_name();
  376. } else {
  377. // Ignore a parameter.
  378. out << "PyObject *" << param_name;
  379. format_specifiers += "O";
  380. parameter_list += ", &" + param_name;
  381. expected_params += "any";
  382. }
  383. if (remap->_parameters[pn]._has_name) {
  384. expected_params += " " + remap->_parameters[pn]._name;
  385. }
  386. out << ";\n";
  387. pexprs.push_back(pexpr_string);
  388. }
  389. expected_params += ")";
  390. indent(out, indent_level + 2)
  391. << "if (PyArg_ParseTuple(args, \"" << format_specifiers
  392. << "\"" << parameter_list << ")) {\n";
  393. if (!extra_convert.empty()) {
  394. indent(out, indent_level + 3)
  395. << extra_convert << "\n";
  396. }
  397. if (!extra_param_check.empty()) {
  398. indent(out, indent_level + 4)
  399. << "if (" << extra_param_check.substr(3) << ") {\n";
  400. if (!extra_cleanup.empty()) {
  401. indent(out, indent_level + 5)
  402. << extra_cleanup << "\n";
  403. }
  404. indent(out, indent_level + 6)
  405. << "PyErr_SetString(PyExc_TypeError, \"Invalid parameters.\");\n";
  406. indent(out, indent_level + 6)
  407. << "return (PyObject *)NULL;\n";
  408. indent(out, indent_level + 4)
  409. << "}\n";
  410. }
  411. if (track_interpreter) {
  412. indent(out, indent_level + 4)
  413. << "in_interpreter = 0;\n";
  414. }
  415. if (!remap->_void_return &&
  416. remap->_return_type->new_type_is_atomic_string()) {
  417. // Treat strings as a special case. We don't want to format the
  418. // return expression.
  419. string return_expr =
  420. remap->call_function(out, indent_level + 4, false, "param0", pexprs);
  421. CPPType *type = remap->_return_type->get_orig_type();
  422. indent(out, indent_level + 4);
  423. type->output_instance(out, "return_value", &parser);
  424. out << " = " << return_expr << ";\n";
  425. if (track_interpreter) {
  426. indent(out, indent_level + 4)
  427. << "in_interpreter = 1;\n";
  428. }
  429. if (!extra_cleanup.empty()) {
  430. indent(out, indent_level + 3)
  431. << extra_cleanup << "\n";
  432. }
  433. return_expr = manage_return_value(out, indent_level + 4, remap, "return_value");
  434. test_assert(out, indent_level + 4);
  435. pack_return_value(out, indent_level + 4, remap, return_expr);
  436. } else {
  437. string return_expr =
  438. remap->call_function(out, indent_level + 4, true, "param0", pexprs);
  439. if (return_expr.empty()) {
  440. if (track_interpreter) {
  441. indent(out, indent_level + 4)
  442. << "in_interpreter = 1;\n";
  443. }
  444. if (!extra_cleanup.empty()) {
  445. indent(out, indent_level + 3)
  446. << extra_cleanup << "\n";
  447. }
  448. test_assert(out, indent_level + 4);
  449. indent(out, indent_level + 4)
  450. << "return Py_BuildValue(\"\");\n";
  451. } else {
  452. CPPType *type = remap->_return_type->get_temporary_type();
  453. indent(out, indent_level + 4);
  454. type->output_instance(out, "return_value", &parser);
  455. out << " = " << return_expr << ";\n";
  456. if (track_interpreter) {
  457. indent(out, indent_level + 4)
  458. << "in_interpreter = 1;\n";
  459. }
  460. if (!extra_cleanup.empty()) {
  461. indent(out, indent_level + 3)
  462. << extra_cleanup << "\n";
  463. }
  464. return_expr = manage_return_value(out, indent_level + 4, remap, "return_value");
  465. test_assert(out, indent_level + 4);
  466. pack_return_value(out, indent_level + 4, remap, remap->_return_type->temporary_to_return(return_expr));
  467. }
  468. }
  469. indent(out, indent_level + 2) << "}\n";
  470. indent(out, indent_level + 2)
  471. << "PyErr_Clear();\n"; // Clear the error generated by ParseTuple()
  472. indent(out, indent_level)
  473. << "}\n";
  474. }
  475. ////////////////////////////////////////////////////////////////////
  476. // Function: InterfaceMakerPythonObj::pack_return_value
  477. // Access: Private
  478. // Description: Outputs a command to pack the indicated expression,
  479. // of the return_type type, as a Python return value.
  480. ////////////////////////////////////////////////////////////////////
  481. void InterfaceMakerPythonObj::
  482. pack_return_value(ostream &out, int indent_level,
  483. FunctionRemap *remap, string return_expr) {
  484. CPPType *orig_type = remap->_return_type->get_orig_type();
  485. CPPType *type = remap->_return_type->get_new_type();
  486. if (remap->_return_type->new_type_is_atomic_string()) {
  487. if (TypeManager::is_char_pointer(orig_type)) {
  488. indent(out, indent_level)
  489. << "return PyString_FromString(" << return_expr << ");\n";
  490. } else {
  491. indent(out, indent_level)
  492. << "return PyString_FromStringAndSize("
  493. << return_expr << ".data(), " << return_expr << ".length());\n";
  494. }
  495. } else if (TypeManager::is_unsigned_longlong(type)) {
  496. indent(out, indent_level)
  497. << "return PyLong_FromUnsignedLongLong(" << return_expr << ");\n";
  498. } else if (TypeManager::is_longlong(type)) {
  499. indent(out, indent_level)
  500. << "return PyLong_FromLongLong(" << return_expr << ");\n";
  501. #ifndef USE_PYTHON_2_2_OR_EARLIER
  502. } else if (TypeManager::is_unsigned_integer(type)) {
  503. indent(out, indent_level)
  504. << "return PyLong_FromUnsignedLong(" << return_expr << ");\n";
  505. #endif
  506. } else if (TypeManager::is_integer(type)) {
  507. indent(out, indent_level)
  508. << "return PyInt_FromLong(" << return_expr << ");\n";
  509. } else if (TypeManager::is_float(type)) {
  510. indent(out, indent_level)
  511. << "return PyFloat_FromDouble(" << return_expr << ");\n";
  512. } else if (TypeManager::is_char_pointer(type)) {
  513. indent(out, indent_level)
  514. << "return PyString_FromString(" << return_expr << ");\n";
  515. } else if (TypeManager::is_pointer(type)) {
  516. bool caller_manages = remap->_return_value_needs_management;
  517. FunctionWriterPtrToPython *writer = get_ptr_to_python(type);
  518. indent(out, indent_level)
  519. << "return " << writer->get_name() << "(("
  520. << writer->get_pointer_type()->get_local_name(&parser) << ")"
  521. << return_expr << ", " << caller_manages << ");\n";
  522. } else {
  523. // Return None.
  524. indent(out, indent_level)
  525. << "return Py_BuildValue(\"\");\n";
  526. }
  527. }
  528. ////////////////////////////////////////////////////////////////////
  529. // Function: InterfaceMakerPythonObj::get_ptr_from_python
  530. // Access: Private
  531. // Description: Returns a FunctionWriter pointer suitable for
  532. // converting from a Python wrapper of the indicated
  533. // type to the corresponding C++ pointer.
  534. ////////////////////////////////////////////////////////////////////
  535. FunctionWriterPtrFromPython *InterfaceMakerPythonObj::
  536. get_ptr_from_python(CPPType *type) {
  537. PtrConverter::iterator ci;
  538. ci = _from_python.find(type);
  539. if (ci != _from_python.end()) {
  540. // We've previously used this type.
  541. return (FunctionWriterPtrFromPython *)(*ci).second;
  542. }
  543. FunctionWriter *writer =
  544. _function_writers.add_writer(new FunctionWriterPtrFromPython(type));
  545. _from_python.insert(PtrConverter::value_type(type, writer));
  546. return (FunctionWriterPtrFromPython *)writer;
  547. }
  548. ////////////////////////////////////////////////////////////////////
  549. // Function: InterfaceMakerPythonObj::get_ptr_to_python
  550. // Access: Private
  551. // Description: Returns a FunctionWriter pointer suitable for
  552. // converting from a C++ pointer of the indicated
  553. // type to the corresponding Python wrapper.
  554. ////////////////////////////////////////////////////////////////////
  555. FunctionWriterPtrToPython *InterfaceMakerPythonObj::
  556. get_ptr_to_python(CPPType *type) {
  557. PtrConverter::iterator ci;
  558. ci = _to_python.find(type);
  559. if (ci != _to_python.end()) {
  560. // We've previously used this type.
  561. return (FunctionWriterPtrToPython *)(*ci).second;
  562. }
  563. FunctionWriter *writer =
  564. _function_writers.add_writer(new FunctionWriterPtrToPython(type));
  565. _to_python.insert(PtrConverter::value_type(type, writer));
  566. return (FunctionWriterPtrToPython *)writer;
  567. }