]>
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 | ||
487 | f << tab4 << "if (" << src << ") {\n" | |
488 | << tab8 << "if (" << src << " == Py_None) { " << dest << " = NULL; }\n" | |
489 | << tab8 << "else if (SWIG_GetPtrObj(" << src << ",(void **) &" << dest << ","; | |
490 | ||
491 | // If we're passing a void pointer, we give the pointer conversion a NULL | |
492 | // pointer, otherwise pass in the expected type. | |
493 | ||
494 | if (t->type == T_VOID) f << "(char *) 0 )) {\n"; | |
495 | else | |
496 | f << "\"" << t->print_mangle() << "\")) {\n"; | |
497 | ||
498 | // This part handles the type checking according to three different | |
499 | // levels. 0 = no checking, 1 = warning message, 2 = strict. | |
500 | ||
501 | switch(TypeStrict) { | |
502 | case 0: // No type checking | |
503 | f << tab8 << "}\n"; | |
504 | break; | |
505 | ||
506 | case 1: // Warning message only | |
507 | ||
508 | // Change this part to how you want to handle a type-mismatch warning. | |
509 | // By default, it will just print to stderr. | |
510 | ||
511 | f << tab8 << tab4 << "fprintf(stderr,\"Warning : type mismatch in " << srcname | |
512 | << " of " << iname << ". Expected " << t->print_mangle() | |
513 | << ", received %s\\n\"," << src << ");\n" | |
514 | << tab8 << "}\n"; | |
515 | ||
516 | break; | |
517 | case 2: // Super strict mode. | |
518 | ||
519 | // Change this part to return an error. | |
520 | ||
521 | f << tab8 << tab4 << "PyErr_SetString(PyExc_TypeError,\"Type error in " << srcname | |
522 | << " of " << iname << ". Expected " << t->print_mangle() << ".\");\n" | |
523 | << tab8 << "return " << ret << ";\n" | |
524 | << tab8 << "}\n"; | |
525 | break; | |
526 | ||
527 | default : | |
528 | fprintf(stderr,"SWIG Error. Unknown strictness level\n"); | |
529 | break; | |
530 | } | |
531 | f << tab4 << "}\n"; | |
532 | } | |
533 | ||
534 | // ---------------------------------------------------------------------- | |
535 | // PYTHON::emit_function_header() | |
536 | // | |
537 | // Return the code to be used as a function header | |
538 | // ---------------------------------------------------------------------- | |
539 | void PYTHON::emit_function_header(WrapperFunction &emit_to, char *wname) | |
540 | { | |
541 | if (!use_kw) { | |
542 | emit_to.def << "static PyObject *" << wname | |
543 | << "(PyObject *self, PyObject *args) {"; | |
544 | } else { | |
545 | emit_to.def << "static PyObject *" << wname | |
546 | << "(PyObject *self, PyObject *args, PyObject *kwargs) {"; | |
547 | } | |
548 | emit_to.code << tab4 << "self = self;\n"; | |
549 | } | |
550 | ||
551 | // ---------------------------------------------------------------------- | |
552 | // PYTHON::convert_self() | |
553 | // | |
554 | // Called during the function generation process, to determine what to | |
555 | // use as the "self" variable during the call. Derived classes may emit code | |
556 | // to convert the real self pointer into a usable pointer. | |
557 | // | |
558 | // Returns the name of the variable to use as the self pointer | |
559 | // ---------------------------------------------------------------------- | |
560 | char *PYTHON::convert_self(WrapperFunction &) | |
561 | { | |
562 | // Default behaviour is no translation | |
563 | return ""; | |
564 | } | |
565 | ||
566 | // ---------------------------------------------------------------------- | |
567 | // PYTHON::make_funcname_wrapper() | |
568 | // | |
569 | // Called to create a name for a wrapper function | |
570 | // ---------------------------------------------------------------------- | |
571 | char *PYTHON::make_funcname_wrapper(char *fnName) | |
572 | { | |
573 | return name_wrapper(fnName,""); | |
574 | } | |
575 | ||
576 | // ---------------------------------------------------------------------- | |
577 | // PYTHON::create_command(char *cname, char *iname) | |
578 | // | |
579 | // Create a new command in the interpreter. Used for C++ inheritance | |
580 | // stuff. | |
581 | // ---------------------------------------------------------------------- | |
582 | ||
583 | void PYTHON::create_command(char *cname, char *iname) { | |
584 | ||
585 | // Create the name of the wrapper function | |
586 | ||
587 | char *wname = name_wrapper(cname,""); | |
588 | ||
589 | // Now register the function with the interpreter. | |
590 | ||
591 | add_method(iname, wname); | |
592 | ||
593 | } | |
594 | ||
595 | // ---------------------------------------------------------------------- | |
596 | // PYTHON::create_function(char *name, char *iname, DataType *d, | |
597 | // ParmList *l) | |
598 | // | |
599 | // This function creates a wrapper function and registers it with the | |
600 | // interpreter. | |
601 | // | |
602 | // Inputs : | |
603 | // name = actual name of the function that's being wrapped | |
604 | // iname = name of the function in the interpreter (may be different) | |
605 | // d = Return datatype of the functions. | |
606 | // l = A linked list containing function parameter information. | |
607 | // | |
608 | // ---------------------------------------------------------------------- | |
609 | ||
610 | void PYTHON::create_function(char *name, char *iname, DataType *d, ParmList *l) | |
611 | { | |
612 | Parm *p; | |
613 | int pcount,i,j; | |
614 | String wname, self_name, call_name; | |
615 | char source[64], target[64], temp[256], argnum[20]; | |
616 | char *usage = 0; | |
617 | WrapperFunction f; | |
618 | String parse_args; | |
619 | String arglist; | |
620 | String get_pointers; | |
621 | String cleanup, outarg; | |
622 | String check; | |
623 | String build; | |
624 | String kwargs; | |
625 | ||
626 | int have_build = 0; | |
627 | char *tm; | |
628 | int numopt = 0; | |
629 | ||
630 | have_output = 0; | |
631 | ||
632 | // Make a valid name for this function. This removes special symbols | |
633 | // that would cause problems in the C compiler. | |
634 | ||
635 | wname = make_funcname_wrapper(iname); | |
636 | ||
637 | // Now emit the function declaration for the wrapper function. You | |
638 | // should modify this to return the appropriate types and use the | |
639 | // appropriate parameters. | |
640 | ||
641 | emit_function_header(f, wname); | |
642 | ||
643 | f.add_local("PyObject *","_resultobj"); | |
644 | ||
645 | // Get the function usage string for later use | |
646 | ||
647 | usage = usage_func(iname,d,l); | |
648 | ||
649 | // Write code to extract function parameters. | |
650 | // This is done in one pass, but we need to construct three independent | |
651 | // pieces. | |
652 | // 1. Python format string such as "iis" | |
653 | // 2. The actual arguments to put values into | |
654 | // 3. Pointer conversion code. | |
655 | // | |
656 | // If there is a type mapping, we will extract the Python argument | |
657 | // as a raw PyObject and let the user deal with it. | |
658 | // | |
659 | ||
660 | pcount = emit_args(d, l, f); | |
661 | if (!use_kw) { | |
662 | parse_args << tab4 << "if(!PyArg_ParseTuple(args,\""; | |
663 | } else { | |
664 | parse_args << tab4 << "if(!PyArg_ParseTupleAndKeywords(args,kwargs,\""; | |
665 | arglist << ",_kwnames"; | |
666 | } | |
667 | ||
668 | i = 0; | |
669 | j = 0; | |
670 | numopt = l->numopt(); // Get number of optional arguments | |
671 | if (numopt) have_defarg = 1; | |
672 | p = l->get_first(); | |
673 | ||
674 | kwargs << "{ "; | |
675 | while (p != 0) { | |
676 | ||
677 | // Generate source and target strings | |
678 | sprintf(source,"_obj%d",i); | |
679 | sprintf(target,"_arg%d",i); | |
680 | sprintf(argnum,"%d",j+1); | |
681 | ||
682 | // Only consider this argument if it's not ignored | |
683 | ||
684 | if (!p->ignore) { | |
685 | arglist << ","; | |
686 | // Add an optional argument separator if needed | |
687 | ||
688 | if (j == pcount-numopt) { | |
689 | parse_args << "|"; | |
690 | } | |
691 | ||
692 | if (strlen(p->name)) { | |
693 | kwargs << "\"" << p->name << "\","; | |
694 | } else { | |
695 | kwargs << "\"arg" << j+1 << "\","; | |
696 | // kwargs << "\"\","; | |
697 | } | |
698 | ||
699 | // Look for input typemap | |
700 | ||
701 | if ((tm = typemap_lookup("in","python",p->t,p->name,source,target,&f))) { | |
702 | parse_args << "O"; // Grab the argument as a raw PyObject | |
703 | f.add_local("PyObject *",source,"0"); | |
704 | arglist << "&" << source; | |
705 | if (i >= (pcount-numopt)) | |
706 | get_pointers << tab4 << "if (" << source << ")\n"; | |
707 | get_pointers << tm << "\n"; | |
708 | get_pointers.replace("$argnum", argnum); | |
709 | get_pointers.replace("$arg",source); | |
710 | } else { | |
711 | ||
712 | // Check if this parameter is a pointer. If not, we'll get values | |
713 | ||
714 | if (!p->t->is_pointer) { | |
715 | // Extract a parameter by "value" | |
716 | ||
717 | switch(p->t->type) { | |
718 | ||
719 | // Handle integers here. Usually this can be done as a single | |
720 | // case if you appropriate cast things. However, if you have | |
721 | // special cases, you'll need to add more code. | |
722 | ||
723 | case T_INT : case T_UINT: case T_SINT: | |
724 | parse_args << "i"; | |
725 | break; | |
726 | case T_SHORT: case T_USHORT: case T_SSHORT: | |
727 | parse_args << "h"; | |
728 | break; | |
729 | case T_LONG : case T_ULONG: case T_SLONG : | |
730 | parse_args << "l"; | |
731 | break; | |
732 | case T_SCHAR : case T_UCHAR : | |
733 | parse_args << "b"; | |
734 | break; | |
735 | case T_CHAR: | |
736 | parse_args << "c"; | |
737 | break; | |
738 | case T_FLOAT : | |
739 | parse_args << "f"; | |
740 | break; | |
741 | case T_DOUBLE: | |
742 | parse_args << "d"; | |
743 | break; | |
744 | ||
745 | case T_BOOL: | |
746 | { | |
747 | String tempb; | |
748 | String tempval; | |
749 | if (p->defvalue) { | |
750 | tempval << "(int) " << p->defvalue; | |
751 | } | |
752 | tempb << "tempbool" << i; | |
753 | parse_args << "i"; | |
754 | if (!p->defvalue) | |
755 | f.add_local("int",tempb.get()); | |
756 | else | |
757 | f.add_local("int",tempb.get(),tempval.get()); | |
758 | get_pointers << tab4 << target << " = " << p->t->print_cast() << " " << tempb << ";\n"; | |
759 | arglist << "&" << tempb; | |
760 | } | |
761 | break; | |
762 | ||
763 | // Void.. Do nothing. | |
764 | ||
765 | case T_VOID : | |
766 | break; | |
767 | ||
768 | // User defined. This is usually invalid. No way to pass a | |
769 | // complex type by "value". We'll just pass into the unsupported | |
770 | // datatype case. | |
771 | ||
772 | case T_USER: | |
773 | ||
774 | // Unsupported data type | |
775 | ||
776 | default : | |
777 | fprintf(stderr,"%s : Line %d. Unable to use type %s as a function argument.\n",input_file, line_number, p->t->print_type()); | |
778 | break; | |
779 | } | |
780 | ||
781 | // Emit code for parameter list | |
782 | ||
783 | if ((p->t->type != T_VOID) && (p->t->type != T_BOOL)) | |
784 | arglist << "&_arg" << i; | |
785 | ||
786 | } else { | |
787 | ||
788 | // Is some other kind of variable. | |
789 | ||
790 | if ((p->t->type == T_CHAR) && (p->t->is_pointer == 1)) { | |
791 | parse_args << "s"; | |
792 | arglist << "&_arg" << i; | |
793 | } else { | |
794 | ||
795 | // Have some sort of pointer variable. Create a temporary local | |
796 | // variable for the string and read the pointer value into it. | |
797 | ||
798 | parse_args << "O"; | |
799 | sprintf(source,"_argo%d", i); | |
800 | sprintf(target,"_arg%d", i); | |
801 | sprintf(temp,"argument %d",i+1); | |
802 | ||
803 | f.add_local("PyObject *", source,"0"); | |
804 | arglist << "&" << source; | |
805 | get_pointer(iname, temp, source, target, p->t, get_pointers, "NULL"); | |
806 | } | |
807 | } | |
808 | } | |
809 | j++; | |
810 | } | |
811 | // Check if there was any constraint code | |
812 | if ((tm = typemap_lookup("check","python",p->t,p->name,source,target))) { | |
813 | check << tm << "\n"; | |
814 | check.replace("$argnum", argnum); | |
815 | } | |
816 | // Check if there was any cleanup code | |
817 | if ((tm = typemap_lookup("freearg","python",p->t,p->name,target,source))) { | |
818 | cleanup << tm << "\n"; | |
819 | cleanup.replace("$argnum", argnum); | |
820 | cleanup.replace("$arg",source); | |
821 | } | |
822 | if ((tm = typemap_lookup("argout","python",p->t,p->name,target,"_resultobj"))) { | |
823 | outarg << tm << "\n"; | |
824 | outarg.replace("$argnum", argnum); | |
825 | outarg.replace("$arg",source); | |
826 | have_output++; | |
827 | } | |
828 | if ((tm = typemap_lookup("build","python",p->t,p->name,source,target))) { | |
829 | build << tm << "\n"; | |
830 | have_build = 1; | |
831 | } | |
832 | p = l->get_next(); | |
833 | i++; | |
834 | } | |
835 | ||
836 | kwargs << " NULL }"; | |
837 | if (use_kw) { | |
838 | f.locals << tab4 << "char *_kwnames[] = " << kwargs << ";\n"; | |
839 | } | |
840 | ||
841 | parse_args << ":" << iname << "\""; // No additional arguments | |
842 | parse_args << arglist << ")) \n" | |
843 | << tab8 << "return NULL;\n"; | |
844 | ||
845 | self_name = convert_self(f); | |
846 | ||
847 | /* Now slap the whole first part of the wrapper function together */ | |
848 | ||
849 | f.code << parse_args << get_pointers << check; | |
850 | ||
851 | ||
852 | // Special handling for build values | |
853 | ||
854 | if (have_build) { | |
855 | char temp1[256]; | |
856 | char temp2[256]; | |
857 | l->sub_parmnames(build); // Replace all parameter names | |
858 | for (i = 0; i < l->nparms; i++) { | |
859 | p = l->get(i); | |
860 | if (strlen(p->name) > 0) { | |
861 | sprintf(temp1,"_in_%s", p->name); | |
862 | } else { | |
863 | sprintf(temp1,"_in_arg%d", i); | |
864 | } | |
865 | sprintf(temp2,"_obj%d",i); | |
866 | build.replaceid(temp1,temp2); | |
867 | } | |
868 | f.code << build; | |
869 | } | |
870 | ||
871 | // This function emits code to call the real function. Assuming you read | |
872 | // the parameters in correctly, this will work. | |
873 | ||
874 | call_name = ""; | |
875 | call_name << self_name << name; | |
876 | emit_func_call(call_name,d,l,f); | |
877 | ||
878 | // Now emit code to return the functions return value (if any). | |
879 | // If there was a result, it was saved in _result. | |
880 | // If the function is a void type, don't do anything. | |
881 | ||
882 | if ((strncmp(name, "new_", 4) != 0) && // don't use the out typemap for constructors | |
883 | (tm = typemap_lookup("out","python",d,iname,"_result","_resultobj"))) { | |
884 | // Yep. Use it instead of the default | |
885 | f.code << tm << "\n"; | |
886 | } else { | |
887 | ||
888 | if ((d->type != T_VOID) || (d->is_pointer)) { | |
889 | // Now have return value, figure out what to do with it. | |
890 | ||
891 | if (!d->is_pointer) { | |
892 | ||
893 | // Function returns a "value" | |
894 | ||
895 | switch(d->type) { | |
896 | ||
897 | // Return an integer type | |
898 | ||
899 | case T_INT: case T_SINT: case T_UINT: case T_BOOL: | |
900 | f.code << tab4 << "_resultobj = Py_BuildValue(\"i\",_result);\n"; | |
901 | break; | |
902 | case T_SHORT: case T_SSHORT: case T_USHORT: | |
903 | f.code << tab4 << "_resultobj = Py_BuildValue(\"h\",_result);\n"; | |
904 | break; | |
905 | case T_LONG : case T_SLONG : case T_ULONG: | |
906 | f.code << tab4 << "_resultobj = Py_BuildValue(\"l\",_result);\n"; | |
907 | break; | |
908 | case T_SCHAR: case T_UCHAR : | |
909 | f.code << tab4 << "_resultobj = Py_BuildValue(\"b\",_result);\n"; | |
910 | break; | |
911 | ||
912 | // Return a floating point value | |
913 | ||
914 | case T_DOUBLE : | |
915 | f.code << tab4 << "_resultobj = Py_BuildValue(\"d\",_result);\n"; | |
916 | break; | |
917 | case T_FLOAT : | |
918 | f.code << tab4 << "_resultobj = Py_BuildValue(\"f\",_result);\n"; | |
919 | break; | |
920 | ||
921 | // Return a single ASCII value. Usually we need to convert | |
922 | // it to a NULL-terminate string and return that instead. | |
923 | ||
924 | case T_CHAR : | |
925 | f.code << tab4 << "_resultobj = Py_BuildValue(\"c\",_result);\n"; | |
926 | break; | |
927 | ||
928 | case T_USER : | |
929 | ||
930 | // Return something by value | |
931 | // We're living dangerously here, but life is short...play hard | |
932 | ||
933 | // Oops. Need another local variable | |
934 | f.add_local("char","_ptemp[128]"); | |
935 | ||
936 | d->is_pointer++; | |
937 | f.code << tab4 << "SWIG_MakePtr(_ptemp, (void *) _result,\"" | |
938 | << d->print_mangle() << "\");\n"; | |
939 | d->is_pointer--; | |
940 | // Return a character string containing our pointer. | |
941 | ||
942 | f.code << tab4 << "_resultobj = Py_BuildValue(\"s\",_ptemp);\n"; | |
943 | break; | |
944 | default : | |
945 | fprintf(stderr,"%s: Line %d. Unable to use return type %s in function %s.\n", input_file, line_number, d->print_type(), name); | |
946 | break; | |
947 | } | |
948 | } else { | |
949 | ||
950 | // Return type is a pointer. We'll see if it's a char * and return | |
951 | // a string. Otherwise, we'll convert it into a SWIG pointer and return | |
952 | // that. | |
953 | ||
954 | if ((d->type == T_CHAR) && (d->is_pointer == 1)) { | |
955 | ||
956 | // Return a character string | |
957 | f.code << tab4 << "_resultobj = Py_BuildValue(\"s\", _result);\n"; | |
958 | ||
959 | // If declared as a new object, free the result | |
960 | ||
961 | } else { | |
962 | ||
963 | // Build a SWIG pointer. | |
964 | f.add_local("char","_ptemp[128]"); | |
965 | f.code << tab4 << "if (_result) {\n" | |
966 | << tab8 << "SWIG_MakePtr(_ptemp, (char *) _result,\"" | |
967 | << d->print_mangle() << "\");\n"; | |
968 | ||
969 | // Return a character string containing our pointer. | |
970 | f.code << tab8 << "_resultobj = Py_BuildValue(\"s\",_ptemp);\n"; | |
971 | f.code << tab4 << "} else {\n" | |
972 | << tab8 << "Py_INCREF(Py_None);\n" | |
973 | << tab8 << "_resultobj = Py_None;\n" | |
974 | << tab4 << "}\n"; | |
975 | } | |
976 | } | |
977 | } else { | |
978 | // no return value and no output args | |
979 | //if (!have_output) { | |
980 | f.code << tab4 << "Py_INCREF(Py_None);\n"; | |
981 | f.code << tab4 << "_resultobj = Py_None;\n"; | |
982 | //} | |
983 | } | |
984 | } | |
985 | ||
986 | // Check to see if there were any output arguments, if so we're going to | |
987 | // create a Python list object out of the current result | |
988 | ||
989 | f.code << outarg; | |
990 | ||
991 | // If there was any other cleanup needed, do that | |
992 | ||
993 | f.code << cleanup; | |
994 | ||
995 | // Look to see if there is any newfree cleanup code | |
996 | ||
997 | if (NewObject) { | |
998 | if ((tm = typemap_lookup("newfree","python",d,iname,"_result",""))) { | |
999 | f.code << tm << "\n"; | |
1000 | } | |
1001 | } | |
1002 | ||
1003 | // See if there is any argument cleanup code | |
1004 | ||
1005 | if ((tm = typemap_lookup("ret","python",d,iname,"_result",""))) { | |
1006 | // Yep. Use it instead of the default | |
1007 | f.code << tm << "\n"; | |
1008 | } | |
1009 | ||
1010 | f.code << tab4 << "return _resultobj;\n"; | |
1011 | f.code << "}\n"; | |
1012 | ||
1013 | // Substitute the cleanup code | |
1014 | f.code.replace("$cleanup",cleanup); | |
1015 | ||
1016 | // Substitute the function name | |
1017 | f.code.replace("$name",iname); | |
1018 | ||
1019 | // Dump the function out | |
1020 | f.print(f_wrappers); | |
1021 | ||
1022 | // Now register the function with the interpreter. | |
1023 | ||
1024 | add_method(iname, wname); | |
1025 | ||
1026 | // Create a documentation entry for this | |
1027 | ||
1028 | if (doc_entry) { | |
1029 | static DocEntry *last_doc_entry = 0; | |
1030 | doc_entry->usage << usage; | |
1031 | if (last_doc_entry != doc_entry) { | |
1032 | doc_entry->cinfo << "returns " << d->print_type(); | |
1033 | last_doc_entry = doc_entry; | |
1034 | } | |
1035 | } | |
1036 | ||
1037 | // --------------------------------------------------------------------------- | |
1038 | // Create a shadow for this function (if enabled and not in a member function) | |
1039 | // --------------------------------------------------------------------------- | |
1040 | ||
1041 | if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { | |
1042 | String translate; | |
1043 | ||
1044 | int need_wrapper = 0; | |
1045 | int munge_return = 0; | |
1046 | int have_optional = 0; | |
1047 | ||
1048 | // Check return code for modification | |
1049 | if ((hash.lookup(d->name)) && (d->is_pointer <=1)) { | |
1050 | need_wrapper = 1; | |
1051 | munge_return = 1; | |
1052 | } | |
1053 | ||
1054 | if (docstring && doc_entry) | |
1055 | need_wrapper = 1; | |
1056 | ||
1057 | // If no modification is needed. We're just going to play some | |
1058 | // symbol table games instead | |
1059 | ||
1060 | if (!need_wrapper) { | |
1061 | func << iname << " = " << module << "." << iname << "\n\n"; | |
1062 | } else { | |
1063 | func << "def " << iname << "(*_args, **_kwargs):\n"; | |
1064 | ||
1065 | // Create a docstring for this | |
1066 | if (docstring && doc_entry) { | |
1067 | func << tab4 << "\"\"\"" << add_docstring(doc_entry) << "\"\"\"\n"; | |
1068 | } | |
1069 | ||
1070 | func << tab4 << "val = apply(" << module << "." << iname << ",_args,_kwargs)\n"; | |
1071 | ||
1072 | if (munge_return) { | |
1073 | // If the output of this object has been remapped in any way, we're | |
1074 | // going to return it as a bare object. | |
1075 | ||
1076 | if (!typemap_check("out",typemap_lang,d,iname)) { | |
1077 | ||
1078 | // If there are output arguments, we are going to return the value | |
1079 | // unchanged. Otherwise, emit some shadow class conversion code. | |
1080 | ||
1081 | if (!have_output) { | |
1082 | func << tab4 << "if val: val = " << (char *) hash.lookup(d->name) << "Ptr(val)"; | |
1083 | if (((hash.lookup(d->name)) && (d->is_pointer < 1)) || | |
1084 | ((hash.lookup(d->name)) && (d->is_pointer == 1) && NewObject)) | |
1085 | func << "; val.thisown = 1\n"; | |
1086 | else | |
1087 | func << "\n"; | |
1088 | } else { | |
1089 | // Does nothing--returns the value unmolested | |
1090 | } | |
1091 | } | |
1092 | } | |
1093 | func << tab4 << "return val\n\n"; | |
1094 | } | |
1095 | } | |
1096 | } | |
1097 | ||
1098 | // ----------------------------------------------------------------------- | |
1099 | // PYTHON::link_variable(char *name, char *iname, DataType *d) | |
1100 | // | |
1101 | // Input variables: | |
1102 | // name = the real name of the variable being linked | |
1103 | // iname = Name of the variable in the interpreter (may be different) | |
1104 | // d = Datatype of the variable. | |
1105 | // | |
1106 | // This creates a pair of functions for evaluating/setting the value | |
1107 | // of a variable. These are then added to the special SWIG global | |
1108 | // variable type. | |
1109 | // ----------------------------------------------------------------------- | |
1110 | ||
1111 | void PYTHON::link_variable(char *name, char *iname, DataType *t) { | |
1112 | ||
1113 | char *wname; | |
1114 | static int have_globals = 0; | |
1115 | char *tm; | |
1116 | ||
1117 | WrapperFunction getf, setf; | |
1118 | ||
1119 | // If this is our first call, add the globals variable to the | |
1120 | // Python dictionary. | |
1121 | ||
1122 | if (!have_globals) { | |
1123 | fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", SWIG_globals);\n",global_name); | |
1124 | have_globals=1; | |
1125 | if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { | |
1126 | vars << global_name << " = " << module << "." << global_name << "\n"; | |
1127 | } | |
1128 | } | |
1129 | // First make a sanitized version of the function name (in case it's some | |
1130 | // funky C++ thing). | |
1131 | ||
1132 | wname = name_wrapper(name,""); | |
1133 | ||
1134 | // --------------------------------------------------------------------- | |
1135 | // Create a function for setting the value of the variable | |
1136 | // --------------------------------------------------------------------- | |
1137 | ||
1138 | setf.def << "static int " << wname << "_set(PyObject *val) {"; | |
1139 | if (!(Status & STAT_READONLY)) { | |
1140 | if ((tm = typemap_lookup("varin","python",t,name,"val",name))) { | |
1141 | setf.code << tm << "\n"; | |
1142 | setf.code.replace("$name",iname); | |
1143 | } else { | |
1144 | if ((t->type != T_VOID) || (t->is_pointer)) { | |
1145 | if (!t->is_pointer) { | |
1146 | ||
1147 | // Have a real value here | |
1148 | ||
1149 | switch(t->type) { | |
1150 | case T_INT: case T_SHORT: case T_LONG : | |
1151 | case T_UINT: case T_USHORT: case T_ULONG: | |
1152 | case T_SINT: case T_SSHORT: case T_SLONG: | |
1153 | case T_SCHAR: case T_UCHAR: case T_BOOL: | |
1154 | // Get an integer value | |
1155 | setf.add_local(t->print_type(), "tval"); | |
1156 | setf.code << tab4 << "tval = " << t->print_cast() << "PyInt_AsLong(val);\n" | |
1157 | << tab4 << "if (PyErr_Occurred()) {\n" | |
1158 | << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" | |
1159 | << iname << "'(" << t->print_type() << ")\");\n" | |
1160 | << tab8 << "return 1; \n" | |
1161 | << tab4 << "}\n" | |
1162 | << tab4 << name << " = tval;\n"; | |
1163 | break; | |
1164 | ||
1165 | case T_FLOAT: case T_DOUBLE: | |
1166 | // Get a floating point value | |
1167 | setf.add_local(t->print_type(), "tval"); | |
1168 | setf.code << tab4 << "tval = " << t->print_cast() << "PyFloat_AsDouble(val);\n" | |
1169 | << tab4 << "if (PyErr_Occurred()) {\n" | |
1170 | << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" | |
1171 | << iname << "'(" << t->print_type() << ")\");\n" | |
1172 | << tab8 << "return 1; \n" | |
1173 | << tab4 << "}\n" | |
1174 | << tab4 << name << " = tval;\n"; | |
1175 | break; | |
1176 | ||
1177 | // A single ascii character | |
1178 | ||
1179 | case T_CHAR: | |
1180 | setf.add_local("char *", "tval"); | |
1181 | setf.code << tab4 << "tval = (char *) PyString_AsString(val);\n" | |
1182 | << tab4 << "if (PyErr_Occurred()) {\n" | |
1183 | << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" | |
1184 | << iname << "'(" << t->print_type() << ")\");\n" | |
1185 | << tab8 << "return 1; \n" | |
1186 | << tab4 << "}\n" | |
1187 | << tab4 << name << " = *tval;\n"; | |
1188 | break; | |
1189 | case T_USER: | |
1190 | t->is_pointer++; | |
1191 | setf.add_local(t->print_type(),"temp"); | |
1192 | get_pointer(iname,"value","val","temp",t,setf.code,"1"); | |
1193 | setf.code << tab4 << name << " = *temp;\n"; | |
1194 | t->is_pointer--; | |
1195 | break; | |
1196 | default: | |
1197 | fprintf(stderr,"%s : Line %d. Unable to link with type %s.\n", input_file, line_number, t->print_type()); | |
1198 | } | |
1199 | } else { | |
1200 | ||
1201 | // Parse a pointer value | |
1202 | ||
1203 | if ((t->type == T_CHAR) && (t->is_pointer == 1)) { | |
1204 | setf.add_local("char *", "tval"); | |
1205 | setf.code << tab4 << "tval = (char *) PyString_AsString(val);\n" | |
1206 | << tab4 << "if (PyErr_Occurred()) {\n" | |
1207 | << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" | |
1208 | << iname << "'(" << t->print_type() << ")\");\n" | |
1209 | << tab8 << "return 1; \n" | |
1210 | << tab4 << "}\n"; | |
1211 | ||
1212 | if (CPlusPlus) { | |
1213 | setf.code << tab4 << "if (" << name << ") delete [] " << name << ";\n" | |
1214 | << tab4 << name << " = new char[strlen(tval)+1];\n" | |
1215 | << tab4 << "strcpy((char *)" << name << ",tval);\n"; | |
1216 | } else { | |
1217 | setf.code << tab4 << "if (" << name << ") free(" << name << ");\n" | |
1218 | << tab4 << name << " = (char *) malloc(strlen(tval)+1);\n" | |
1219 | << tab4 << "strcpy((char *)" << name << ",tval);\n"; | |
1220 | } | |
1221 | } else { | |
1222 | ||
1223 | // Is a generic pointer value. | |
1224 | ||
1225 | setf.add_local(t->print_type(),"temp"); | |
1226 | get_pointer(iname,"value","val","temp",t,setf.code,"1"); | |
1227 | setf.code << tab4 << name << " = temp;\n"; | |
1228 | } | |
1229 | } | |
1230 | } | |
1231 | } | |
1232 | setf.code << tab4 << "return 0;\n"; | |
1233 | } else { | |
1234 | // Is a readonly variable. Issue an error | |
1235 | setf.code << tab4 << "PyErr_SetString(PyExc_TypeError,\"Variable " << iname | |
1236 | << " is read-only.\");\n" | |
1237 | << tab4 << "return 1;\n"; | |
1238 | } | |
1239 | ||
1240 | setf.code << "}\n"; | |
1241 | ||
1242 | // Dump out function for setting value | |
1243 | ||
1244 | setf.print(f_wrappers); | |
1245 | ||
1246 | // ---------------------------------------------------------------- | |
1247 | // Create a function for getting the value of a variable | |
1248 | // ---------------------------------------------------------------- | |
1249 | ||
1250 | getf.def << "static PyObject *" << wname << "_get() {"; | |
1251 | getf.add_local("PyObject *","pyobj"); | |
1252 | if ((tm = typemap_lookup("varout","python",t,name,name,"pyobj"))) { | |
1253 | getf.code << tm << "\n"; | |
1254 | getf.code.replace("$name",iname); | |
1255 | } else if ((tm = typemap_lookup("out","python",t,name,name,"pyobj"))) { | |
1256 | getf.code << tm << "\n"; | |
1257 | getf.code.replace("$name",iname); | |
1258 | } else { | |
1259 | if ((t->type != T_VOID) || (t->is_pointer)) { | |
1260 | if (!t->is_pointer) { | |
1261 | ||
1262 | /* Is a normal datatype */ | |
1263 | switch(t->type) { | |
1264 | case T_INT: case T_SINT: case T_UINT: | |
1265 | case T_SHORT: case T_SSHORT: case T_USHORT: | |
1266 | case T_LONG: case T_SLONG: case T_ULONG: | |
1267 | case T_SCHAR: case T_UCHAR: case T_BOOL: | |
1268 | getf.code << tab4 << "pyobj = PyInt_FromLong((long) " << name << ");\n"; | |
1269 | break; | |
1270 | case T_FLOAT: case T_DOUBLE: | |
1271 | getf.code << tab4 << "pyobj = PyFloat_FromDouble((double) " << name << ");\n"; | |
1272 | break; | |
1273 | case T_CHAR: | |
1274 | getf.add_local("char","ptemp[2]"); | |
1275 | getf.code << tab4 << "ptemp[0] = " << name << ";\n" | |
1276 | << tab4 << "ptemp[1] = 0;\n" | |
1277 | << tab4 << "pyobj = PyString_FromString(ptemp);\n"; | |
1278 | break; | |
1279 | case T_USER: | |
1280 | // Hack this into a pointer | |
1281 | getf.add_local("char", "ptemp[128]"); | |
1282 | t->is_pointer++; | |
1283 | getf.code << tab4 << "SWIG_MakePtr(ptemp,(char *) &" << name | |
1284 | << "," << quote << t->print_mangle() << quote << ");\n" | |
1285 | << tab4 << "pyobj = PyString_FromString(ptemp);\n"; | |
1286 | t->is_pointer--; | |
1287 | break; | |
1288 | default: | |
1289 | fprintf(stderr,"Unable to link with type %s\n", t->print_type()); | |
1290 | break; | |
1291 | } | |
1292 | } else { | |
1293 | ||
1294 | // Is some sort of pointer value | |
1295 | if ((t->type == T_CHAR) && (t->is_pointer == 1)) { | |
1296 | getf.code << tab4 << "if (" << name << ")\n" | |
1297 | << tab8 << "pyobj = PyString_FromString(" << name << ");\n" | |
1298 | << tab4 << "else pyobj = PyString_FromString(\"(NULL)\");\n"; | |
1299 | } else { | |
1300 | getf.add_local("char","ptemp[128]"); | |
1301 | getf.code << tab4 << "SWIG_MakePtr(ptemp, (char *) " << name << ",\"" | |
1302 | << t->print_mangle() << "\");\n" | |
1303 | << tab4 << "pyobj = PyString_FromString(ptemp);\n"; | |
1304 | } | |
1305 | } | |
1306 | } | |
1307 | } | |
1308 | ||
1309 | getf.code << tab4 << "return pyobj;\n" | |
1310 | << "}\n"; | |
1311 | ||
1312 | getf.print(f_wrappers); | |
1313 | ||
1314 | // Now add this to the variable linking mechanism | |
1315 | ||
1316 | fprintf(f_init,"\t SWIG_addvarlink(SWIG_globals,\"%s\",%s_get, %s_set);\n", iname, wname, wname); | |
1317 | ||
1318 | ||
1319 | // Fill in the documentation entry | |
1320 | ||
1321 | if (doc_entry) { | |
1322 | doc_entry->usage << usage_var(iname, t); | |
1323 | doc_entry->cinfo << "Global : " << t->print_type() << " " << name; | |
1324 | } | |
1325 | ||
1326 | // ---------------------------------------------------------- | |
1327 | // Output a shadow variable. (If applicable and possible) | |
1328 | // ---------------------------------------------------------- | |
1329 | if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { | |
1330 | if ((hash.lookup(t->name)) && (t->is_pointer <= 1)) { | |
1331 | vars << iname << " = " << (char *) hash.lookup(t->name) << "Ptr(" << module << "." << global_name | |
1332 | << "." << iname << ")\n"; | |
1333 | } | |
1334 | } | |
1335 | } | |
1336 | ||
1337 | // ----------------------------------------------------------------------- | |
1338 | // PYTHON::declare_const(char *name, char *iname, DataType *type, char *value) | |
1339 | // | |
1340 | // Makes a constant as defined with #define. Constants are added to the | |
1341 | // module's dictionary and are **NOT** guaranteed to be read-only, | |
1342 | // sorry. | |
1343 | // | |
1344 | // ------------------------------------------------------------------------ | |
1345 | ||
1346 | void PYTHON::declare_const(char *name, char *, DataType *type, char *value) { | |
1347 | ||
1348 | char *tm; | |
1349 | ||
1350 | // Make a static python object | |
1351 | ||
1352 | if ((tm = typemap_lookup("const","python",type,name,value,name))) { | |
1353 | fprintf(f_init,"%s\n",tm); | |
1354 | } else { | |
1355 | ||
1356 | if ((type->type == T_USER) && (!type->is_pointer)) { | |
1357 | fprintf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number); | |
1358 | return; | |
1359 | } | |
1360 | ||
1361 | if (type->is_pointer == 0) { | |
1362 | switch(type->type) { | |
1363 | case T_INT:case T_SINT: case T_UINT: case T_BOOL: | |
1364 | case T_SHORT: case T_SSHORT: case T_USHORT: | |
1365 | case T_LONG: case T_SLONG: case T_ULONG: | |
1366 | case T_SCHAR: case T_UCHAR: | |
1367 | fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyInt_FromLong((long) %s));\n",name,value); | |
1368 | break; | |
1369 | case T_DOUBLE: | |
1370 | case T_FLOAT: | |
1371 | fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyFloat_FromDouble((double) %s));\n",name,value); | |
1372 | break; | |
1373 | case T_CHAR : | |
1374 | fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyString_FromString(\"%s\"));\n",name,value); | |
1375 | break; | |
1376 | default: | |
1377 | fprintf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number); | |
1378 | break; | |
1379 | } | |
1380 | } else { | |
1381 | if ((type->type == T_CHAR) && (type->is_pointer == 1)) { | |
1382 | fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyString_FromString(\"%s\"));\n",name,value); | |
1383 | } else { | |
1384 | // A funky user-defined type. We're going to munge it into a string pointer value | |
1385 | fprintf(f_init,"\t {\n"); | |
1386 | fprintf(f_init,"\t\t char %s_char[%d];\n", name, (int) strlen(type->print_mangle()) + 20); | |
1387 | fprintf(f_init,"\t\t SWIG_MakePtr(%s_char, (void *) (%s),\"%s\");\n", | |
1388 | name, value, type->print_mangle()); | |
1389 | fprintf(f_init,"\t\t PyDict_SetItemString(d,\"%s\", PyString_FromString(%s_char));\n",name,name); | |
1390 | fprintf(f_init,"\t }\n"); | |
1391 | } | |
1392 | } | |
1393 | } | |
1394 | if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { | |
1395 | vars << name << " = " << module << "." << name << "\n"; | |
1396 | } | |
1397 | if (doc_entry) { | |
1398 | doc_entry->usage = ""; | |
1399 | doc_entry->usage << usage_const(name,type,value); | |
1400 | doc_entry->cinfo = ""; | |
1401 | doc_entry->cinfo << "Constant: " << type->print_type(); | |
1402 | } | |
1403 | } | |
1404 | ||
1405 | // ---------------------------------------------------------------------- | |
1406 | // PYTHON::usage_var(char *iname, DataType *t) | |
1407 | // | |
1408 | // This function produces a string indicating how to use a variable. | |
1409 | // It is called by the documentation system to produce syntactically | |
1410 | // correct documentation entires. | |
1411 | // | |
1412 | // s is a pointer to a character pointer. You should create | |
1413 | // a string and set this pointer to point to it. | |
1414 | // ---------------------------------------------------------------------- | |
1415 | ||
1416 | char *PYTHON::usage_var(char *iname, DataType *) { | |
1417 | ||
1418 | static String temp; | |
1419 | ||
1420 | temp = ""; | |
1421 | temp << global_name << "." << iname; | |
1422 | ||
1423 | // Create result. Don't modify this | |
1424 | ||
1425 | return temp.get(); | |
1426 | } | |
1427 | ||
1428 | // --------------------------------------------------------------------------- | |
1429 | // PYTHON::usage_func(char *iname, DataType *t, ParmList *l) | |
1430 | // | |
1431 | // Produces a string indicating how to call a function in the target | |
1432 | // language. | |
1433 | // | |
1434 | // --------------------------------------------------------------------------- | |
1435 | ||
1436 | char *PYTHON::usage_func(char *iname, DataType *, ParmList *l) { | |
1437 | ||
1438 | static String temp; | |
1439 | Parm *p; | |
1440 | int i; | |
1441 | ||
1442 | temp = ""; | |
1443 | temp << iname << "("; | |
1444 | ||
1445 | // Now go through and print parameters | |
1446 | // You probably don't need to change this | |
1447 | ||
1448 | i = 0; | |
1449 | p = l->get_first(); | |
1450 | while (p != 0) { | |
1451 | if (!p->ignore) { | |
1452 | i++; | |
1453 | /* If parameter has been named, use that. Otherwise, just print a type */ | |
1454 | ||
1455 | if ((p->t->type != T_VOID) || (p->t->is_pointer)) { | |
1456 | if (strlen(p->name) > 0) { | |
1457 | temp << p->name; | |
1458 | } else { | |
1459 | temp << p->t->print_type(); | |
1460 | } | |
1461 | } | |
1462 | p = l->get_next(); | |
1463 | if (p != 0) { | |
1464 | if (!p->ignore) | |
1465 | temp << ","; | |
1466 | } | |
1467 | } else { | |
1468 | p = l->get_next(); | |
1469 | if (p) { | |
1470 | if ((!p->ignore) && (i > 0)) | |
1471 | temp << ","; | |
1472 | } | |
1473 | } | |
1474 | } | |
1475 | ||
1476 | temp << ")"; | |
1477 | ||
1478 | // Create result. Don't change this | |
1479 | ||
1480 | return temp.get(); | |
1481 | ||
1482 | } | |
1483 | ||
1484 | ||
1485 | // ---------------------------------------------------------------------- | |
1486 | // PYTHON::usage_const(char *iname, DataType *type, char *value) | |
1487 | // | |
1488 | // Produces a string for a constant. Really about the same as | |
1489 | // usage_var() except we'll indicate the value of the constant. | |
1490 | // ---------------------------------------------------------------------- | |
1491 | ||
1492 | char *PYTHON::usage_const(char *iname, DataType *, char *value) { | |
1493 | ||
1494 | static String temp; | |
1495 | temp = ""; | |
1496 | temp << iname << " = " << value; | |
1497 | ||
1498 | return temp.get(); | |
1499 | } | |
1500 | ||
1501 | // ----------------------------------------------------------------------- | |
1502 | // PYTHON::add_native(char *name, char *funcname) | |
1503 | // | |
1504 | // Add a native module name to the methods list. | |
1505 | // ----------------------------------------------------------------------- | |
1506 | ||
1507 | void PYTHON::add_native(char *name, char *funcname) { | |
1508 | add_method(name, funcname); | |
1509 | if (shadow) { | |
1510 | func << name << " = " << module << "." << name << "\n\n"; | |
1511 | } | |
1512 | } | |
1513 | ||
1514 | // ----------------------------------------------------------------------- | |
1515 | // PYTHON::cpp_class_decl(char *name, char *rename, char *type) | |
1516 | // | |
1517 | // Treatment of an empty class definition. Used to handle | |
1518 | // shadow classes across modules. | |
1519 | // ----------------------------------------------------------------------- | |
1520 | ||
1521 | void PYTHON::cpp_class_decl(char *name, char *rename, char *type) { | |
1522 | char temp[256]; | |
1523 | if (shadow) { | |
1524 | hash.add(name,copy_string(rename)); | |
1525 | // Add full name of datatype to the hash table | |
1526 | if (strlen(type) > 0) { | |
1527 | sprintf(temp,"%s %s", type, name); | |
1528 | hash.add(temp,copy_string(rename)); | |
1529 | } | |
1530 | } | |
1531 | } | |
1532 | ||
1533 | // ----------------------------------------------------------------------- | |
1534 | // PYTHON::pragma(char *name, char *type) | |
1535 | // | |
1536 | // Pragma directive. Used to do various python specific things | |
1537 | // ----------------------------------------------------------------------- | |
1538 | ||
1539 | void PYTHON::pragma(char *lang, char *cmd, char *value) { | |
1540 | ||
1541 | if (strcmp(lang,"python") == 0) { | |
1542 | if (strcmp(cmd,"CODE") == 0) { | |
1543 | if (shadow) { | |
1544 | fprintf(f_shadow,"%s\n",value); | |
1545 | } | |
1546 | } else if (strcmp(cmd,"code") == 0) { | |
1547 | if (shadow) { | |
1548 | fprintf(f_shadow,"%s\n",value); | |
1549 | } | |
1550 | } else if (strcmp(cmd,"include") == 0) { | |
1551 | if (shadow) { | |
1552 | if (value) { | |
1553 | if (get_file(value,pragma_include) == -1) { | |
1554 | fprintf(stderr,"%s : Line %d. Unable to locate file %s\n", input_file, line_number, value); | |
1555 | } | |
1556 | } | |
1557 | } | |
1558 | } else { | |
1559 | fprintf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number); | |
1560 | } | |
1561 | } | |
1562 | } | |
1563 | ||
1564 | ||
1565 | struct PyPragma { | |
1566 | PyPragma(char *method, char *text) : m_method(method), m_text(text), next(0) { } | |
1567 | ~PyPragma() { if (next) delete next; } | |
1568 | String m_method; | |
1569 | String m_text; | |
1570 | PyPragma *next; | |
1571 | }; | |
1572 | ||
1573 | static PyPragma *pragmas = 0; | |
1574 | ||
1575 | // ----------------------------------------------------------------------------- | |
1576 | // PYTHON::cpp_pragma(Pragma *plist) | |
1577 | // | |
1578 | // Handle C++ pragmas | |
1579 | // ----------------------------------------------------------------------------- | |
1580 | ||
1581 | void PYTHON::cpp_pragma(Pragma *plist) { | |
1582 | PyPragma *pyp1 = 0, *pyp2 = 0; | |
1583 | if (pragmas) { | |
1584 | delete pragmas; | |
1585 | pragmas = 0; | |
1586 | } | |
1587 | while (plist) { | |
1588 | if (strcmp(plist->lang,"python") == 0) { | |
1589 | if (strcmp(plist->name,"addtomethod") == 0) { | |
1590 | // parse value, expected to be in the form "methodName:line" | |
1591 | String temp = plist->value; | |
1592 | char* txtptr = strchr(temp.get(), ':'); | |
1593 | if (txtptr) { | |
1594 | // add name and line to a list in current_class | |
1595 | *txtptr = 0; | |
1596 | txtptr++; | |
1597 | pyp1 = new PyPragma(temp,txtptr); | |
1598 | if (pyp2) { | |
1599 | pyp2->next = pyp1; | |
1600 | pyp2 = pyp1; | |
1601 | } else { | |
1602 | pragmas = pyp1; | |
1603 | pyp2 = pragmas; | |
1604 | } | |
1605 | } else { | |
1606 | fprintf(stderr,"%s : Line %d. Malformed addtomethod pragma. Should be \"methodName:text\"\n", | |
1607 | plist->filename.get(),plist->lineno); | |
1608 | } | |
1609 | } else if (strcmp(plist->name, "addtoclass") == 0) { | |
1610 | pyp1 = new PyPragma("__class__",plist->value); | |
1611 | if (pyp2) { | |
1612 | pyp2->next = pyp1; | |
1613 | pyp2 = pyp1; | |
1614 | } else { | |
1615 | pragmas = pyp1; | |
1616 | pyp2 = pragmas; | |
1617 | } | |
1618 | } | |
1619 | } | |
1620 | plist = plist->next; | |
1621 | } | |
1622 | } | |
1623 | ||
1624 | // -------------------------------------------------------------------------------- | |
1625 | // PYTHON::emitAddPragmas(String& output, char* name, char* spacing); | |
1626 | // | |
1627 | // Search the current class pragma for any text belonging to name. | |
1628 | // Append the text properly spaced to the output string. | |
1629 | // -------------------------------------------------------------------------------- | |
1630 | ||
1631 | void PYTHON::emitAddPragmas(String& output, char* name, char* spacing) | |
1632 | { | |
1633 | PyPragma *p = pragmas; | |
1634 | while (p) { | |
1635 | if (strcmp(p->m_method,name) == 0) { | |
1636 | output << spacing << p->m_text << "\n"; | |
1637 | } | |
1638 | p = p->next; | |
1639 | } | |
1640 | } |