interfaceMakerPythonSimple.cxx 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. // Filename: interfaceMakerPythonSimple.cxx
  2. // Created by: drose (01Oct01)
  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 "interfaceMakerPythonSimple.h"
  19. #include "interrogateBuilder.h"
  20. #include "interrogate.h"
  21. #include "functionRemap.h"
  22. #include "parameterRemapUnchanged.h"
  23. #include "typeManager.h"
  24. #include "interrogateDatabase.h"
  25. #include "interrogateType.h"
  26. #include "interrogateFunction.h"
  27. #include "cppFunctionType.h"
  28. ////////////////////////////////////////////////////////////////////
  29. // Function: InterfaceMakerPythonSimple::Constructor
  30. // Access: Public
  31. // Description:
  32. ////////////////////////////////////////////////////////////////////
  33. InterfaceMakerPythonSimple::
  34. InterfaceMakerPythonSimple(InterrogateModuleDef *def) :
  35. InterfaceMakerPython(def)
  36. {
  37. }
  38. ////////////////////////////////////////////////////////////////////
  39. // Function: InterfaceMakerPythonSimple::Destructor
  40. // Access: Public, Virtual
  41. // Description:
  42. ////////////////////////////////////////////////////////////////////
  43. InterfaceMakerPythonSimple::
  44. ~InterfaceMakerPythonSimple() {
  45. }
  46. ////////////////////////////////////////////////////////////////////
  47. // Function: InterfaceMakerPythonSimple::write_prototypes
  48. // Access: Public, Virtual
  49. // Description: Generates the list of function prototypes
  50. // corresponding to the functions that will be output in
  51. // write_functions().
  52. ////////////////////////////////////////////////////////////////////
  53. void InterfaceMakerPythonSimple::
  54. write_prototypes(ostream &out,ostream *out_h) {
  55. Functions::iterator fi;
  56. for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
  57. Function *func = (*fi);
  58. write_prototype_for(out, func);
  59. }
  60. out << "\n";
  61. InterfaceMakerPython::write_prototypes(out,out_h);
  62. }
  63. ////////////////////////////////////////////////////////////////////
  64. // Function: InterfaceMakerPythonSimple::write_functions
  65. // Access: Public, Virtual
  66. // Description: Generates the list of functions that are appropriate
  67. // for this interface. This function is called *before*
  68. // write_prototypes(), above.
  69. ////////////////////////////////////////////////////////////////////
  70. void InterfaceMakerPythonSimple::
  71. write_functions(ostream &out) {
  72. Functions::iterator fi;
  73. for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
  74. Function *func = (*fi);
  75. write_function_for(out, func);
  76. }
  77. InterfaceMakerPython::write_functions(out);
  78. }
  79. ////////////////////////////////////////////////////////////////////
  80. // Function: InterfaceMakerPythonSimple::write_module
  81. // Access: Public, Virtual
  82. // Description: Generates whatever additional code is required to
  83. // support a module file.
  84. ////////////////////////////////////////////////////////////////////
  85. void InterfaceMakerPythonSimple::
  86. write_module(ostream &out,ostream *out_h, InterrogateModuleDef *def) {
  87. InterfaceMakerPython::write_module(out,out_h, def);
  88. out << "static PyMethodDef python_simple_funcs[] = {\n";
  89. Functions::iterator fi;
  90. for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
  91. Function *func = (*fi);
  92. Function::Remaps::const_iterator ri;
  93. for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  94. FunctionRemap *remap = (*ri);
  95. out << " { \"" << remap->_reported_name << "\", &"
  96. << remap->_wrapper_name << ", METH_VARARGS },\n";
  97. }
  98. }
  99. out << " { NULL, NULL }\n"
  100. << "};\n\n"
  101. << "#ifdef _WIN32\n"
  102. << "extern \"C\" __declspec(dllexport) void init" << def->library_name << "();\n"
  103. << "#else\n"
  104. << "extern \"C\" void init" << def->library_name << "();\n"
  105. << "#endif\n\n"
  106. << "void init" << def->library_name << "() {\n"
  107. << " Py_InitModule(\"" << def->library_name
  108. << "\", python_simple_funcs);\n"
  109. << "}\n\n";
  110. }
  111. ////////////////////////////////////////////////////////////////////
  112. // Function: InterfaceMakerPythonSimple::synthesize_this_parameter
  113. // Access: Public, Virtual
  114. // Description: This method should be overridden and redefined to
  115. // return true for interfaces that require the implicit
  116. // "this" parameter, if present, to be passed as the
  117. // first parameter to any wrapper functions.
  118. ////////////////////////////////////////////////////////////////////
  119. bool InterfaceMakerPythonSimple::
  120. synthesize_this_parameter() {
  121. return true;
  122. }
  123. ////////////////////////////////////////////////////////////////////
  124. // Function: InterfaceMakerPythonSimple::get_wrapper_prefix
  125. // Access: Protected, Virtual
  126. // Description: Returns the prefix string used to generate wrapper
  127. // function names.
  128. ////////////////////////////////////////////////////////////////////
  129. string InterfaceMakerPythonSimple::
  130. get_wrapper_prefix() {
  131. return "_inP";
  132. }
  133. ////////////////////////////////////////////////////////////////////
  134. // Function: InterfaceMakerPythonSimple::get_unique_prefix
  135. // Access: Protected, Virtual
  136. // Description: Returns the prefix string used to generate unique
  137. // symbolic names, which are not necessarily C-callable
  138. // function names.
  139. ////////////////////////////////////////////////////////////////////
  140. string InterfaceMakerPythonSimple::
  141. get_unique_prefix() {
  142. return "p";
  143. }
  144. ////////////////////////////////////////////////////////////////////
  145. // Function: InterfaceMakerPythonSimple::record_function_wrapper
  146. // Access: Protected, Virtual
  147. // Description: Associates the function wrapper with its function in
  148. // the appropriate structures in the database.
  149. ////////////////////////////////////////////////////////////////////
  150. void InterfaceMakerPythonSimple::
  151. record_function_wrapper(InterrogateFunction &ifunc,
  152. FunctionWrapperIndex wrapper_index) {
  153. ifunc._python_wrappers.push_back(wrapper_index);
  154. }
  155. ////////////////////////////////////////////////////////////////////
  156. // Function: InterfaceMakerPythonSimple::write_prototype_for
  157. // Access: Private
  158. // Description: Writes the prototype for the indicated function.
  159. ////////////////////////////////////////////////////////////////////
  160. void InterfaceMakerPythonSimple::
  161. write_prototype_for(ostream &out, InterfaceMaker::Function *func) {
  162. Function::Remaps::const_iterator ri;
  163. for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  164. FunctionRemap *remap = (*ri);
  165. if (!output_function_names) {
  166. // If we're not saving the function names, don't export it from
  167. // the library.
  168. out << "static ";
  169. } else {
  170. out << "extern \"C\" ";
  171. }
  172. out << "PyObject *"
  173. << remap->_wrapper_name << "(PyObject *self, PyObject *args);\n";
  174. }
  175. }
  176. ////////////////////////////////////////////////////////////////////
  177. // Function: InterfaceMakerPythonSimple::write_function_for
  178. // Access: Private
  179. // Description: Writes the definition for a function that will call
  180. // the indicated C++ function or method.
  181. ////////////////////////////////////////////////////////////////////
  182. void InterfaceMakerPythonSimple::
  183. write_function_for(ostream &out, InterfaceMaker::Function *func) {
  184. Function::Remaps::const_iterator ri;
  185. for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  186. FunctionRemap *remap = (*ri);
  187. write_function_instance(out, func, remap);
  188. }
  189. }
  190. ////////////////////////////////////////////////////////////////////
  191. // Function: InterfaceMakerPythonSimple::write_function_instance
  192. // Access: Private
  193. // Description: Writes out the particular function that handles a
  194. // single instance of an overloaded function.
  195. ////////////////////////////////////////////////////////////////////
  196. void InterfaceMakerPythonSimple::write_function_instance(ostream &out, InterfaceMaker::Function *func,
  197. FunctionRemap *remap) {
  198. out << "/*\n"
  199. << " * Python simple wrapper for\n"
  200. << " * ";
  201. remap->write_orig_prototype(out, 0);
  202. out << "\n"
  203. << " */\n";
  204. if (!output_function_names) {
  205. // If we're not saving the function names, don't export it from
  206. // the library.
  207. out << "static ";
  208. }
  209. out << "PyObject *\n"
  210. << remap->_wrapper_name << "(PyObject *, PyObject *args) {\n";
  211. if (generate_spam) {
  212. write_spam_message(out, remap);
  213. }
  214. string format_specifiers;
  215. string parameter_list;
  216. string container;
  217. vector_string pexprs;
  218. string extra_convert;
  219. string extra_param_check;
  220. string extra_cleanup;
  221. // Make one pass through the parameter list. We will output a
  222. // one-line temporary variable definition for each parameter, while
  223. // simultaneously building the ParseTuple() function call and also
  224. // the parameter expression list for call_function().
  225. int pn;
  226. for (pn = 0; pn < (int)remap->_parameters.size(); ++pn) {
  227. indent(out, 2);
  228. CPPType *orig_type = remap->_parameters[pn]._remap->get_orig_type();
  229. CPPType *type = remap->_parameters[pn]._remap->get_new_type();
  230. string param_name = remap->get_parameter_name(pn);
  231. // This is the string to convert our local variable to the
  232. // appropriate C++ type. Normally this is just a cast.
  233. string pexpr_string =
  234. "(" + type->get_local_name(&parser) + ")" + param_name;
  235. if (remap->_parameters[pn]._remap->new_type_is_atomic_string()) {
  236. if (TypeManager::is_char_pointer(orig_type)) {
  237. out << "char *" << param_name;
  238. format_specifiers += "s";
  239. parameter_list += ", &" + param_name;
  240. } else if (TypeManager::is_wstring(orig_type)) {
  241. out << "Py_UNICODE *" << param_name
  242. << "_str; int " << param_name << "_len";
  243. format_specifiers += "u#";
  244. parameter_list += ", &" + param_name
  245. + "_str, &" + param_name + "_len";
  246. pexpr_string = "basic_string<wchar_t>((wchar_t *)" +
  247. param_name + "_str, " +
  248. param_name + "_len)";
  249. } else {
  250. out << "char *" << param_name
  251. << "_str; int " << param_name << "_len";
  252. format_specifiers += "s#";
  253. parameter_list += ", &" + param_name
  254. + "_str, &" + param_name + "_len";
  255. pexpr_string = "basic_string<char>(" +
  256. param_name + "_str, " +
  257. param_name + "_len)";
  258. }
  259. } else if (TypeManager::is_bool(type)) {
  260. out << "PyObject *" << param_name;
  261. format_specifiers += "O";
  262. parameter_list += ", &" + param_name;
  263. pexpr_string = "(PyObject_IsTrue(" + param_name + ")!=0)";
  264. } else if (TypeManager::is_unsigned_longlong(type)) {
  265. out << "PyObject *" << param_name;
  266. format_specifiers += "O";
  267. parameter_list += ", &" + param_name;
  268. extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
  269. extra_param_check += "|| (" + param_name + "_long == NULL)";
  270. pexpr_string = "PyLong_AsUnsignedLongLong(" + param_name + "_long)";
  271. extra_cleanup += " Py_XDECREF(" + param_name + "_long);";
  272. } else if (TypeManager::is_longlong(type)) {
  273. out << "PyObject *" << param_name;
  274. format_specifiers += "O";
  275. parameter_list += ", &" + param_name;
  276. extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
  277. extra_param_check += "|| (" + param_name + "_long == NULL)";
  278. pexpr_string = "PyLong_AsLongLong(" + param_name + "_long)";
  279. extra_cleanup += " Py_XDECREF(" + param_name + "_long);";
  280. } else if (TypeManager::is_unsigned_integer(type)) {
  281. out << "PyObject *" << param_name;
  282. format_specifiers += "O";
  283. parameter_list += ", &" + param_name;
  284. extra_convert += " PyObject *" + param_name + "_uint = PyNumber_Long(" + param_name + ");";
  285. extra_param_check += "|| (" + param_name + "_uint == NULL)";
  286. pexpr_string = "(unsigned int)PyLong_AsUnsignedLong(" + param_name + "_uint)";
  287. extra_cleanup += " Py_XDECREF(" + param_name + "_uint);";
  288. } else if (TypeManager::is_integer(type)) {
  289. out << "int " << param_name;
  290. format_specifiers += "i";
  291. parameter_list += ", &" + param_name;
  292. } else if (TypeManager::is_float(type)) {
  293. out << "double " << param_name;
  294. format_specifiers += "d";
  295. parameter_list += ", &" + param_name;
  296. } else if (TypeManager::is_char_pointer(type)) {
  297. out << "char *" << param_name;
  298. format_specifiers += "s";
  299. parameter_list += ", &" + param_name;
  300. } else if (TypeManager::is_pointer_to_PyObject(type)) {
  301. out << "PyObject *" << param_name;
  302. format_specifiers += "O";
  303. parameter_list += ", &" + param_name;
  304. pexpr_string = param_name;
  305. } else if (TypeManager::is_pointer(type)) {
  306. out << "int " << param_name;
  307. format_specifiers += "i";
  308. parameter_list += ", &" + param_name;
  309. } else {
  310. // Ignore a parameter.
  311. out << "PyObject *" << param_name;
  312. format_specifiers += "O";
  313. parameter_list += ", &" + param_name;
  314. }
  315. out << ";\n";
  316. if (remap->_has_this && pn == 0) {
  317. // The "this" parameter gets passed in separately.
  318. container = pexpr_string;
  319. }
  320. pexprs.push_back(pexpr_string);
  321. }
  322. out << " if (PyArg_ParseTuple(args, \"" << format_specifiers
  323. << "\"" << parameter_list << ")) {\n";
  324. if (!extra_convert.empty()) {
  325. out << " " << extra_convert << "\n";
  326. }
  327. if (!extra_param_check.empty()) {
  328. out << " if (" << extra_param_check.substr(3) << ") {\n";
  329. if (!extra_cleanup.empty()) {
  330. out << " " << extra_cleanup << "\n";
  331. }
  332. out << " PyErr_SetString(PyExc_TypeError, \"Invalid parameters.\");\n"
  333. << " return (PyObject *)NULL;\n"
  334. << " }\n";
  335. }
  336. if (track_interpreter) {
  337. out << " in_interpreter = 0;\n";
  338. }
  339. if (!remap->_void_return &&
  340. remap->_return_type->new_type_is_atomic_string()) {
  341. // Treat strings as a special case. We don't want to format the
  342. // return expression.
  343. string return_expr = remap->call_function(out, 4, false, container, pexprs);
  344. CPPType *type = remap->_return_type->get_orig_type();
  345. out << " ";
  346. type->output_instance(out, "return_value", &parser);
  347. out << " = " << return_expr << ";\n";
  348. if (track_interpreter) {
  349. out << " in_interpreter = 1;\n";
  350. }
  351. if (!extra_cleanup.empty()) {
  352. out << " " << extra_cleanup << "\n";
  353. }
  354. return_expr = manage_return_value(out, 4, remap, "return_value");
  355. test_assert(out, 4);
  356. pack_return_value(out, 4, remap, return_expr);
  357. } else {
  358. string return_expr = remap->call_function(out, 4, true, container, pexprs);
  359. if (return_expr.empty()) {
  360. if (track_interpreter) {
  361. out << " in_interpreter = 1;\n";
  362. }
  363. if (!extra_cleanup.empty()) {
  364. out << " " << extra_cleanup << "\n";
  365. }
  366. test_assert(out, 4);
  367. out << " return Py_BuildValue(\"\");\n";
  368. } else {
  369. CPPType *type = remap->_return_type->get_temporary_type();
  370. out << " ";
  371. type->output_instance(out, "return_value", &parser);
  372. out << " = " << return_expr << ";\n";
  373. if (track_interpreter) {
  374. out << " in_interpreter = 1;\n";
  375. }
  376. if (!extra_cleanup.empty()) {
  377. out << " " << extra_cleanup << "\n";
  378. }
  379. return_expr = manage_return_value(out, 4, remap, "return_value");
  380. test_assert(out, 4);
  381. pack_return_value(out, 4, remap, remap->_return_type->temporary_to_return(return_expr));
  382. }
  383. }
  384. out << " }\n";
  385. out << " return (PyObject *)NULL;\n";
  386. out << "}\n\n";
  387. }
  388. ////////////////////////////////////////////////////////////////////
  389. // Function: InterfaceMakerPythonSimple::pack_return_value
  390. // Access: Private
  391. // Description: Outputs a command to pack the indicated expression,
  392. // of the return_type type, as a Python return value.
  393. ////////////////////////////////////////////////////////////////////
  394. void InterfaceMakerPythonSimple::
  395. pack_return_value(ostream &out, int indent_level,
  396. FunctionRemap *remap, string return_expr) {
  397. CPPType *orig_type = remap->_return_type->get_orig_type();
  398. CPPType *type = remap->_return_type->get_new_type();
  399. if (remap->_return_type->new_type_is_atomic_string())
  400. {
  401. if (TypeManager::is_char_pointer(orig_type)) {
  402. indent(out, indent_level)
  403. << "return PyString_FromString(" << return_expr << ");\n";
  404. } else if (TypeManager::is_wstring(orig_type)) {
  405. indent(out, indent_level)
  406. << "return PyUnicode_FromWideChar("
  407. << return_expr << ".data(), (int)" << return_expr << ".length());\n";
  408. } else {
  409. indent(out, indent_level)
  410. << "return PyString_FromStringAndSize("
  411. << return_expr << ".data(), " << return_expr << ".length());\n";
  412. }
  413. } else if (TypeManager::is_unsigned_longlong(type))
  414. {
  415. indent(out, indent_level)
  416. << "return PyLong_FromUnsignedLongLong(" << return_expr << ");\n";
  417. } else if (TypeManager::is_longlong(type))
  418. {
  419. indent(out, indent_level)
  420. << "return PyLong_FromLongLong(" << return_expr << ");\n";
  421. } else if (TypeManager::is_unsigned_integer(type)) {
  422. indent(out, indent_level)
  423. << "return PyLong_FromUnsignedLong(" << return_expr << ");\n";
  424. } else if (TypeManager::is_integer(type)) {
  425. indent(out, indent_level)
  426. << "return PyInt_FromLong(" << return_expr << ");\n";
  427. } else if (TypeManager::is_float(type)) {
  428. indent(out, indent_level)
  429. << "return PyFloat_FromDouble(" << return_expr << ");\n";
  430. } else if (TypeManager::is_char_pointer(type)) {
  431. indent(out, indent_level)
  432. << "return PyString_FromString(" << return_expr << ");\n";
  433. } else if (TypeManager::is_pointer_to_PyObject(type)) {
  434. indent(out, indent_level)
  435. << "return " << return_expr << ";\n";
  436. } else if (TypeManager::is_pointer(type)) {
  437. indent(out, indent_level)
  438. << "return PyInt_FromLong((int)" << return_expr << ");\n";
  439. } else {
  440. // Return None.
  441. indent(out, indent_level)
  442. << "return Py_BuildValue(\"\");\n";
  443. }
  444. }