00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "interfaceMakerPythonSimple.h"
00020 #include "interrogateBuilder.h"
00021 #include "interrogate.h"
00022 #include "functionRemap.h"
00023 #include "parameterRemapUnchanged.h"
00024 #include "typeManager.h"
00025
00026 #include "interrogateDatabase.h"
00027 #include "interrogateType.h"
00028 #include "interrogateFunction.h"
00029 #include "cppFunctionType.h"
00030
00031
00032
00033
00034
00035
00036 InterfaceMakerPythonSimple::
00037 InterfaceMakerPythonSimple(InterrogateModuleDef *def) :
00038 InterfaceMakerPython(def)
00039 {
00040 }
00041
00042
00043
00044
00045
00046
00047 InterfaceMakerPythonSimple::
00048 ~InterfaceMakerPythonSimple() {
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058 void InterfaceMakerPythonSimple::
00059 write_prototypes(ostream &out) {
00060 Functions::iterator fi;
00061 for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
00062 Function *func = (*fi);
00063 write_prototype_for(out, func);
00064 }
00065
00066 out << "\n";
00067 InterfaceMakerPython::write_prototypes(out);
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077 void InterfaceMakerPythonSimple::
00078 write_functions(ostream &out) {
00079 Functions::iterator fi;
00080 for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
00081 Function *func = (*fi);
00082 write_function_for(out, func);
00083 }
00084
00085 InterfaceMakerPython::write_functions(out);
00086 }
00087
00088
00089
00090
00091
00092
00093
00094 void InterfaceMakerPythonSimple::
00095 write_module(ostream &out, InterrogateModuleDef *def) {
00096 InterfaceMakerPython::write_module(out, def);
00097
00098 out << "static PyMethodDef python_simple_funcs[] = {\n";
00099
00100 Functions::iterator fi;
00101 for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
00102 Function *func = (*fi);
00103 Function::Remaps::const_iterator ri;
00104 for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
00105 FunctionRemap *remap = (*ri);
00106 out << " { \"" << remap->_unique_name << "\", &"
00107 << remap->_wrapper_name << ", METH_VARARGS },\n";
00108 }
00109 }
00110 out << " { NULL, NULL }\n"
00111 << "};\n\n"
00112
00113 << "#ifdef _WIN32\n"
00114 << "extern \"C\" __declspec(dllexport) void init" << def->library_name << "();\n"
00115 << "#else\n"
00116 << "extern \"C\" void init" << def->library_name << "();\n"
00117 << "#endif\n\n"
00118
00119 << "void init" << def->library_name << "() {\n"
00120 << " Py_InitModule(\"" << def->library_name
00121 << "\", python_simple_funcs);\n"
00122 << "}\n\n";
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 bool InterfaceMakerPythonSimple::
00134 synthesize_this_parameter() {
00135 return true;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144 string InterfaceMakerPythonSimple::
00145 get_wrapper_prefix() {
00146 return "_inP";
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156 string InterfaceMakerPythonSimple::
00157 get_unique_prefix() {
00158 return "p";
00159 }
00160
00161
00162
00163
00164
00165
00166
00167 void InterfaceMakerPythonSimple::
00168 record_function_wrapper(InterrogateFunction &ifunc,
00169 FunctionWrapperIndex wrapper_index) {
00170 ifunc._python_wrappers.push_back(wrapper_index);
00171 }
00172
00173
00174
00175
00176
00177
00178 void InterfaceMakerPythonSimple::
00179 write_prototype_for(ostream &out, InterfaceMaker::Function *func) {
00180 Function::Remaps::const_iterator ri;
00181
00182 for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
00183 FunctionRemap *remap = (*ri);
00184 if (!output_function_names) {
00185
00186
00187 out << "static ";
00188 } else {
00189 out << "extern \"C\" ";
00190 }
00191 out << "PyObject *"
00192 << remap->_wrapper_name << "(PyObject *self, PyObject *args);\n";
00193 }
00194 }
00195
00196
00197
00198
00199
00200
00201
00202 void InterfaceMakerPythonSimple::
00203 write_function_for(ostream &out, InterfaceMaker::Function *func) {
00204 Function::Remaps::const_iterator ri;
00205
00206 for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
00207 FunctionRemap *remap = (*ri);
00208 write_function_instance(out, func, remap);
00209 }
00210 }
00211
00212
00213
00214
00215
00216
00217
00218 void InterfaceMakerPythonSimple::
00219 write_function_instance(ostream &out, InterfaceMaker::Function *func,
00220 FunctionRemap *remap) {
00221 out << "/*\n"
00222 << " * Python simple wrapper for\n"
00223 << " * ";
00224 remap->write_orig_prototype(out, 0);
00225 out << "\n"
00226 << " */\n";
00227
00228 if (!output_function_names) {
00229
00230
00231 out << "static ";
00232 }
00233
00234 out << "PyObject *\n"
00235 << remap->_wrapper_name << "(PyObject *, PyObject *args) {\n";
00236
00237 if (generate_spam) {
00238 write_spam_message(out, remap);
00239 }
00240
00241 string format_specifiers;
00242 string parameter_list;
00243 string container;
00244 vector_string pexprs;
00245
00246
00247
00248
00249
00250
00251 int pn;
00252 for (pn = 0; pn < (int)remap->_parameters.size(); pn++) {
00253 indent(out, 2);
00254 CPPType *orig_type = remap->_parameters[pn]._remap->get_orig_type();
00255 CPPType *type = remap->_parameters[pn]._remap->get_new_type();
00256 string param_name = remap->get_parameter_name(pn);
00257
00258
00259
00260 string pexpr_string =
00261 "(" + type->get_local_name(&parser) + ")" + param_name;
00262
00263 if (remap->_parameters[pn]._remap->new_type_is_atomic_string()) {
00264 if (TypeManager::is_char_pointer(orig_type)) {
00265 out << "char *" << param_name;
00266 format_specifiers += "s";
00267 parameter_list += ", &" + param_name;
00268
00269 } else {
00270 out << "char *" << param_name
00271 << "_str; int " << param_name << "_len";
00272 format_specifiers += "s#";
00273 parameter_list += ", &" + param_name
00274 + "_str, &" + param_name + "_len";
00275 pexpr_string = "basic_string<char>(" +
00276 param_name + "_str, " +
00277 param_name + "_len)";
00278 }
00279
00280 } else if (TypeManager::is_bool(type)) {
00281 out << "PyObject *" << param_name;
00282 format_specifiers += "O";
00283 parameter_list += ", &" + param_name;
00284 pexpr_string = "(PyObject_IsTrue(" + param_name + ")!=0)";
00285
00286 } else if (TypeManager::is_integer(type)) {
00287 out << "int " << param_name;
00288 format_specifiers += "i";
00289 parameter_list += ", &" + param_name;
00290
00291 } else if (TypeManager::is_float(type)) {
00292 out << "double " << param_name;
00293 format_specifiers += "d";
00294 parameter_list += ", &" + param_name;
00295
00296 } else if (TypeManager::is_char_pointer(type)) {
00297 out << "char *" << param_name;
00298 format_specifiers += "s";
00299 parameter_list += ", &" + param_name;
00300
00301 } else if (TypeManager::is_pointer(type)) {
00302 out << "int " << param_name;
00303 format_specifiers += "i";
00304 parameter_list += ", &" + param_name;
00305
00306 } else {
00307
00308 out << "PyObject *" << param_name;
00309 format_specifiers += "O";
00310 parameter_list += ", &" + param_name;
00311 }
00312
00313 out << ";\n";
00314 if (remap->_has_this && pn == 0) {
00315
00316 container = pexpr_string;
00317 }
00318 pexprs.push_back(pexpr_string);
00319 }
00320
00321 out << " if (PyArg_ParseTuple(args, \"" << format_specifiers
00322 << "\"" << parameter_list << ")) {\n";
00323
00324 if (track_interpreter) {
00325 out << " in_interpreter = 0;\n";
00326 }
00327
00328 if (!remap->_void_return &&
00329 remap->_return_type->new_type_is_atomic_string()) {
00330
00331
00332 string return_expr = remap->call_function(out, 4, false, container, pexprs);
00333
00334 CPPType *type = remap->_return_type->get_orig_type();
00335 out << " ";
00336 type->output_instance(out, "return_value", &parser);
00337 out << " = " << return_expr << ";\n";
00338
00339 if (track_interpreter) {
00340 out << " in_interpreter = 1;\n";
00341 }
00342
00343 return_expr = manage_return_value(out, 4, remap, "return_value");
00344 test_assert(out, 4);
00345 pack_return_value(out, 4, remap, return_expr);
00346
00347 } else {
00348 string return_expr = remap->call_function(out, 4, true, container, pexprs);
00349 if (return_expr.empty()) {
00350 if (track_interpreter) {
00351 out << " in_interpreter = 1;\n";
00352 }
00353 test_assert(out, 4);
00354 out << " return Py_BuildValue(\"\");\n";
00355
00356 } else {
00357 CPPType *type = remap->_return_type->get_temporary_type();
00358 out << " ";
00359 type->output_instance(out, "return_value", &parser);
00360 out << " = " << return_expr << ";\n";
00361 if (track_interpreter) {
00362 out << " in_interpreter = 1;\n";
00363 }
00364
00365 return_expr = manage_return_value(out, 4, remap, "return_value");
00366 test_assert(out, 4);
00367 pack_return_value(out, 4, remap, remap->_return_type->temporary_to_return(return_expr));
00368 }
00369 }
00370
00371 out << " }\n";
00372
00373 out << " return (PyObject *)NULL;\n";
00374 out << "}\n\n";
00375 }
00376
00377
00378
00379
00380
00381
00382
00383 void InterfaceMakerPythonSimple::
00384 pack_return_value(ostream &out, int indent_level,
00385 FunctionRemap *remap, string return_expr) {
00386 CPPType *orig_type = remap->_return_type->get_orig_type();
00387 CPPType *type = remap->_return_type->get_new_type();
00388
00389 if (remap->_return_type->new_type_is_atomic_string()) {
00390 if (TypeManager::is_char_pointer(orig_type)) {
00391 indent(out, indent_level)
00392 << "return PyString_FromString(" << return_expr << ");\n";
00393
00394 } else {
00395 indent(out, indent_level)
00396 << "return PyString_FromStringAndSize("
00397 << return_expr << ".data(), " << return_expr << ".length());\n";
00398 }
00399
00400 } else if (TypeManager::is_integer(type)) {
00401 indent(out, indent_level)
00402 << "return PyInt_FromLong(" << return_expr << ");\n";
00403
00404 } else if (TypeManager::is_float(type)) {
00405 indent(out, indent_level)
00406 << "return PyFloat_FromDouble(" << return_expr << ");\n";
00407
00408 } else if (TypeManager::is_char_pointer(type)) {
00409 indent(out, indent_level)
00410 << "return PyString_FromString(" << return_expr << ");\n";
00411
00412 } else if (TypeManager::is_pointer(type)) {
00413 indent(out, indent_level)
00414 << "return PyInt_FromLong((int)" << return_expr << ");\n";
00415
00416 } else {
00417
00418 indent(out, indent_level)
00419 << "return Py_BuildValue(\"\");\n";
00420 }
00421 }