]>
Commit | Line | Data |
---|---|---|
c90f71dd RD |
1 | /******************************************************************************* |
2 | * Simplified Wrapper and Interface Generator (SWIG) | |
3 | * | |
4 | * Author : David Beazley | |
5 | * | |
6 | * Department of Computer Science | |
7 | * University of Chicago | |
8 | * 1100 E 58th Street | |
9 | * Chicago, IL 60637 | |
10 | * beazley@cs.uchicago.edu | |
11 | * | |
12 | * Please read the file LICENSE for the copyright and terms by which SWIG | |
13 | * can be used and distributed. | |
14 | *******************************************************************************/ | |
15 | ||
16 | /********************************************************************** | |
17 | * $Header$ | |
18 | * | |
19 | * python.cxx | |
20 | * | |
21 | * Python module. | |
22 | **************************************************************************/ | |
23 | ||
24 | ||
25 | #include "swig.h" | |
26 | #include "python.h" | |
27 | ||
28 | // Structures for managing doc strings | |
29 | ||
30 | struct DocString { | |
31 | DocEntry *de; | |
32 | char *name; | |
33 | DocString *next; | |
34 | }; | |
35 | ||
36 | static int doc_index = 0; | |
37 | static DocString *doc_strings = 0; | |
38 | ||
39 | static char *usage = "\ | |
40 | Python Options (available with -python)\n\ | |
41 | -docstring - Produce docstrings (only applies to shadow classes)\n\ | |
42 | -globals name - Set name used to access C global variable ('cvar' by default).\n\ | |
43 | -module name - Set module name\n\ | |
44 | -keyword - Use keyword arguments\n\ | |
45 | -shadow - Generate shadow classes. \n\n"; | |
46 | ||
47 | static String pragma_include; | |
48 | ||
49 | // --------------------------------------------------------------------- | |
50 | // PYTHON::parse_args(int argc, char *argv[]) | |
51 | // | |
52 | // --------------------------------------------------------------------- | |
53 | ||
54 | void PYTHON::parse_args(int argc, char *argv[]) { | |
55 | ||
56 | int i = 1; | |
57 | ||
58 | sprintf(LibDir,"%s",path); | |
59 | ||
60 | docstring = 0; | |
61 | ||
62 | // Look for additional command line options. | |
63 | for (i = 1; i < argc; i++) { | |
64 | if (argv[i]) { | |
65 | if(strcmp(argv[i],"-module") == 0) { | |
66 | if (argv[i+1]) { | |
67 | module = new char[strlen(argv[i+1])+2]; | |
68 | strcpy(module, argv[i+1]); | |
69 | mark_arg(i); | |
70 | mark_arg(i+1); | |
71 | i+=1; | |
72 | } else { | |
73 | arg_error(); | |
74 | } | |
75 | } else if (strcmp(argv[i],"-globals") == 0) { | |
76 | if (argv[i+1]) { | |
77 | global_name = new char[strlen(argv[i+1])+1]; | |
78 | strcpy(global_name, argv[i+1]); | |
79 | mark_arg(i); | |
80 | mark_arg(i+1); | |
81 | i++; | |
82 | } else { | |
83 | arg_error(); | |
84 | } | |
85 | } else if (strcmp(argv[i],"-shadow") == 0) { | |
86 | shadow = 1; | |
87 | mark_arg(i); | |
88 | } else if (strcmp(argv[i],"-docstring") == 0) { | |
89 | docstring = 1; | |
90 | mark_arg(i); | |
91 | } else if (strcmp(argv[i],"-keyword") == 0) { | |
92 | use_kw = 1; | |
93 | mark_arg(i); | |
94 | } else if (strcmp(argv[i],"-help") == 0) { | |
95 | fputs(usage,stderr); | |
96 | } | |
97 | } | |
98 | } | |
99 | // Create a symbol for this language | |
100 | add_symbol("SWIGPYTHON",0,0); | |
101 | ||
102 | // Set name of typemaps | |
103 | ||
104 | typemap_lang = "python"; | |
105 | ||
106 | } | |
107 | ||
108 | // --------------------------------------------------------------------- | |
109 | // PYTHON::parse() | |
110 | // | |
111 | // Parse the interface file | |
112 | // --------------------------------------------------------------------- | |
113 | ||
114 | void | |
115 | PYTHON::parse() { | |
116 | ||
117 | printf("Generating wrappers for Python\n"); | |
118 | headers(); | |
119 | ||
120 | // Run the SWIG parser | |
121 | ||
122 | yyparse(); | |
123 | } | |
124 | ||
125 | // --------------------------------------------------------------------- | |
126 | // PYTHON::set_module(char *mod_name, char **mod_list) | |
127 | // | |
128 | // Sets the module name. | |
129 | // Does nothing if it's already set (so it can be overridden as a command | |
130 | // line option). | |
131 | // | |
132 | //---------------------------------------------------------------------- | |
133 | ||
134 | void PYTHON::set_module(char *mod_name, char **mod_list) { | |
135 | int i; | |
136 | ||
137 | // If an "import" method has been set and we're in shadow class mode, | |
138 | // output a python command to load the module | |
139 | ||
140 | if (import_file) { | |
141 | if (!(strcmp(import_file,input_file+strlen(input_file)-strlen(import_file)))) { | |
142 | if (shadow) { | |
143 | fprintf(f_shadow,"\nfrom %s import *\n", mod_name); | |
144 | } | |
145 | delete import_file; | |
146 | import_file = 0; | |
147 | } | |
148 | } | |
149 | ||
150 | if (module) return; | |
151 | ||
152 | module = new char[strlen(mod_name)+1]; | |
153 | strcpy(module,mod_name); | |
154 | ||
155 | // If there was a mod_list specified, make this incredible hack | |
156 | if (mod_list) { | |
157 | modinit << "#define SWIGMODINIT "; | |
158 | modextern << "#ifdef __cplusplus\n" | |
159 | << "extern \"C\" {\n" | |
160 | << "#endif\n"; | |
161 | i = 0; | |
162 | while(mod_list[i]) { | |
163 | modinit << "swig_add_module(\"" << mod_list[i] << "\",init" | |
164 | << mod_list[i] << "); \\\n"; | |
165 | ||
166 | modextern << "extern void init" << mod_list[i] << "();\n"; | |
167 | i++; | |
168 | } | |
169 | modextern << "#ifdef __cplusplus\n" | |
170 | << "}\n" | |
171 | << "#endif\n"; | |
172 | modinit << "/* End of extern module initialization */\n"; | |
173 | ||
174 | } | |
175 | } | |
176 | ||
177 | // --------------------------------------------------------------------- | |
178 | // PYTHON::set_init(char *iname) | |
179 | // | |
180 | // Sets the initialization function name. | |
181 | // Does nothing if it's already set | |
182 | // | |
183 | //---------------------------------------------------------------------- | |
184 | ||
185 | void PYTHON::set_init(char *iname) { | |
186 | set_module(iname,0); | |
187 | } | |
188 | ||
189 | ||
190 | // --------------------------------------------------------------------- | |
191 | // PYTHON::import(char *filename) | |
192 | // | |
193 | // Imports a SWIG module as a separate file. | |
194 | //---------------------------------------------------------------------- | |
195 | ||
196 | void PYTHON::import(char *filename) { | |
197 | if (import_file) delete import_file; | |
198 | import_file = copy_string(filename); | |
199 | } | |
200 | ||
201 | // ---------------------------------------------------------------------- | |
202 | // PYTHON::add_method(char *name, char *function) | |
203 | // | |
204 | // Add some symbols to the methods table | |
205 | // ---------------------------------------------------------------------- | |
206 | ||
207 | void PYTHON::add_method(char *name, char *function) { | |
208 | ||
209 | Method *n; | |
210 | ||
211 | n = new Method; | |
212 | n->name = new char[strlen(name)+1]; | |
213 | strcpy(n->name,name); | |
214 | n->function = new char[strlen(function)+1]; | |
215 | strcpy(n->function, function); | |
216 | ||
217 | n->next = head; | |
218 | head = n; | |
219 | } | |
220 | ||
221 | // --------------------------------------------------------------------- | |
222 | // PYTHON::print_methods() | |
223 | // | |
224 | // Prints out the method array. | |
225 | // --------------------------------------------------------------------- | |
226 | ||
227 | void PYTHON::print_methods() { | |
228 | ||
229 | Method *n; | |
230 | ||
231 | fprintf(f_wrappers,"static PyMethodDef %sMethods[] = {\n", module); | |
232 | n = head; | |
233 | while (n) { | |
234 | if (!use_kw) { | |
235 | fprintf(f_wrappers,"\t { \"%s\", %s, METH_VARARGS },\n", n->name, n->function); | |
236 | } else { | |
237 | fprintf(f_wrappers,"\t { \"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS },\n", n->name, n->function); | |
238 | } | |
239 | n = n->next; | |
240 | } | |
241 | fprintf(f_wrappers,"\t { NULL, NULL }\n"); | |
242 | fprintf(f_wrappers,"};\n"); | |
243 | fprintf(f_wrappers,"#ifdef __cplusplus\n"); | |
244 | fprintf(f_wrappers,"}\n"); | |
245 | fprintf(f_wrappers,"#endif\n"); | |
246 | } | |
247 | ||
248 | // --------------------------------------------------------------------- | |
249 | // char *PYTHON::add_docstring(DocEntry *de) | |
250 | // | |
251 | // Adds a documentation entry to the doc-string generator. Returns a | |
252 | // unique character symbol that will be used to fill in the doc-string | |
253 | // at a later time. | |
254 | // --------------------------------------------------------------------- | |
255 | ||
256 | char *PYTHON::add_docstring(DocEntry *de) { | |
257 | DocString *s; | |
258 | String str; | |
259 | ||
260 | str = "@doc"; | |
261 | str << doc_index << "@"; | |
262 | ||
263 | s = new DocString(); | |
264 | s->de = de; | |
265 | s->name = copy_string(str); | |
266 | s->next = doc_strings; | |
267 | doc_strings = s; | |
268 | doc_index++; | |
269 | return s->name; | |
270 | } | |
271 | ||
272 | // --------------------------------------------------------------------- | |
273 | // PYTHON::headers(void) | |
274 | // | |
275 | // ---------------------------------------------------------------------- | |
276 | ||
277 | void PYTHON::headers(void) | |
278 | { | |
279 | ||
280 | emit_banner(f_header); | |
281 | ||
282 | fprintf(f_header,"/* Implementation : PYTHON */\n\n"); | |
283 | fprintf(f_header,"#define SWIGPYTHON\n"); | |
284 | ||
285 | if (!NoInclude) { | |
286 | if (insert_file("python.swg", f_header) == -1) { | |
287 | fprintf(stderr,"SWIG : Fatal error. Unable to locate python.swg. (Possible installation problem).\n"); | |
288 | SWIG_exit(1); | |
289 | } | |
290 | } else { | |
291 | if (insert_file("pyexp.swg", f_header) == -1) { | |
292 | fprintf(stderr,"SWIG : Fatal error. Unable to locate pyexp.swg. (Possible installation problem).\n"); | |
293 | SWIG_exit(1); | |
294 | } | |
295 | } | |
296 | } | |
297 | ||
298 | ||
299 | // -------------------------------------------------------------------- | |
300 | // PYTHON::initialize(void) | |
301 | // | |
302 | // This function outputs the starting code for a function to initialize | |
303 | // your interface. It is only called once by the parser. | |
304 | // | |
305 | // --------------------------------------------------------------------- | |
306 | ||
307 | void PYTHON::initialize(void) | |
308 | { | |
309 | ||
310 | char filen[256]; | |
311 | char *temp; | |
312 | char *oldmodule = 0; | |
313 | ||
314 | if (!module) { | |
315 | module = "swig"; | |
316 | fprintf(stderr,"SWIG : *** Warning. No module name specified.\n"); | |
317 | } | |
318 | ||
319 | // If shadow classing is enabled, we're going to change the module | |
320 | // name to "modulec" | |
321 | ||
322 | if (shadow) { | |
323 | temp = new char[strlen(module)+2]; | |
324 | sprintf(temp,"%sc",module); | |
325 | oldmodule = module; | |
326 | module = temp; | |
327 | } | |
328 | /* Initialize the C code for the module */ | |
329 | initialize_cmodule(); | |
330 | /* Create a shadow file (if enabled).*/ | |
331 | if (shadow) { | |
332 | sprintf(filen,"%s%s.py", output_dir, oldmodule); | |
333 | if ((f_shadow = fopen(filen,"w")) == 0) { | |
334 | fprintf(stderr,"Unable to open %s\n", filen); | |
335 | SWIG_exit(0); | |
336 | } | |
337 | fprintf(f_shadow,"# This file was created automatically by SWIG.\n"); | |
338 | fprintf(f_shadow,"import %s\n", module); | |
339 | } | |
340 | ||
341 | // Dump out external module declarations | |
342 | ||
343 | if (strlen(modinit.get()) > 0) { | |
344 | fprintf(f_header,"%s\n",modinit.get()); | |
345 | } | |
346 | if (strlen(modextern.get()) > 0) { | |
347 | fprintf(f_header,"%s\n",modextern.get()); | |
348 | } | |
349 | fprintf(f_wrappers,"#ifdef __cplusplus\n"); | |
350 | fprintf(f_wrappers,"extern \"C\" {\n"); | |
351 | fprintf(f_wrappers,"#endif\n"); | |
352 | } | |
353 | ||
354 | // --------------------------------------------------------------------- | |
355 | // PYTHON::initialize_cmodule(void) | |
356 | // | |
357 | // Initializes the C module. | |
358 | // | |
359 | // --------------------------------------------------------------------- | |
360 | void PYTHON::initialize_cmodule(void) | |
361 | { | |
362 | int i; | |
363 | fprintf(f_header,"#define SWIG_init init%s\n\n", module); | |
364 | fprintf(f_header,"#define SWIG_name \"%s\"\n", module); | |
365 | ||
366 | // Output the start of the init function. | |
367 | // Modify this to use the proper return type and arguments used | |
368 | // by the target Language | |
369 | ||
370 | fprintf(f_init,"static PyObject *SWIG_globals;\n"); | |
371 | ||
372 | fprintf(f_init,"#ifdef __cplusplus\n"); | |
373 | fprintf(f_init,"extern \"C\" \n"); | |
374 | fprintf(f_init,"#endif\n"); | |
375 | ||
376 | fprintf(f_init,"SWIGEXPORT(void) init%s() {\n",module); | |
377 | fprintf(f_init,"\t PyObject *m, *d;\n"); | |
378 | ||
379 | if (InitNames) { | |
380 | i = 0; | |
381 | while (InitNames[i]) { | |
382 | fprintf(f_init,"\t %s();\n", InitNames[i]); | |
383 | i++; | |
384 | } | |
385 | } | |
386 | fprintf(f_init,"\t SWIG_globals = SWIG_newvarlink();\n"); | |
387 | fprintf(f_init,"\t m = Py_InitModule(\"%s\", %sMethods);\n", module, module); | |
388 | fprintf(f_init,"\t d = PyModule_GetDict(m);\n"); | |
389 | } | |
390 | ||
391 | ||
392 | // --------------------------------------------------------------------- | |
393 | // PYTHON::close(void) | |
394 | // | |
395 | // Called when the end of the interface file is reached. Closes the | |
396 | // initialization function and performs cleanup as necessary. | |
397 | // --------------------------------------------------------------------- | |
398 | ||
399 | void PYTHON::close(void) | |
400 | { | |
401 | ||
402 | print_methods(); | |
403 | close_cmodule(); | |
404 | if ((doc_entry) && (module)){ | |
405 | String temp; | |
406 | temp << "Python Module : "; | |
407 | if (shadow) { | |
408 | module[strlen(module)-1] = 0; | |
409 | } | |
410 | temp << module; | |
411 | doc_entry->cinfo << temp; | |
412 | } | |
413 | if (shadow) { | |
414 | String fullshadow; | |
415 | fullshadow << classes | |
416 | << "\n\n#-------------- FUNCTION WRAPPERS ------------------\n\n" | |
417 | << func | |
418 | << "\n\n#-------------- VARIABLE WRAPPERS ------------------\n\n" | |
419 | << vars; | |
420 | ||
421 | if (strlen(pragma_include) > 0) { | |
422 | fullshadow << "\n\n#-------------- USER INCLUDE -----------------------\n\n" | |
423 | << pragma_include; | |
424 | } | |
425 | ||
426 | // Go through all of the docstrings and replace the docstrings | |
427 | ||
428 | DocString *s; | |
429 | s = doc_strings; | |
430 | while (s) { | |
431 | fullshadow.replace(s->name, s->de->text); | |
432 | s = s->next; | |
433 | } | |
434 | /* | |
435 | fprintf(f_shadow,"\n\n#-------------- FUNCTION WRAPPERS ------------------\n\n"); | |
436 | fprintf(f_shadow,"%s",func.get()); | |
437 | fprintf(f_shadow,"\n\n#-------------- VARIABLE WRAPPERS ------------------\n\n"); | |
438 | fprintf(f_shadow,"%s",vars.get()); | |
439 | if (strlen(pragma_include) > 0) { | |
440 | fprintf(f_shadow,"\n\n#-------------- USER INCLUDE -----------------------\n\n"); | |
441 | fprintf(f_shadow,"%s",pragma_include.get()); | |
442 | } | |
443 | */ | |
444 | fprintf(f_shadow, "%s", fullshadow.get()); | |
445 | fclose(f_shadow); | |
446 | } | |
447 | } | |
448 | ||
449 | // -------------------------------------------------------------------- | |
450 | // PYTHON::close_cmodule(void) | |
451 | // | |
452 | // Called to cleanup the C module code | |
453 | // -------------------------------------------------------------------- | |
454 | void PYTHON::close_cmodule(void) | |
455 | { | |
456 | emit_ptr_equivalence(f_init); | |
457 | fprintf(f_init,"}\n"); | |
458 | } | |
459 | ||
460 | // ---------------------------------------------------------------------- | |
461 | // PYTHON::get_pointer(char *iname, char *srcname, char *src, char *target, | |
462 | // DataType *t, WrapperFunction &f, char *ret) | |
463 | // | |
464 | // Emits code to get a pointer and do type checking. | |
465 | // iname = name of the function/method (used for error messages) | |
466 | // srcname = Name of source (used for error message reporting). | |
467 | // src = name of variable where source string is located. | |
468 | // dest = name of variable where pointer value is stored. | |
469 | // t = Expected datatype of the parameter | |
470 | // f = Wrapper function object being used to generate code. | |
471 | // ret = return code upon failure. | |
472 | // | |
473 | // Note : pointers are stored as strings so you first need to get | |
474 | // a string and then call _swig_get_hex() to extract a point. | |
475 | // | |
476 | // This module is pretty ugly, but type checking is kind of nasty | |
477 | // anyways. | |
478 | // ---------------------------------------------------------------------- | |
479 | ||
480 | void | |
481 | PYTHON::get_pointer(char *iname, char *srcname, char *src, char *dest, | |
482 | DataType *t, String &f, char *ret) | |
483 | { | |
484 | ||
485 | // Now get the pointer value from the string and save in dest | |
486 | ||
1e4a197e RD |
487 | if (t->is_reference) |
488 | f << tab4 << "if (" << src << ") {\n" | |
489 | << tab8 << "if (SWIG_GetPtrObj(" << src << ",(void **) &" << dest << ","; | |
490 | else | |
491 | f << tab4 << "if (" << src << ") {\n" | |
492 | << tab8 << "if (" << src << " == Py_None) { " << dest << " = NULL; }\n" | |
493 | << tab8 << "else if (SWIG_GetPtrObj(" << src << ",(void **) &" << dest << ","; | |
c90f71dd RD |
494 | |
495 | // If we're passing a void pointer, we give the pointer conversion a NULL | |
496 | // pointer, otherwise pass in the expected type. | |
497 | ||
498 | if (t->type == T_VOID) f << "(char *) 0 )) {\n"; | |
499 | else | |
500 | f << "\"" << t->print_mangle() << "\")) {\n"; | |
501 | ||
502 | // This part handles the type checking according to three different | |
503 | // levels. 0 = no checking, 1 = warning message, 2 = strict. | |
504 | ||
505 | switch(TypeStrict) { | |
506 | case 0: // No type checking | |
507 | f << tab8 << "}\n"; | |
508 | break; | |
509 | ||
510 | case 1: // Warning message only | |
511 | ||
512 | // Change this part to how you want to handle a type-mismatch warning. | |
513 | // By default, it will just print to stderr. | |
514 | ||
515 | f << tab8 << tab4 << "fprintf(stderr,\"Warning : type mismatch in " << srcname | |
516 | << " of " << iname << ". Expected " << t->print_mangle() | |
517 | << ", received %s\\n\"," << src << ");\n" | |
518 | << tab8 << "}\n"; | |
519 | ||
520 | break; | |
521 | case 2: // Super strict mode. | |
522 | ||
523 | // Change this part to return an error. | |
524 | ||
525 | f << tab8 << tab4 << "PyErr_SetString(PyExc_TypeError,\"Type error in " << srcname | |
526 | << " of " << iname << ". Expected " << t->print_mangle() << ".\");\n" | |
527 | << tab8 << "return " << ret << ";\n" | |
528 | << tab8 << "}\n"; | |
529 | break; | |
530 | ||
531 | default : | |
532 | fprintf(stderr,"SWIG Error. Unknown strictness level\n"); | |
533 | break; | |
534 | } | |
535 | f << tab4 << "}\n"; | |
536 | } | |
537 | ||
538 | // ---------------------------------------------------------------------- | |
539 | // PYTHON::emit_function_header() | |
540 | // | |
541 | // Return the code to be used as a function header | |
542 | // ---------------------------------------------------------------------- | |
543 | void PYTHON::emit_function_header(WrapperFunction &emit_to, char *wname) | |
544 | { | |
545 | if (!use_kw) { | |
546 | emit_to.def << "static PyObject *" << wname | |
547 | << "(PyObject *self, PyObject *args) {"; | |
548 | } else { | |
549 | emit_to.def << "static PyObject *" << wname | |
550 | << "(PyObject *self, PyObject *args, PyObject *kwargs) {"; | |
551 | } | |
552 | emit_to.code << tab4 << "self = self;\n"; | |
553 | } | |
554 | ||
555 | // ---------------------------------------------------------------------- | |
556 | // PYTHON::convert_self() | |
557 | // | |
558 | // Called during the function generation process, to determine what to | |
559 | // use as the "self" variable during the call. Derived classes may emit code | |
560 | // to convert the real self pointer into a usable pointer. | |
561 | // | |
562 | // Returns the name of the variable to use as the self pointer | |
563 | // ---------------------------------------------------------------------- | |
564 | char *PYTHON::convert_self(WrapperFunction &) | |
565 | { | |
566 | // Default behaviour is no translation | |
567 | return ""; | |
568 | } | |
569 | ||
570 | // ---------------------------------------------------------------------- | |
571 | // PYTHON::make_funcname_wrapper() | |
572 | // | |
573 | // Called to create a name for a wrapper function | |
574 | // ---------------------------------------------------------------------- | |
575 | char *PYTHON::make_funcname_wrapper(char *fnName) | |
576 | { | |
577 | return name_wrapper(fnName,""); | |
578 | } | |
579 | ||
580 | // ---------------------------------------------------------------------- | |
581 | // PYTHON::create_command(char *cname, char *iname) | |
582 | // | |
583 | // Create a new command in the interpreter. Used for C++ inheritance | |
584 | // stuff. | |
585 | // ---------------------------------------------------------------------- | |
586 | ||
587 | void PYTHON::create_command(char *cname, char *iname) { | |
588 | ||
589 | // Create the name of the wrapper function | |
590 | ||
591 | char *wname = name_wrapper(cname,""); | |
592 | ||
593 | // Now register the function with the interpreter. | |
594 | ||
595 | add_method(iname, wname); | |
596 | ||
597 | } | |
598 | ||
599 | // ---------------------------------------------------------------------- | |
600 | // PYTHON::create_function(char *name, char *iname, DataType *d, | |
601 | // ParmList *l) | |
602 | // | |
603 | // This function creates a wrapper function and registers it with the | |
604 | // interpreter. | |
605 | // | |
606 | // Inputs : | |
607 | // name = actual name of the function that's being wrapped | |
608 | // iname = name of the function in the interpreter (may be different) | |
609 | // d = Return datatype of the functions. | |
610 | // l = A linked list containing function parameter information. | |
611 | // | |
612 | // ---------------------------------------------------------------------- | |
613 | ||
614 | void PYTHON::create_function(char *name, char *iname, DataType *d, ParmList *l) | |
615 | { | |
616 | Parm *p; | |
617 | int pcount,i,j; | |
618 | String wname, self_name, call_name; | |
619 | char source[64], target[64], temp[256], argnum[20]; | |
620 | char *usage = 0; | |
621 | WrapperFunction f; | |
622 | String parse_args; | |
623 | String arglist; | |
624 | String get_pointers; | |
625 | String cleanup, outarg; | |
626 | String check; | |
627 | String build; | |
628 | String kwargs; | |
629 | ||
630 | int have_build = 0; | |
631 | char *tm; | |
632 | int numopt = 0; | |
633 | ||
634 | have_output = 0; | |
635 | ||
636 | // Make a valid name for this function. This removes special symbols | |
637 | // that would cause problems in the C compiler. | |
638 | ||
639 | wname = make_funcname_wrapper(iname); | |
640 | ||
641 | // Now emit the function declaration for the wrapper function. You | |
642 | // should modify this to return the appropriate types and use the | |
643 | // appropriate parameters. | |
644 | ||
645 | emit_function_header(f, wname); | |
646 | ||
647 | f.add_local("PyObject *","_resultobj"); | |
648 | ||
649 | // Get the function usage string for later use | |
650 | ||
651 | usage = usage_func(iname,d,l); | |
652 | ||
653 | // Write code to extract function parameters. | |
654 | // This is done in one pass, but we need to construct three independent | |
655 | // pieces. | |
656 | // 1. Python format string such as "iis" | |
657 | // 2. The actual arguments to put values into | |
658 | // 3. Pointer conversion code. | |
659 | // | |
660 | // If there is a type mapping, we will extract the Python argument | |
661 | // as a raw PyObject and let the user deal with it. | |
662 | // | |
663 | ||
664 | pcount = emit_args(d, l, f); | |
665 | if (!use_kw) { | |
666 | parse_args << tab4 << "if(!PyArg_ParseTuple(args,\""; | |
667 | } else { | |
668 | parse_args << tab4 << "if(!PyArg_ParseTupleAndKeywords(args,kwargs,\""; | |
669 | arglist << ",_kwnames"; | |
670 | } | |
671 | ||
672 | i = 0; | |
673 | j = 0; | |
674 | numopt = l->numopt(); // Get number of optional arguments | |
675 | if (numopt) have_defarg = 1; | |
676 | p = l->get_first(); | |
677 | ||
678 | kwargs << "{ "; | |
679 | while (p != 0) { | |
680 | ||
681 | // Generate source and target strings | |
682 | sprintf(source,"_obj%d",i); | |
683 | sprintf(target,"_arg%d",i); | |
684 | sprintf(argnum,"%d",j+1); | |
685 | ||
686 | // Only consider this argument if it's not ignored | |
687 | ||
688 | if (!p->ignore) { | |
689 | arglist << ","; | |
690 | // Add an optional argument separator if needed | |
691 | ||
692 | if (j == pcount-numopt) { | |
693 | parse_args << "|"; | |
694 | } | |
695 | ||
696 | if (strlen(p->name)) { | |
697 | kwargs << "\"" << p->name << "\","; | |
698 | } else { | |
699 | kwargs << "\"arg" << j+1 << "\","; | |
700 | // kwargs << "\"\","; | |
701 | } | |
702 | ||
703 | // Look for input typemap | |
704 | ||
705 | if ((tm = typemap_lookup("in","python",p->t,p->name,source,target,&f))) { | |
706 | parse_args << "O"; // Grab the argument as a raw PyObject | |
707 | f.add_local("PyObject *",source,"0"); | |
708 | arglist << "&" << source; | |
709 | if (i >= (pcount-numopt)) | |
710 | get_pointers << tab4 << "if (" << source << ")\n"; | |
711 | get_pointers << tm << "\n"; | |
712 | get_pointers.replace("$argnum", argnum); | |
713 | get_pointers.replace("$arg",source); | |
714 | } else { | |
715 | ||
716 | // Check if this parameter is a pointer. If not, we'll get values | |
717 | ||
718 | if (!p->t->is_pointer) { | |
719 | // Extract a parameter by "value" | |
720 | ||
721 | switch(p->t->type) { | |
722 | ||
723 | // Handle integers here. Usually this can be done as a single | |
724 | // case if you appropriate cast things. However, if you have | |
725 | // special cases, you'll need to add more code. | |
726 | ||
727 | case T_INT : case T_UINT: case T_SINT: | |
728 | parse_args << "i"; | |
729 | break; | |
730 | case T_SHORT: case T_USHORT: case T_SSHORT: | |
731 | parse_args << "h"; | |
732 | break; | |
733 | case T_LONG : case T_ULONG: case T_SLONG : | |
734 | parse_args << "l"; | |
735 | break; | |
736 | case T_SCHAR : case T_UCHAR : | |
737 | parse_args << "b"; | |
738 | break; | |
739 | case T_CHAR: | |
740 | parse_args << "c"; | |
741 | break; | |
742 | case T_FLOAT : | |
743 | parse_args << "f"; | |
744 | break; | |
745 | case T_DOUBLE: | |
746 | parse_args << "d"; | |
747 | break; | |
748 | ||
749 | case T_BOOL: | |
750 | { | |
751 | String tempb; | |
752 | String tempval; | |
753 | if (p->defvalue) { | |
754 | tempval << "(int) " << p->defvalue; | |
755 | } | |
756 | tempb << "tempbool" << i; | |
757 | parse_args << "i"; | |
758 | if (!p->defvalue) | |
759 | f.add_local("int",tempb.get()); | |
760 | else | |
761 | f.add_local("int",tempb.get(),tempval.get()); | |
762 | get_pointers << tab4 << target << " = " << p->t->print_cast() << " " << tempb << ";\n"; | |
763 | arglist << "&" << tempb; | |
764 | } | |
765 | break; | |
766 | ||
767 | // Void.. Do nothing. | |
768 | ||
769 | case T_VOID : | |
770 | break; | |
771 | ||
772 | // User defined. This is usually invalid. No way to pass a | |
773 | // complex type by "value". We'll just pass into the unsupported | |
774 | // datatype case. | |
775 | ||
776 | case T_USER: | |
777 | ||
778 | // Unsupported data type | |
779 | ||
780 | default : | |
781 | fprintf(stderr,"%s : Line %d. Unable to use type %s as a function argument.\n",input_file, line_number, p->t->print_type()); | |
782 | break; | |
783 | } | |
784 | ||
785 | // Emit code for parameter list | |
786 | ||
787 | if ((p->t->type != T_VOID) && (p->t->type != T_BOOL)) | |
788 | arglist << "&_arg" << i; | |
789 | ||
790 | } else { | |
791 | ||
792 | // Is some other kind of variable. | |
793 | ||
794 | if ((p->t->type == T_CHAR) && (p->t->is_pointer == 1)) { | |
795 | parse_args << "s"; | |
796 | arglist << "&_arg" << i; | |
797 | } else { | |
798 | ||
799 | // Have some sort of pointer variable. Create a temporary local | |
800 | // variable for the string and read the pointer value into it. | |
801 | ||
802 | parse_args << "O"; | |
803 | sprintf(source,"_argo%d", i); | |
804 | sprintf(target,"_arg%d", i); | |
805 | sprintf(temp,"argument %d",i+1); | |
806 | ||
807 | f.add_local("PyObject *", source,"0"); | |
808 | arglist << "&" << source; | |
809 | get_pointer(iname, temp, source, target, p->t, get_pointers, "NULL"); | |
810 | } | |
811 | } | |
812 | } | |
813 | j++; | |
814 | } | |
815 | // Check if there was any constraint code | |
816 | if ((tm = typemap_lookup("check","python",p->t,p->name,source,target))) { | |
817 | check << tm << "\n"; | |
818 | check.replace("$argnum", argnum); | |
819 | } | |
820 | // Check if there was any cleanup code | |
821 | if ((tm = typemap_lookup("freearg","python",p->t,p->name,target,source))) { | |
822 | cleanup << tm << "\n"; | |
823 | cleanup.replace("$argnum", argnum); | |
824 | cleanup.replace("$arg",source); | |
825 | } | |
826 | if ((tm = typemap_lookup("argout","python",p->t,p->name,target,"_resultobj"))) { | |
827 | outarg << tm << "\n"; | |
828 | outarg.replace("$argnum", argnum); | |
829 | outarg.replace("$arg",source); | |
830 | have_output++; | |
831 | } | |
832 | if ((tm = typemap_lookup("build","python",p->t,p->name,source,target))) { | |
833 | build << tm << "\n"; | |
834 | have_build = 1; | |
835 | } | |
836 | p = l->get_next(); | |
837 | i++; | |
838 | } | |
839 | ||
840 | kwargs << " NULL }"; | |
841 | if (use_kw) { | |
842 | f.locals << tab4 << "char *_kwnames[] = " << kwargs << ";\n"; | |
843 | } | |
844 | ||
845 | parse_args << ":" << iname << "\""; // No additional arguments | |
846 | parse_args << arglist << ")) \n" | |
847 | << tab8 << "return NULL;\n"; | |
848 | ||
849 | self_name = convert_self(f); | |
850 | ||
851 | /* Now slap the whole first part of the wrapper function together */ | |
852 | ||
853 | f.code << parse_args << get_pointers << check; | |
854 | ||
855 | ||
856 | // Special handling for build values | |
857 | ||
858 | if (have_build) { | |
859 | char temp1[256]; | |
860 | char temp2[256]; | |
861 | l->sub_parmnames(build); // Replace all parameter names | |
862 | for (i = 0; i < l->nparms; i++) { | |
863 | p = l->get(i); | |
864 | if (strlen(p->name) > 0) { | |
865 | sprintf(temp1,"_in_%s", p->name); | |
866 | } else { | |
867 | sprintf(temp1,"_in_arg%d", i); | |
868 | } | |
869 | sprintf(temp2,"_obj%d",i); | |
870 | build.replaceid(temp1,temp2); | |
871 | } | |
872 | f.code << build; | |
873 | } | |
874 | ||
875 | // This function emits code to call the real function. Assuming you read | |
876 | // the parameters in correctly, this will work. | |
877 | ||
878 | call_name = ""; | |
879 | call_name << self_name << name; | |
880 | emit_func_call(call_name,d,l,f); | |
881 | ||
882 | // Now emit code to return the functions return value (if any). | |
883 | // If there was a result, it was saved in _result. | |
884 | // If the function is a void type, don't do anything. | |
885 | ||
886 | if ((strncmp(name, "new_", 4) != 0) && // don't use the out typemap for constructors | |
887 | (tm = typemap_lookup("out","python",d,iname,"_result","_resultobj"))) { | |
888 | // Yep. Use it instead of the default | |
889 | f.code << tm << "\n"; | |
890 | } else { | |
891 | ||
892 | if ((d->type != T_VOID) || (d->is_pointer)) { | |
893 | // Now have return value, figure out what to do with it. | |
894 | ||
895 | if (!d->is_pointer) { | |
896 | ||
897 | // Function returns a "value" | |
898 | ||
899 | switch(d->type) { | |
900 | ||
901 | // Return an integer type | |
902 | ||
903 | case T_INT: case T_SINT: case T_UINT: case T_BOOL: | |
904 | f.code << tab4 << "_resultobj = Py_BuildValue(\"i\",_result);\n"; | |
905 | break; | |
906 | case T_SHORT: case T_SSHORT: case T_USHORT: | |
907 | f.code << tab4 << "_resultobj = Py_BuildValue(\"h\",_result);\n"; | |
908 | break; | |
909 | case T_LONG : case T_SLONG : case T_ULONG: | |
910 | f.code << tab4 << "_resultobj = Py_BuildValue(\"l\",_result);\n"; | |
911 | break; | |
912 | case T_SCHAR: case T_UCHAR : | |
913 | f.code << tab4 << "_resultobj = Py_BuildValue(\"b\",_result);\n"; | |
914 | break; | |
915 | ||
916 | // Return a floating point value | |
917 | ||
918 | case T_DOUBLE : | |
919 | f.code << tab4 << "_resultobj = Py_BuildValue(\"d\",_result);\n"; | |
920 | break; | |
921 | case T_FLOAT : | |
922 | f.code << tab4 << "_resultobj = Py_BuildValue(\"f\",_result);\n"; | |
923 | break; | |
924 | ||
925 | // Return a single ASCII value. Usually we need to convert | |
926 | // it to a NULL-terminate string and return that instead. | |
927 | ||
928 | case T_CHAR : | |
929 | f.code << tab4 << "_resultobj = Py_BuildValue(\"c\",_result);\n"; | |
930 | break; | |
931 | ||
932 | case T_USER : | |
933 | ||
934 | // Return something by value | |
935 | // We're living dangerously here, but life is short...play hard | |
936 | ||
937 | // Oops. Need another local variable | |
938 | f.add_local("char","_ptemp[128]"); | |
939 | ||
940 | d->is_pointer++; | |
941 | f.code << tab4 << "SWIG_MakePtr(_ptemp, (void *) _result,\"" | |
942 | << d->print_mangle() << "\");\n"; | |
943 | d->is_pointer--; | |
944 | // Return a character string containing our pointer. | |
945 | ||
946 | f.code << tab4 << "_resultobj = Py_BuildValue(\"s\",_ptemp);\n"; | |
947 | break; | |
948 | default : | |
949 | fprintf(stderr,"%s: Line %d. Unable to use return type %s in function %s.\n", input_file, line_number, d->print_type(), name); | |
950 | break; | |
951 | } | |
952 | } else { | |
953 | ||
954 | // Return type is a pointer. We'll see if it's a char * and return | |
955 | // a string. Otherwise, we'll convert it into a SWIG pointer and return | |
956 | // that. | |
957 | ||
958 | if ((d->type == T_CHAR) && (d->is_pointer == 1)) { | |
959 | ||
960 | // Return a character string | |
961 | f.code << tab4 << "_resultobj = Py_BuildValue(\"s\", _result);\n"; | |
962 | ||
963 | // If declared as a new object, free the result | |
964 | ||
965 | } else { | |
966 | ||
967 | // Build a SWIG pointer. | |
968 | f.add_local("char","_ptemp[128]"); | |
969 | f.code << tab4 << "if (_result) {\n" | |
970 | << tab8 << "SWIG_MakePtr(_ptemp, (char *) _result,\"" | |
971 | << d->print_mangle() << "\");\n"; | |
972 | ||
973 | // Return a character string containing our pointer. | |
974 | f.code << tab8 << "_resultobj = Py_BuildValue(\"s\",_ptemp);\n"; | |
975 | f.code << tab4 << "} else {\n" | |
976 | << tab8 << "Py_INCREF(Py_None);\n" | |
977 | << tab8 << "_resultobj = Py_None;\n" | |
978 | << tab4 << "}\n"; | |
979 | } | |
980 | } | |
981 | } else { | |
982 | // no return value and no output args | |
983 | //if (!have_output) { | |
984 | f.code << tab4 << "Py_INCREF(Py_None);\n"; | |
985 | f.code << tab4 << "_resultobj = Py_None;\n"; | |
986 | //} | |
987 | } | |
988 | } | |
989 | ||
990 | // Check to see if there were any output arguments, if so we're going to | |
991 | // create a Python list object out of the current result | |
992 | ||
993 | f.code << outarg; | |
994 | ||
995 | // If there was any other cleanup needed, do that | |
996 | ||
997 | f.code << cleanup; | |
998 | ||
999 | // Look to see if there is any newfree cleanup code | |
1000 | ||
1001 | if (NewObject) { | |
1002 | if ((tm = typemap_lookup("newfree","python",d,iname,"_result",""))) { | |
1003 | f.code << tm << "\n"; | |
1004 | } | |
1005 | } | |
1006 | ||
1007 | // See if there is any argument cleanup code | |
1008 | ||
1009 | if ((tm = typemap_lookup("ret","python",d,iname,"_result",""))) { | |
1010 | // Yep. Use it instead of the default | |
1011 | f.code << tm << "\n"; | |
1012 | } | |
1013 | ||
1014 | f.code << tab4 << "return _resultobj;\n"; | |
1015 | f.code << "}\n"; | |
1016 | ||
1017 | // Substitute the cleanup code | |
1018 | f.code.replace("$cleanup",cleanup); | |
1019 | ||
1020 | // Substitute the function name | |
1021 | f.code.replace("$name",iname); | |
1022 | ||
1023 | // Dump the function out | |
1024 | f.print(f_wrappers); | |
1025 | ||
1026 | // Now register the function with the interpreter. | |
1027 | ||
1028 | add_method(iname, wname); | |
1029 | ||
1030 | // Create a documentation entry for this | |
1031 | ||
1032 | if (doc_entry) { | |
1033 | static DocEntry *last_doc_entry = 0; | |
1034 | doc_entry->usage << usage; | |
1035 | if (last_doc_entry != doc_entry) { | |
1036 | doc_entry->cinfo << "returns " << d->print_type(); | |
1037 | last_doc_entry = doc_entry; | |
1038 | } | |
1039 | } | |
1040 | ||
1041 | // --------------------------------------------------------------------------- | |
1042 | // Create a shadow for this function (if enabled and not in a member function) | |
1043 | // --------------------------------------------------------------------------- | |
1044 | ||
1045 | if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { | |
1046 | String translate; | |
1047 | ||
1048 | int need_wrapper = 0; | |
1049 | int munge_return = 0; | |
1050 | int have_optional = 0; | |
1051 | ||
1052 | // Check return code for modification | |
1053 | if ((hash.lookup(d->name)) && (d->is_pointer <=1)) { | |
1054 | need_wrapper = 1; | |
1055 | munge_return = 1; | |
1056 | } | |
1057 | ||
1058 | if (docstring && doc_entry) | |
1059 | need_wrapper = 1; | |
1060 | ||
1061 | // If no modification is needed. We're just going to play some | |
1062 | // symbol table games instead | |
1063 | ||
1064 | if (!need_wrapper) { | |
1065 | func << iname << " = " << module << "." << iname << "\n\n"; | |
1066 | } else { | |
1067 | func << "def " << iname << "(*_args, **_kwargs):\n"; | |
1068 | ||
1069 | // Create a docstring for this | |
1070 | if (docstring && doc_entry) { | |
1071 | func << tab4 << "\"\"\"" << add_docstring(doc_entry) << "\"\"\"\n"; | |
1072 | } | |
1073 | ||
1074 | func << tab4 << "val = apply(" << module << "." << iname << ",_args,_kwargs)\n"; | |
1075 | ||
1076 | if (munge_return) { | |
1077 | // If the output of this object has been remapped in any way, we're | |
1078 | // going to return it as a bare object. | |
1079 | ||
1080 | if (!typemap_check("out",typemap_lang,d,iname)) { | |
1081 | ||
1082 | // If there are output arguments, we are going to return the value | |
1083 | // unchanged. Otherwise, emit some shadow class conversion code. | |
1084 | ||
1085 | if (!have_output) { | |
1086 | func << tab4 << "if val: val = " << (char *) hash.lookup(d->name) << "Ptr(val)"; | |
1087 | if (((hash.lookup(d->name)) && (d->is_pointer < 1)) || | |
1088 | ((hash.lookup(d->name)) && (d->is_pointer == 1) && NewObject)) | |
1089 | func << "; val.thisown = 1\n"; | |
1090 | else | |
1091 | func << "\n"; | |
1092 | } else { | |
1093 | // Does nothing--returns the value unmolested | |
1094 | } | |
1095 | } | |
1096 | } | |
1097 | func << tab4 << "return val\n\n"; | |
1098 | } | |
1099 | } | |
1100 | } | |
1101 | ||
1102 | // ----------------------------------------------------------------------- | |
1103 | // PYTHON::link_variable(char *name, char *iname, DataType *d) | |
1104 | // | |
1105 | // Input variables: | |
1106 | // name = the real name of the variable being linked | |
1107 | // iname = Name of the variable in the interpreter (may be different) | |
1108 | // d = Datatype of the variable. | |
1109 | // | |
1110 | // This creates a pair of functions for evaluating/setting the value | |
1111 | // of a variable. These are then added to the special SWIG global | |
1112 | // variable type. | |
1113 | // ----------------------------------------------------------------------- | |
1114 | ||
1115 | void PYTHON::link_variable(char *name, char *iname, DataType *t) { | |
1116 | ||
1117 | char *wname; | |
1118 | static int have_globals = 0; | |
1119 | char *tm; | |
1120 | ||
1121 | WrapperFunction getf, setf; | |
1122 | ||
1123 | // If this is our first call, add the globals variable to the | |
1124 | // Python dictionary. | |
1125 | ||
1126 | if (!have_globals) { | |
1127 | fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", SWIG_globals);\n",global_name); | |
1128 | have_globals=1; | |
1129 | if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { | |
1130 | vars << global_name << " = " << module << "." << global_name << "\n"; | |
1131 | } | |
1132 | } | |
1133 | // First make a sanitized version of the function name (in case it's some | |
1134 | // funky C++ thing). | |
1135 | ||
1136 | wname = name_wrapper(name,""); | |
1137 | ||
1138 | // --------------------------------------------------------------------- | |
1139 | // Create a function for setting the value of the variable | |
1140 | // --------------------------------------------------------------------- | |
1141 | ||
1142 | setf.def << "static int " << wname << "_set(PyObject *val) {"; | |
1143 | if (!(Status & STAT_READONLY)) { | |
1144 | if ((tm = typemap_lookup("varin","python",t,name,"val",name))) { | |
1145 | setf.code << tm << "\n"; | |
1146 | setf.code.replace("$name",iname); | |
1147 | } else { | |
1148 | if ((t->type != T_VOID) || (t->is_pointer)) { | |
1149 | if (!t->is_pointer) { | |
1150 | ||
1151 | // Have a real value here | |
1152 | ||
1153 | switch(t->type) { | |
1154 | case T_INT: case T_SHORT: case T_LONG : | |
1155 | case T_UINT: case T_USHORT: case T_ULONG: | |
1156 | case T_SINT: case T_SSHORT: case T_SLONG: | |
1157 | case T_SCHAR: case T_UCHAR: case T_BOOL: | |
1158 | // Get an integer value | |
1159 | setf.add_local(t->print_type(), "tval"); | |
1160 | setf.code << tab4 << "tval = " << t->print_cast() << "PyInt_AsLong(val);\n" | |
1161 | << tab4 << "if (PyErr_Occurred()) {\n" | |
1162 | << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" | |
1163 | << iname << "'(" << t->print_type() << ")\");\n" | |
1164 | << tab8 << "return 1; \n" | |
1165 | << tab4 << "}\n" | |
1166 | << tab4 << name << " = tval;\n"; | |
1167 | break; | |
1168 | ||
1169 | case T_FLOAT: case T_DOUBLE: | |
1170 | // Get a floating point value | |
1171 | setf.add_local(t->print_type(), "tval"); | |
1172 | setf.code << tab4 << "tval = " << t->print_cast() << "PyFloat_AsDouble(val);\n" | |
1173 | << tab4 << "if (PyErr_Occurred()) {\n" | |
1174 | << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" | |
1175 | << iname << "'(" << t->print_type() << ")\");\n" | |
1176 | << tab8 << "return 1; \n" | |
1177 | << tab4 << "}\n" | |
1178 | << tab4 << name << " = tval;\n"; | |
1179 | break; | |
1180 | ||
1181 | // A single ascii character | |
1182 | ||
1183 | case T_CHAR: | |
1184 | setf.add_local("char *", "tval"); | |
1185 | setf.code << tab4 << "tval = (char *) PyString_AsString(val);\n" | |
1186 | << tab4 << "if (PyErr_Occurred()) {\n" | |
1187 | << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" | |
1188 | << iname << "'(" << t->print_type() << ")\");\n" | |
1189 | << tab8 << "return 1; \n" | |
1190 | << tab4 << "}\n" | |
1191 | << tab4 << name << " = *tval;\n"; | |
1192 | break; | |
1193 | case T_USER: | |
1194 | t->is_pointer++; | |
1195 | setf.add_local(t->print_type(),"temp"); | |
1196 | get_pointer(iname,"value","val","temp",t,setf.code,"1"); | |
1197 | setf.code << tab4 << name << " = *temp;\n"; | |
1198 | t->is_pointer--; | |
1199 | break; | |
1200 | default: | |
1201 | fprintf(stderr,"%s : Line %d. Unable to link with type %s.\n", input_file, line_number, t->print_type()); | |
1202 | } | |
1203 | } else { | |
1204 | ||
1205 | // Parse a pointer value | |
1206 | ||
1207 | if ((t->type == T_CHAR) && (t->is_pointer == 1)) { | |
1208 | setf.add_local("char *", "tval"); | |
1209 | setf.code << tab4 << "tval = (char *) PyString_AsString(val);\n" | |
1210 | << tab4 << "if (PyErr_Occurred()) {\n" | |
1211 | << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" | |
1212 | << iname << "'(" << t->print_type() << ")\");\n" | |
1213 | << tab8 << "return 1; \n" | |
1214 | << tab4 << "}\n"; | |
1215 | ||
1216 | if (CPlusPlus) { | |
1217 | setf.code << tab4 << "if (" << name << ") delete [] " << name << ";\n" | |
1218 | << tab4 << name << " = new char[strlen(tval)+1];\n" | |
1219 | << tab4 << "strcpy((char *)" << name << ",tval);\n"; | |
1220 | } else { | |
1221 | setf.code << tab4 << "if (" << name << ") free(" << name << ");\n" | |
1222 | << tab4 << name << " = (char *) malloc(strlen(tval)+1);\n" | |
1223 | << tab4 << "strcpy((char *)" << name << ",tval);\n"; | |
1224 | } | |
1225 | } else { | |
1226 | ||
1227 | // Is a generic pointer value. | |
1228 | ||
1229 | setf.add_local(t->print_type(),"temp"); | |
1230 | get_pointer(iname,"value","val","temp",t,setf.code,"1"); | |
1231 | setf.code << tab4 << name << " = temp;\n"; | |
1232 | } | |
1233 | } | |
1234 | } | |
1235 | } | |
1236 | setf.code << tab4 << "return 0;\n"; | |
1237 | } else { | |
1238 | // Is a readonly variable. Issue an error | |
1239 | setf.code << tab4 << "PyErr_SetString(PyExc_TypeError,\"Variable " << iname | |
1240 | << " is read-only.\");\n" | |
1241 | << tab4 << "return 1;\n"; | |
1242 | } | |
1243 | ||
1244 | setf.code << "}\n"; | |
1245 | ||
1246 | // Dump out function for setting value | |
1247 | ||
1248 | setf.print(f_wrappers); | |
1249 | ||
1250 | // ---------------------------------------------------------------- | |
1251 | // Create a function for getting the value of a variable | |
1252 | // ---------------------------------------------------------------- | |
1253 | ||
1254 | getf.def << "static PyObject *" << wname << "_get() {"; | |
1255 | getf.add_local("PyObject *","pyobj"); | |
1256 | if ((tm = typemap_lookup("varout","python",t,name,name,"pyobj"))) { | |
1257 | getf.code << tm << "\n"; | |
1258 | getf.code.replace("$name",iname); | |
1259 | } else if ((tm = typemap_lookup("out","python",t,name,name,"pyobj"))) { | |
1260 | getf.code << tm << "\n"; | |
1261 | getf.code.replace("$name",iname); | |
1262 | } else { | |
1263 | if ((t->type != T_VOID) || (t->is_pointer)) { | |
1264 | if (!t->is_pointer) { | |
1265 | ||
1266 | /* Is a normal datatype */ | |
1267 | switch(t->type) { | |
1268 | case T_INT: case T_SINT: case T_UINT: | |
1269 | case T_SHORT: case T_SSHORT: case T_USHORT: | |
1270 | case T_LONG: case T_SLONG: case T_ULONG: | |
1271 | case T_SCHAR: case T_UCHAR: case T_BOOL: | |
1272 | getf.code << tab4 << "pyobj = PyInt_FromLong((long) " << name << ");\n"; | |
1273 | break; | |
1274 | case T_FLOAT: case T_DOUBLE: | |
1275 | getf.code << tab4 << "pyobj = PyFloat_FromDouble((double) " << name << ");\n"; | |
1276 | break; | |
1277 | case T_CHAR: | |
1278 | getf.add_local("char","ptemp[2]"); | |
1279 | getf.code << tab4 << "ptemp[0] = " << name << ";\n" | |
1280 | << tab4 << "ptemp[1] = 0;\n" | |
1281 | << tab4 << "pyobj = PyString_FromString(ptemp);\n"; | |
1282 | break; | |
1283 | case T_USER: | |
1284 | // Hack this into a pointer | |
1285 | getf.add_local("char", "ptemp[128]"); | |
1286 | t->is_pointer++; | |
1287 | getf.code << tab4 << "SWIG_MakePtr(ptemp,(char *) &" << name | |
1288 | << "," << quote << t->print_mangle() << quote << ");\n" | |
1289 | << tab4 << "pyobj = PyString_FromString(ptemp);\n"; | |
1290 | t->is_pointer--; | |
1291 | break; | |
1292 | default: | |
1293 | fprintf(stderr,"Unable to link with type %s\n", t->print_type()); | |
1294 | break; | |
1295 | } | |
1296 | } else { | |
1297 | ||
1298 | // Is some sort of pointer value | |
1299 | if ((t->type == T_CHAR) && (t->is_pointer == 1)) { | |
1300 | getf.code << tab4 << "if (" << name << ")\n" | |
1301 | << tab8 << "pyobj = PyString_FromString(" << name << ");\n" | |
1302 | << tab4 << "else pyobj = PyString_FromString(\"(NULL)\");\n"; | |
1303 | } else { | |
1304 | getf.add_local("char","ptemp[128]"); | |
1305 | getf.code << tab4 << "SWIG_MakePtr(ptemp, (char *) " << name << ",\"" | |
1306 | << t->print_mangle() << "\");\n" | |
1307 | << tab4 << "pyobj = PyString_FromString(ptemp);\n"; | |
1308 | } | |
1309 | } | |
1310 | } | |
1311 | } | |
1312 | ||
1313 | getf.code << tab4 << "return pyobj;\n" | |
1314 | << "}\n"; | |
1315 | ||
1316 | getf.print(f_wrappers); | |
1317 | ||
1318 | // Now add this to the variable linking mechanism | |
1319 | ||
1320 | fprintf(f_init,"\t SWIG_addvarlink(SWIG_globals,\"%s\",%s_get, %s_set);\n", iname, wname, wname); | |
1321 | ||
1322 | ||
1323 | // Fill in the documentation entry | |
1324 | ||
1325 | if (doc_entry) { | |
1326 | doc_entry->usage << usage_var(iname, t); | |
1327 | doc_entry->cinfo << "Global : " << t->print_type() << " " << name; | |
1328 | } | |
1329 | ||
1330 | // ---------------------------------------------------------- | |
1331 | // Output a shadow variable. (If applicable and possible) | |
1332 | // ---------------------------------------------------------- | |
1333 | if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { | |
1334 | if ((hash.lookup(t->name)) && (t->is_pointer <= 1)) { | |
1335 | vars << iname << " = " << (char *) hash.lookup(t->name) << "Ptr(" << module << "." << global_name | |
1336 | << "." << iname << ")\n"; | |
1337 | } | |
1338 | } | |
1339 | } | |
1340 | ||
1341 | // ----------------------------------------------------------------------- | |
1342 | // PYTHON::declare_const(char *name, char *iname, DataType *type, char *value) | |
1343 | // | |
1344 | // Makes a constant as defined with #define. Constants are added to the | |
1345 | // module's dictionary and are **NOT** guaranteed to be read-only, | |
1346 | // sorry. | |
1347 | // | |
1348 | // ------------------------------------------------------------------------ | |
1349 | ||
1350 | void PYTHON::declare_const(char *name, char *, DataType *type, char *value) { | |
1351 | ||
1352 | char *tm; | |
1353 | ||
1354 | // Make a static python object | |
1355 | ||
1356 | if ((tm = typemap_lookup("const","python",type,name,value,name))) { | |
1357 | fprintf(f_init,"%s\n",tm); | |
1358 | } else { | |
1359 | ||
1360 | if ((type->type == T_USER) && (!type->is_pointer)) { | |
1361 | fprintf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number); | |
1362 | return; | |
1363 | } | |
1364 | ||
1365 | if (type->is_pointer == 0) { | |
1366 | switch(type->type) { | |
1367 | case T_INT:case T_SINT: case T_UINT: case T_BOOL: | |
1368 | case T_SHORT: case T_SSHORT: case T_USHORT: | |
1369 | case T_LONG: case T_SLONG: case T_ULONG: | |
1370 | case T_SCHAR: case T_UCHAR: | |
1371 | fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyInt_FromLong((long) %s));\n",name,value); | |
1372 | break; | |
1373 | case T_DOUBLE: | |
1374 | case T_FLOAT: | |
1375 | fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyFloat_FromDouble((double) %s));\n",name,value); | |
1376 | break; | |
1377 | case T_CHAR : | |
1378 | fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyString_FromString(\"%s\"));\n",name,value); | |
1379 | break; | |
1380 | default: | |
1381 | fprintf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number); | |
1382 | break; | |
1383 | } | |
1384 | } else { | |
1385 | if ((type->type == T_CHAR) && (type->is_pointer == 1)) { | |
1386 | fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyString_FromString(\"%s\"));\n",name,value); | |
1387 | } else { | |
1388 | // A funky user-defined type. We're going to munge it into a string pointer value | |
1389 | fprintf(f_init,"\t {\n"); | |
1390 | fprintf(f_init,"\t\t char %s_char[%d];\n", name, (int) strlen(type->print_mangle()) + 20); | |
1391 | fprintf(f_init,"\t\t SWIG_MakePtr(%s_char, (void *) (%s),\"%s\");\n", | |
1392 | name, value, type->print_mangle()); | |
1393 | fprintf(f_init,"\t\t PyDict_SetItemString(d,\"%s\", PyString_FromString(%s_char));\n",name,name); | |
1394 | fprintf(f_init,"\t }\n"); | |
1395 | } | |
1396 | } | |
1397 | } | |
1398 | if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { | |
1399 | vars << name << " = " << module << "." << name << "\n"; | |
1400 | } | |
1401 | if (doc_entry) { | |
1402 | doc_entry->usage = ""; | |
1403 | doc_entry->usage << usage_const(name,type,value); | |
1404 | doc_entry->cinfo = ""; | |
1405 | doc_entry->cinfo << "Constant: " << type->print_type(); | |
1406 | } | |
1407 | } | |
1408 | ||
1409 | // ---------------------------------------------------------------------- | |
1410 | // PYTHON::usage_var(char *iname, DataType *t) | |
1411 | // | |
1412 | // This function produces a string indicating how to use a variable. | |
1413 | // It is called by the documentation system to produce syntactically | |
1414 | // correct documentation entires. | |
1415 | // | |
1416 | // s is a pointer to a character pointer. You should create | |
1417 | // a string and set this pointer to point to it. | |
1418 | // ---------------------------------------------------------------------- | |
1419 | ||
1420 | char *PYTHON::usage_var(char *iname, DataType *) { | |
1421 | ||
1422 | static String temp; | |
1423 | ||
1424 | temp = ""; | |
1425 | temp << global_name << "." << iname; | |
1426 | ||
1427 | // Create result. Don't modify this | |
1428 | ||
1429 | return temp.get(); | |
1430 | } | |
1431 | ||
1432 | // --------------------------------------------------------------------------- | |
1433 | // PYTHON::usage_func(char *iname, DataType *t, ParmList *l) | |
1434 | // | |
1435 | // Produces a string indicating how to call a function in the target | |
1436 | // language. | |
1437 | // | |
1438 | // --------------------------------------------------------------------------- | |
1439 | ||
1440 | char *PYTHON::usage_func(char *iname, DataType *, ParmList *l) { | |
1441 | ||
1442 | static String temp; | |
1443 | Parm *p; | |
1444 | int i; | |
1445 | ||
1446 | temp = ""; | |
1447 | temp << iname << "("; | |
1448 | ||
1449 | // Now go through and print parameters | |
1450 | // You probably don't need to change this | |
1451 | ||
1452 | i = 0; | |
1453 | p = l->get_first(); | |
1454 | while (p != 0) { | |
1455 | if (!p->ignore) { | |
1456 | i++; | |
1457 | /* If parameter has been named, use that. Otherwise, just print a type */ | |
1458 | ||
1459 | if ((p->t->type != T_VOID) || (p->t->is_pointer)) { | |
1460 | if (strlen(p->name) > 0) { | |
1461 | temp << p->name; | |
1462 | } else { | |
1463 | temp << p->t->print_type(); | |
1464 | } | |
1465 | } | |
1466 | p = l->get_next(); | |
1467 | if (p != 0) { | |
1468 | if (!p->ignore) | |
1469 | temp << ","; | |
1470 | } | |
1471 | } else { | |
1472 | p = l->get_next(); | |
1473 | if (p) { | |
1474 | if ((!p->ignore) && (i > 0)) | |
1475 | temp << ","; | |
1476 | } | |
1477 | } | |
1478 | } | |
1479 | ||
1480 | temp << ")"; | |
1481 | ||
1482 | // Create result. Don't change this | |
1483 | ||
1484 | return temp.get(); | |
1485 | ||
1486 | } | |
1487 | ||
1488 | ||
1489 | // ---------------------------------------------------------------------- | |
1490 | // PYTHON::usage_const(char *iname, DataType *type, char *value) | |
1491 | // | |
1492 | // Produces a string for a constant. Really about the same as | |
1493 | // usage_var() except we'll indicate the value of the constant. | |
1494 | // ---------------------------------------------------------------------- | |
1495 | ||
1496 | char *PYTHON::usage_const(char *iname, DataType *, char *value) { | |
1497 | ||
1498 | static String temp; | |
1499 | temp = ""; | |
1500 | temp << iname << " = " << value; | |
1501 | ||
1502 | return temp.get(); | |
1503 | } | |
1504 | ||
1505 | // ----------------------------------------------------------------------- | |
1506 | // PYTHON::add_native(char *name, char *funcname) | |
1507 | // | |
1508 | // Add a native module name to the methods list. | |
1509 | // ----------------------------------------------------------------------- | |
1510 | ||
1511 | void PYTHON::add_native(char *name, char *funcname) { | |
1512 | add_method(name, funcname); | |
1513 | if (shadow) { | |
1514 | func << name << " = " << module << "." << name << "\n\n"; | |
1515 | } | |
1516 | } | |
1517 | ||
1518 | // ----------------------------------------------------------------------- | |
1519 | // PYTHON::cpp_class_decl(char *name, char *rename, char *type) | |
1520 | // | |
1521 | // Treatment of an empty class definition. Used to handle | |
1522 | // shadow classes across modules. | |
1523 | // ----------------------------------------------------------------------- | |
1524 | ||
1525 | void PYTHON::cpp_class_decl(char *name, char *rename, char *type) { | |
1526 | char temp[256]; | |
1527 | if (shadow) { | |
1528 | hash.add(name,copy_string(rename)); | |
1529 | // Add full name of datatype to the hash table | |
1530 | if (strlen(type) > 0) { | |
1531 | sprintf(temp,"%s %s", type, name); | |
1532 | hash.add(temp,copy_string(rename)); | |
1533 | } | |
1534 | } | |
1535 | } | |
1536 | ||
1537 | // ----------------------------------------------------------------------- | |
1538 | // PYTHON::pragma(char *name, char *type) | |
1539 | // | |
1540 | // Pragma directive. Used to do various python specific things | |
1541 | // ----------------------------------------------------------------------- | |
1542 | ||
1543 | void PYTHON::pragma(char *lang, char *cmd, char *value) { | |
1544 | ||
1545 | if (strcmp(lang,"python") == 0) { | |
1546 | if (strcmp(cmd,"CODE") == 0) { | |
1547 | if (shadow) { | |
1548 | fprintf(f_shadow,"%s\n",value); | |
1549 | } | |
1550 | } else if (strcmp(cmd,"code") == 0) { | |
1551 | if (shadow) { | |
1552 | fprintf(f_shadow,"%s\n",value); | |
1553 | } | |
1554 | } else if (strcmp(cmd,"include") == 0) { | |
1555 | if (shadow) { | |
1556 | if (value) { | |
1557 | if (get_file(value,pragma_include) == -1) { | |
1558 | fprintf(stderr,"%s : Line %d. Unable to locate file %s\n", input_file, line_number, value); | |
1559 | } | |
1560 | } | |
1561 | } | |
1562 | } else { | |
1563 | fprintf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number); | |
1564 | } | |
1565 | } | |
1566 | } | |
1567 | ||
1568 | ||
1569 | struct PyPragma { | |
1570 | PyPragma(char *method, char *text) : m_method(method), m_text(text), next(0) { } | |
1571 | ~PyPragma() { if (next) delete next; } | |
1572 | String m_method; | |
1573 | String m_text; | |
1574 | PyPragma *next; | |
1575 | }; | |
1576 | ||
1577 | static PyPragma *pragmas = 0; | |
1578 | ||
1579 | // ----------------------------------------------------------------------------- | |
1580 | // PYTHON::cpp_pragma(Pragma *plist) | |
1581 | // | |
1582 | // Handle C++ pragmas | |
1583 | // ----------------------------------------------------------------------------- | |
1584 | ||
1585 | void PYTHON::cpp_pragma(Pragma *plist) { | |
1586 | PyPragma *pyp1 = 0, *pyp2 = 0; | |
1587 | if (pragmas) { | |
1588 | delete pragmas; | |
1589 | pragmas = 0; | |
1590 | } | |
1591 | while (plist) { | |
1592 | if (strcmp(plist->lang,"python") == 0) { | |
1593 | if (strcmp(plist->name,"addtomethod") == 0) { | |
1594 | // parse value, expected to be in the form "methodName:line" | |
1595 | String temp = plist->value; | |
1596 | char* txtptr = strchr(temp.get(), ':'); | |
1597 | if (txtptr) { | |
1598 | // add name and line to a list in current_class | |
1599 | *txtptr = 0; | |
1600 | txtptr++; | |
1601 | pyp1 = new PyPragma(temp,txtptr); | |
1602 | if (pyp2) { | |
1603 | pyp2->next = pyp1; | |
1604 | pyp2 = pyp1; | |
1605 | } else { | |
1606 | pragmas = pyp1; | |
1607 | pyp2 = pragmas; | |
1608 | } | |
1609 | } else { | |
1610 | fprintf(stderr,"%s : Line %d. Malformed addtomethod pragma. Should be \"methodName:text\"\n", | |
1611 | plist->filename.get(),plist->lineno); | |
1612 | } | |
1613 | } else if (strcmp(plist->name, "addtoclass") == 0) { | |
1614 | pyp1 = new PyPragma("__class__",plist->value); | |
1615 | if (pyp2) { | |
1616 | pyp2->next = pyp1; | |
1617 | pyp2 = pyp1; | |
1618 | } else { | |
1619 | pragmas = pyp1; | |
1620 | pyp2 = pragmas; | |
1621 | } | |
1622 | } | |
1623 | } | |
1624 | plist = plist->next; | |
1625 | } | |
1626 | } | |
1627 | ||
1628 | // -------------------------------------------------------------------------------- | |
1629 | // PYTHON::emitAddPragmas(String& output, char* name, char* spacing); | |
1630 | // | |
1631 | // Search the current class pragma for any text belonging to name. | |
1632 | // Append the text properly spaced to the output string. | |
1633 | // -------------------------------------------------------------------------------- | |
1634 | ||
1635 | void PYTHON::emitAddPragmas(String& output, char* name, char* spacing) | |
1636 | { | |
1637 | PyPragma *p = pragmas; | |
1638 | while (p) { | |
1639 | if (strcmp(p->m_method,name) == 0) { | |
1640 | output << spacing << p->m_text << "\n"; | |
1641 | } | |
1642 | p = p->next; | |
1643 | } | |
1644 | } |