interfaceMakerPythonObj.cxx 25 KB

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