00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <interrogate_interface.h>
00025 #include <interrogate_request.h>
00026 #include <load_dso.h>
00027 #include <pystub.h>
00028 #include <notify.h>
00029
00030
00031
00032 #ifndef HAVE_GETOPT_LONG_ONLY
00033 #include <gnu_getopt.h>
00034 #else
00035 #include <getopt.h>
00036 #endif
00037
00038 Filename output_code_filename;
00039 string module_name;
00040 string library_name;
00041 bool build_c_wrappers = false;
00042 bool build_python_wrappers = false;
00043 bool track_interpreter = false;
00044
00045
00046 static const char *short_options = "";
00047
00048
00049 enum CommandOptions {
00050 CO_oc = 256,
00051 CO_module,
00052 CO_library,
00053 CO_c,
00054 CO_python,
00055 CO_track_interpreter,
00056 };
00057
00058 static struct option long_options[] = {
00059 { "oc", required_argument, NULL, CO_oc },
00060 { "module", required_argument, NULL, CO_module },
00061 { "library", required_argument, NULL, CO_library },
00062 { "c", no_argument, NULL, CO_c },
00063 { "python", no_argument, NULL, CO_python },
00064 { "track-interpreter", no_argument, NULL, CO_track_interpreter },
00065 { NULL }
00066 };
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 int
00082 write_python_table(ostream &out) {
00083 out << "\n#include <dtoolbase.h>\n"
00084 << "#include <interrogate_request.h>\n\n"
00085 << "#include <Python.h>\n\n";
00086
00087 int count = 0;
00088
00089
00090
00091
00092 out << "extern \"C\" {\n";
00093
00094
00095 int num_functions = interrogate_number_of_functions();
00096 int fi;
00097 for (fi = 0; fi < num_functions; fi++) {
00098 FunctionIndex function_index = interrogate_get_function(fi);
00099
00100
00101 if (interrogate_function_has_module_name(function_index) &&
00102 module_name == interrogate_function_module_name(function_index)) {
00103
00104
00105 int num_wrappers =
00106 interrogate_function_number_of_python_wrappers(function_index);
00107
00108 for (int wi = 0; wi < num_wrappers; wi++) {
00109 FunctionWrapperIndex wrapper_index =
00110 interrogate_function_python_wrapper(function_index, wi);
00111
00112 if (interrogate_wrapper_is_callable_by_name(wrapper_index)) {
00113 count++;
00114 const char *wrapper_name =
00115 interrogate_wrapper_name(wrapper_index);
00116 out << " PyObject *" << wrapper_name
00117 << "(PyObject *self, PyObject *args);\n";
00118 }
00119 }
00120 }
00121 }
00122
00123 out << "}\n\n";
00124
00125
00126 out << "static PyMethodDef python_methods[" << count + 1 << "] = {\n";
00127
00128
00129 for (fi = 0; fi < num_functions; fi++) {
00130 FunctionIndex function_index = interrogate_get_function(fi);
00131
00132
00133 if (interrogate_function_has_module_name(function_index) &&
00134 module_name == interrogate_function_module_name(function_index)) {
00135
00136
00137 int num_wrappers =
00138 interrogate_function_number_of_python_wrappers(function_index);
00139 for (int wi = 0; wi < num_wrappers; wi++) {
00140 FunctionWrapperIndex wrapper_index =
00141 interrogate_function_python_wrapper(function_index, wi);
00142
00143 if (interrogate_wrapper_is_callable_by_name(wrapper_index)) {
00144 const char *wrapper_name =
00145 interrogate_wrapper_name(wrapper_index);
00146 out << " { \""
00147 << wrapper_name << "\", &"
00148 << wrapper_name << ", METH_VARARGS },\n";
00149 }
00150 }
00151 }
00152 }
00153
00154 if (library_name.empty()) {
00155 library_name = module_name;
00156 }
00157
00158 out << " { NULL, NULL }\n"
00159 << "};\n\n"
00160
00161 << "#ifdef _WIN32\n"
00162 << "extern \"C\" __declspec(dllexport) void init" << library_name << "();\n"
00163 << "#else\n"
00164 << "extern \"C\" void init" << library_name << "();\n"
00165 << "#endif\n\n"
00166
00167 << "void init" << library_name << "() {\n";
00168 if (track_interpreter) {
00169 out << " in_interpreter = 1;\n";
00170 }
00171 out << " Py_InitModule(\"" << library_name << "\", python_methods);\n"
00172 << "}\n\n";
00173
00174 return count;
00175 }
00176
00177 int
00178 main(int argc, char *argv[]) {
00179 extern char *optarg;
00180 extern int optind;
00181 int flag;
00182
00183 flag = getopt_long_only(argc, argv, short_options, long_options, NULL);
00184 while (flag != EOF) {
00185 switch (flag) {
00186 case CO_oc:
00187 output_code_filename = optarg;
00188 break;
00189
00190 case CO_module:
00191 module_name = optarg;
00192 break;
00193
00194 case CO_library:
00195 library_name = optarg;
00196 break;
00197
00198 case CO_c:
00199 build_c_wrappers = true;
00200 break;
00201
00202 case CO_python:
00203 build_python_wrappers = true;
00204 break;
00205
00206 case CO_track_interpreter:
00207 track_interpreter = true;
00208 break;
00209
00210 default:
00211 exit(1);
00212 }
00213 flag = getopt_long_only(argc, argv, short_options, long_options, NULL);
00214 }
00215
00216 argc -= (optind-1);
00217 argv += (optind-1);
00218
00219 if (argc < 2) {
00220 nout
00221 << "\nUsage:\n"
00222 << " interrogate-module [opts] libname.in [libname.in ...]\n\n";
00223 exit(1);
00224 }
00225
00226 output_code_filename.set_text();
00227
00228 if (!build_c_wrappers && !build_python_wrappers) {
00229 build_c_wrappers = true;
00230 }
00231
00232 for (int i = 1; i < argc; i++) {
00233 string param = argv[i];
00234
00235
00236 if (param.length() > 3 && param.substr(param.length() - 3) == ".in") {
00237
00238
00239 interrogate_request_database(param.c_str());
00240
00241 } else {
00242
00243 Filename pathname = argv[i];
00244 pathname.set_type(Filename::T_dso);
00245 nout << "Loading " << pathname << "\n";
00246 void *dl = load_dso(pathname);
00247 if (dl == NULL) {
00248 nout << "Unable to load: " << load_dso_error() << "\n";
00249 exit(1);
00250 }
00251 }
00252 }
00253
00254
00255 if (!output_code_filename.empty()) {
00256 ofstream output_code;
00257
00258 if (!output_code_filename.open_write(output_code)) {
00259 nout << "Unable to write to " << output_code_filename << "\n";
00260 } else {
00261 if (build_python_wrappers) {
00262 int count = write_python_table(output_code);
00263 nout << count << " python function wrappers exported.\n";
00264 }
00265 }
00266 }
00267
00268 return (0);
00269 }