]>
Commit | Line | Data |
---|---|---|
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 | #include "internal.h" | |
17 | /******************************************************************************* | |
18 | * $Header$ | |
19 | * | |
20 | * File : emit.cxx | |
21 | * | |
22 | * This file contains some useful functions for emitting code that would be | |
23 | * common to all of the interface languages. Mainly this function deals with | |
24 | * declaring functions external, creating lists of arguments, and making | |
25 | * function calls. | |
26 | *******************************************************************************/ | |
27 | ||
28 | // ----------------------------------------------------------------------------- | |
29 | // void emit_banner(FILE *f) | |
30 | // | |
31 | // Emits the SWIG identifying banner in the wrapper file | |
32 | // | |
33 | // Inputs : f = FILE handle | |
34 | // | |
35 | // Output : None | |
36 | // | |
37 | // Side Effects : None | |
38 | // ----------------------------------------------------------------------------- | |
39 | ||
40 | void emit_banner(FILE *f) { | |
41 | ||
42 | extern char *get_time(); | |
43 | extern char fn_header[]; | |
44 | ||
45 | fprintf(f, | |
46 | "/*\n\ | |
47 | * FILE : %s\n\ | |
48 | * \n\ | |
49 | * This file was automatically generated by :\n\ | |
50 | * Simplified Wrapper and Interface Generator (SWIG)\n\ | |
51 | * Version %d.%d %s\n\ | |
52 | * \n\ | |
53 | * Portions Copyright (c) 1995-1998\n\ | |
54 | * The University of Utah and The Regents of the University of California.\n\ | |
55 | * Permission is granted to distribute this file in any manner provided\n\ | |
56 | * this notice remains intact.\n\ | |
57 | * \n\ | |
58 | * Do not make changes to this file--changes will be lost!\n\ | |
59 | *\n\ | |
60 | */\n\n", fn_header, SWIG_MAJOR_VERSION, SWIG_MINOR_VERSION, SWIG_SPIN); | |
61 | ||
62 | fprintf(f,"\n#define SWIGCODE\n"); | |
63 | ||
64 | } | |
65 | ||
66 | // ----------------------------------------------------------------------------- | |
67 | // emit_extern_var(char *decl, DataType *t, int extern_type, FILE *f) | |
68 | // | |
69 | // Emits an external variables declaration. Extern_type defines the | |
70 | // type of external declaration. Currently, only C/C++ declarations | |
71 | // are allowed, but this might be extended to allow Fortran linkage | |
72 | // someday | |
73 | // | |
74 | // Inputs : | |
75 | // decl = Name of the declaration | |
76 | // t = Datatype | |
77 | // extern_type = Numeric code indicating type of extern | |
78 | // 0 - No "extern" | |
79 | // 1,2 - Normal extern (C/C++) | |
80 | // f = FILE handle | |
81 | // | |
82 | // Output : None | |
83 | // | |
84 | // Side Effects : None | |
85 | // ----------------------------------------------------------------------------- | |
86 | ||
87 | void emit_extern_var(char *decl, DataType *t, int extern_type, FILE *f) { | |
88 | char *arr = 0; | |
89 | ||
90 | if (t->arraystr) arr = t->arraystr; | |
91 | else arr = ""; | |
92 | ||
93 | switch(extern_type) { | |
94 | ||
95 | case 0: | |
96 | // No extern. Just a forward reference | |
97 | if (t->arraystr) | |
98 | t->is_pointer--; | |
99 | ||
100 | if (t->is_reference) { | |
101 | t->is_pointer--; | |
102 | fprintf(f,"%s& %s%s; \n", t->print_full(), decl, arr); | |
103 | t->is_pointer++; | |
104 | } else { | |
105 | fprintf(f,"%s %s%s; \n", t->print_full(), decl,arr); | |
106 | } | |
107 | if (t->arraystr) | |
108 | t->is_pointer++; | |
109 | break; | |
110 | case 1: case 2: | |
111 | if (t->arraystr) | |
112 | t->is_pointer--; | |
113 | ||
114 | // Normal C/C++ extern | |
115 | // fprintf(f,"#line %d \"%s\"\n", line_number, input_file); | |
116 | if (t->is_reference) { | |
117 | t->is_pointer--; | |
118 | fprintf(f,"extern %s& %s%s; \n", t->print_full(), decl,arr); | |
119 | t->is_pointer++; | |
120 | } else { | |
121 | fprintf(f,"extern %s %s%s; \n", t->print_full(), decl,arr); | |
122 | } | |
123 | if (t->arraystr) | |
124 | t->is_pointer++; | |
125 | ||
126 | default: | |
127 | break; | |
128 | } | |
129 | } | |
130 | ||
131 | // ----------------------------------------------------------------------------- | |
132 | // emit_extern_func(char *decl, DataType *t, ParmList *L, int extern_type, | |
133 | // FILE *f) | |
134 | // | |
135 | // Emits an external function declaration (similiar to emit_extern_var). | |
136 | // | |
137 | // Inputs : | |
138 | // decl = Name of declaration | |
139 | // t = Return datatype | |
140 | // L = parameter list | |
141 | // extern_type = Type of extern | |
142 | // 0 - No "extern" | |
143 | // 1 - extern | |
144 | // 2 - extern "C" | |
145 | // 3 - Function declaration (with arg names) | |
146 | // f = FILE Handle | |
147 | // | |
148 | // Output : None | |
149 | // | |
150 | // Side Effects : None | |
151 | // | |
152 | // ----------------------------------------------------------------------------- | |
153 | ||
154 | void emit_extern_func(char *decl, DataType *t, ParmList *L, int extern_type, FILE *f) { | |
155 | ||
156 | switch(extern_type) { | |
157 | case 0: | |
158 | if (t->is_reference) { | |
159 | t->is_pointer--; | |
160 | fprintf(f,"%s&", t->print_full()); | |
161 | t->is_pointer++; | |
162 | } else { | |
163 | fprintf(f,"%s", t->print_full()); | |
164 | } | |
165 | ||
166 | fprintf(f,"%s(", decl); | |
167 | L->print_types(f); | |
168 | fprintf(f,");\n"); | |
169 | break; | |
170 | case 1: | |
171 | // Normal C/C++ extern | |
172 | // fprintf(f,"#line %d \"%s\"\n", line_number, input_file); | |
173 | if (t->is_reference) { | |
174 | t->is_pointer--; | |
175 | fprintf(f,"extern %s&", t->print_full()); | |
176 | t->is_pointer++; | |
177 | } else { | |
178 | fprintf(f,"extern %s", t->print_full()); | |
179 | } | |
180 | fprintf(f,"%s(", decl); | |
181 | L->print_types(f); | |
182 | fprintf(f,");\n"); | |
183 | break; | |
184 | case 2: | |
185 | // A C++ --- > C Extern | |
186 | // fprintf(f,"#line %d \"%s\"\n", line_number, input_file); | |
187 | if (t->is_reference) { | |
188 | t->is_pointer--; | |
189 | fprintf(f,"extern \"C\" %s&", t->print_full()); | |
190 | t->is_pointer++; | |
191 | } else { | |
192 | fprintf(f,"extern \"C\" %s", t->print_full()); | |
193 | } | |
194 | fprintf(f,"%s(", decl); | |
195 | L->print_types(f); | |
196 | fprintf(f,");\n"); | |
197 | break; | |
198 | case 3: | |
199 | // A function declaration (for inlining ) | |
200 | if (t->is_reference) { | |
201 | t->is_pointer--; | |
202 | fprintf(f,"%s&", t->print_full()); | |
203 | t->is_pointer++; | |
204 | } else { | |
205 | fprintf(f,"%s", t->print_full()); | |
206 | } | |
207 | ||
208 | fprintf(f,"%s(", decl); | |
209 | L->print_args(f); | |
210 | fprintf(f,")\n"); | |
211 | break; | |
212 | default: | |
213 | break; | |
214 | } | |
215 | } | |
216 | ||
217 | // ----------------------------------------------------------------------------- | |
218 | // char *emit_local(int i) | |
219 | // | |
220 | // Returns the name of local variable for parameter i | |
221 | // | |
222 | // Inputs : i = Parameter number | |
223 | // | |
224 | // Output : NULL terminated ASCII string | |
225 | // | |
226 | // Side Effects : Result is left in a static local variable. | |
227 | // ----------------------------------------------------------------------------- | |
228 | ||
229 | char *emit_local(int i) { | |
230 | static char arg[64]; | |
231 | ||
232 | sprintf(arg,"_arg%d", i); | |
233 | return arg; | |
234 | } | |
235 | ||
236 | // ----------------------------------------------------------------------------- | |
237 | // int emit_args(char *d, DataType *rt, ParmList *l, FILE *f) | |
238 | // | |
239 | // Creates a list of variable declarations for both the return value | |
240 | // and function parameters. | |
241 | // | |
242 | // The return value is always called _result and arguments label as | |
243 | // _arg0, _arg1, _arg2, etc... | |
244 | // | |
245 | // Returns the number of parameters associated with a function. | |
246 | // | |
247 | // Inputs : | |
248 | // d = Name of function | |
249 | // rt = Return type | |
250 | // l = Parameter list | |
251 | // f = FILE Handle | |
252 | // | |
253 | // Output : Number of function arguments | |
254 | // | |
255 | // Side Effects : None | |
256 | // | |
257 | // Note : This function is obsolete. Use emit_args below... | |
258 | // ----------------------------------------------------------------------------- | |
259 | ||
260 | int emit_args(DataType *rt, ParmList *l, FILE *f) { | |
261 | ||
262 | Parm *p; | |
263 | int i; | |
264 | char temp[64]; | |
265 | String def; | |
266 | char *tm; | |
267 | ||
268 | // Declare the return variable | |
269 | ||
270 | if ((rt->type != T_VOID) || (rt->is_pointer)) { | |
271 | if ((rt->type == T_USER) && (!rt->is_pointer)) { | |
272 | ||
273 | // Special case for return by "value" | |
274 | ||
275 | rt->is_pointer++; | |
276 | fprintf(f,"\t %s _result;\n", rt->print_type()); | |
277 | rt->is_pointer--; | |
278 | } else { | |
279 | ||
280 | // Normal return value | |
281 | ||
282 | fprintf(f,"\t %s _result;\n", rt->print_type()); | |
283 | } | |
284 | } | |
285 | ||
286 | // Emit function arguments | |
287 | ||
288 | i = 0; | |
289 | p = l->get_first(); | |
290 | while (p != 0) { | |
291 | if ((p->t->type != T_VOID) || (p->t->is_pointer)) { | |
292 | sprintf(temp,"_arg%d", i); | |
293 | if (p->defvalue) { | |
294 | if ((p->t->is_reference) || ((p->t->type == T_USER) && (p->call_type == CALL_REFERENCE))) | |
295 | fprintf(f,"\t %s _arg%d = &%s;\n", p->t->print_type(),i, p->defvalue); | |
296 | else | |
297 | fprintf(f,"\t %s _arg%d = %s;\n", p->t->print_type(),i, p->defvalue); | |
298 | } else { | |
299 | fprintf(f,"\t %s _arg%d;\n", p->t->print_type(),i); | |
300 | tm = typemap_lookup("arginit", typemap_lang, p->t, p->name,"",temp); | |
301 | if (tm) { | |
302 | def << tm; | |
303 | } | |
304 | } | |
305 | ||
306 | // Check for ignore or default typemaps | |
307 | ||
308 | tm = typemap_lookup("default",typemap_lang,p->t,p->name,"",temp); | |
309 | if (tm) | |
310 | def << tm; | |
311 | tm = typemap_lookup("ignore",typemap_lang,p->t,p->name,"",temp); | |
312 | ||
313 | if (tm) { | |
314 | def << tm; | |
315 | p->ignore = 1; | |
316 | } | |
317 | tm = typemap_check("build",typemap_lang,p->t,p->name); | |
318 | if (tm) { | |
319 | p->ignore = 1; | |
320 | } | |
321 | i++; | |
322 | } | |
323 | p = l->get_next(); | |
324 | } | |
325 | ||
326 | fprintf(f,"%s",def.get()); | |
327 | ||
328 | // i now contains number of parameters | |
329 | ||
330 | return(i); | |
331 | ||
332 | } | |
333 | ||
334 | ||
335 | // ----------------------------------------------------------------------------- | |
336 | // int emit_args(char *d, DataType *rt, ParmList *l, WrapperFunction &f) | |
337 | // | |
338 | // Creates a list of variable declarations for both the return value | |
339 | // and function parameters. | |
340 | // | |
341 | // The return value is always called _result and arguments label as | |
342 | // _arg0, _arg1, _arg2, etc... | |
343 | // | |
344 | // Returns the number of parameters associated with a function. | |
345 | // | |
346 | // Inputs : | |
347 | // d = Name of function | |
348 | // rt = Return type | |
349 | // l = Parameter list | |
350 | // f = Wrapper function object | |
351 | // | |
352 | // Output : Number of function arguments | |
353 | // | |
354 | // Side Effects : None | |
355 | // | |
356 | // ----------------------------------------------------------------------------- | |
357 | ||
358 | int emit_args(DataType *rt, ParmList *l, WrapperFunction &f) { | |
359 | ||
360 | Parm *p; | |
361 | int i; | |
362 | char *tm; | |
363 | ||
364 | // Declare the return variable | |
365 | ||
366 | if ((rt->type != T_VOID) || (rt->is_pointer)) { | |
367 | if ((rt->type == T_USER) && (!rt->is_pointer)) { | |
368 | ||
369 | // Special case for return by "value" | |
370 | rt->is_pointer++; | |
371 | f.add_local(rt->print_type(), "_result"); | |
372 | rt->is_pointer--; | |
373 | } else { | |
374 | ||
375 | // Normal return value | |
376 | ||
377 | f.add_local(rt->print_type(), "_result"); | |
378 | } | |
379 | } | |
380 | ||
381 | // Emit function arguments | |
382 | ||
383 | i = 0; | |
384 | p = l->get_first(); | |
385 | while (p != 0) { | |
386 | if ((p->t->type != T_VOID) || (p->t->is_pointer)) { | |
387 | char *temp = emit_local(i); | |
388 | // Figure out default values | |
389 | if (((p->t->is_reference) && (p->defvalue)) || | |
390 | ((p->t->type == T_USER) && (p->call_type == CALL_REFERENCE) && (p->defvalue))) { | |
391 | String deftmp; | |
392 | deftmp << "(" << p->t->print_type() << ") &" << p->defvalue; | |
393 | f.add_local(p->t->print_type(),temp,deftmp.get()); | |
394 | } else { | |
395 | String deftmp; | |
396 | char *dv = 0; | |
397 | if (p->defvalue) { | |
398 | deftmp << "(" << p->t->print_type() << ") " << p->defvalue; | |
399 | dv = deftmp.get(); | |
400 | } | |
401 | f.add_local(p->t->print_type(), temp, dv); | |
402 | tm = typemap_lookup("arginit", typemap_lang, p->t,p->name,"",temp,&f); | |
403 | if (tm) { | |
404 | f.code << tm << "\n"; | |
405 | } | |
406 | } | |
407 | // Check for ignore or default typemaps | |
408 | tm = typemap_lookup("default",typemap_lang,p->t,p->name,"",temp,&f); | |
409 | if (tm) | |
410 | f.code << tm << "\n"; | |
411 | tm = typemap_lookup("ignore",typemap_lang,p->t,p->name,"",temp,&f); | |
412 | if (tm) { | |
413 | f.code << tm << "\n"; | |
414 | p->ignore = 1; | |
415 | } | |
416 | tm = typemap_check("build",typemap_lang,p->t,p->name); | |
417 | if (tm) { | |
418 | p->ignore = 1; | |
419 | } | |
420 | i++; | |
421 | } | |
422 | p = l->get_next(); | |
423 | } | |
424 | ||
425 | // i now contains number of parameters | |
426 | return(i); | |
427 | } | |
428 | ||
429 | // ----------------------------------------------------------------------------- | |
430 | // int emit_func_call(char *decl, DataType *t, ParmList *l, FILE *f) | |
431 | // | |
432 | // Emits code for a function call. | |
433 | // | |
434 | // Inputs : | |
435 | // decl = name of function | |
436 | // t = Return datatype | |
437 | // l = Parameter list | |
438 | // f = FILE Handle | |
439 | // | |
440 | // Output : None | |
441 | // | |
442 | // Side Effects : None | |
443 | // | |
444 | // Note : This function is obsolete | |
445 | // ----------------------------------------------------------------------------- | |
446 | ||
447 | void emit_func_call(char *decl, DataType *t, ParmList *l, FILE *f) { | |
448 | ||
449 | int i; | |
450 | Parm *p; | |
451 | ||
452 | // fprintf(f,"#line %d \"%s\"\n", line_number, input_file); | |
453 | fprintf(f,"\t "); | |
454 | ||
455 | // First check if there is a return value | |
456 | ||
457 | if ((t->type != T_VOID) || (t->is_pointer)) { | |
458 | if ((t->type == T_USER) && (!t->is_pointer)) { | |
459 | ||
460 | // Special case for return by "value" | |
461 | // Caution : This *will* cause a memory leak if not | |
462 | // used properly. | |
463 | ||
464 | if (CPlusPlus) { | |
465 | fprintf(f,"_result = new %s(", t->print_type()); | |
466 | } else { | |
467 | t->is_pointer++; | |
468 | fprintf(f,"_result = %s malloc(sizeof(", t->print_cast()); | |
469 | t->is_pointer--; | |
470 | fprintf(f,"%s));\n", t->print_type()); | |
471 | fprintf(f,"\t*(_result) = "); | |
472 | } | |
473 | } else { | |
474 | // Check if this is a C++ reference | |
475 | if (t->is_reference) { | |
476 | t->is_pointer--; | |
477 | fprintf(f,"%s& _result_ref = ", t->print_full()); | |
478 | t->is_pointer++; | |
479 | } else { | |
480 | ||
481 | // Normal return values | |
482 | fprintf(f,"_result = %s", t->print_cast()); | |
483 | } | |
484 | } | |
485 | } | |
486 | ||
487 | // Now print out function call | |
488 | ||
489 | fprintf(f,"%s(",decl); | |
490 | ||
491 | i = 0; | |
492 | p = l->get_first(); | |
493 | while(p != 0) { | |
494 | if ((p->t->type != T_VOID) || (p->t->is_pointer)){ | |
495 | fprintf(f,"%s",p->t->print_arraycast()); | |
496 | if ((!p->t->is_reference) && (p->call_type & CALL_VALUE)) fprintf(f,"&"); | |
497 | if ((!(p->call_type & CALL_VALUE)) && | |
498 | ((p->t->is_reference) || (p->call_type & CALL_REFERENCE))) | |
499 | fprintf(f,"*"); | |
500 | fprintf(f,"_arg%d",i); | |
501 | i++; | |
502 | } | |
503 | p = l->get_next(); | |
504 | if (p != 0) | |
505 | fprintf(f,","); | |
506 | } | |
507 | ||
508 | fprintf(f,")"); | |
509 | if ((t->type == T_USER) && (!t->is_pointer)) { | |
510 | if (CPlusPlus) { | |
511 | fprintf(f,")"); | |
512 | } | |
513 | } | |
514 | fprintf(f,";\n"); | |
515 | if (t->is_reference) { | |
516 | fprintf(f,"\t _result = %s &_result_ref;\n", t->print_cast()); | |
517 | } | |
518 | } | |
519 | ||
520 | ||
521 | ||
522 | // ----------------------------------------------------------------------------- | |
523 | // int emit_func_call(char *decl, DataType *t, ParmList *l, WrapperFunction &f) | |
524 | // | |
525 | // Emits code for a function call (new version). | |
526 | // | |
527 | // Exception handling support : | |
528 | // | |
529 | // - This function checks to see if any sort of exception mechanism | |
530 | // has been defined. If so, we emit the function call in an exception | |
531 | // handling block. | |
532 | // | |
533 | // Inputs : | |
534 | // decl = name of function | |
535 | // t = Return datatype | |
536 | // l = Parameter list | |
537 | // f = WrapperFunction object | |
538 | // | |
539 | // Output : None | |
540 | // | |
541 | // Side Effects : None | |
542 | // | |
543 | // ----------------------------------------------------------------------------- | |
544 | ||
545 | void emit_func_call(char *decl, DataType *t, ParmList *l, WrapperFunction &f) { | |
546 | ||
547 | int i; | |
548 | Parm *p; | |
549 | String fcall; | |
550 | String exc; | |
551 | char *tm; | |
552 | ||
553 | // f.code << "#line " << line_number << " \"" << input_file << "\"\n"; | |
554 | fcall << tab4; | |
555 | ||
556 | // First check if there is a return value | |
557 | ||
558 | if ((t->type != T_VOID) || (t->is_pointer)) { | |
559 | if ((t->type == T_USER) && (!t->is_pointer)) { | |
560 | ||
561 | // Special case for return by "value" | |
562 | // Caution : This *will* cause a memory leak if not | |
563 | // used properly. | |
564 | ||
565 | if (CPlusPlus) { | |
566 | fcall << "_result = new " << t->print_type() << "("; | |
567 | } else { | |
568 | t->is_pointer++; | |
569 | fcall << "_result = " << t->print_cast() << " malloc(sizeof("; | |
570 | t->is_pointer--; | |
571 | fcall << t->print_type() << "));\n"; | |
572 | fcall << tab4 << "*(_result) = "; | |
573 | } | |
574 | } else { | |
575 | // Check if this is a C++ reference | |
576 | if (t->is_reference) { | |
577 | t->is_pointer--; | |
578 | fcall << t->print_full() << "& _result_ref = "; | |
579 | t->is_pointer++; | |
580 | } else { | |
581 | ||
582 | // Normal return value | |
583 | fcall << "_result = " << t->print_cast(); | |
584 | } | |
585 | } | |
586 | } | |
587 | ||
588 | // Now print out function call | |
589 | ||
590 | fcall << decl << "("; | |
591 | ||
592 | i = 0; | |
593 | p = l->get_first(); | |
594 | while(p != 0) { | |
595 | if ((p->t->type != T_VOID) || (p->t->is_pointer)){ | |
596 | fcall << p->t->print_arraycast(); | |
597 | if ((!p->t->is_reference) && (p->call_type & CALL_VALUE)) | |
598 | fcall << "&"; | |
599 | if ((!(p->call_type & CALL_VALUE)) && | |
600 | ((p->t->is_reference) || (p->call_type & CALL_REFERENCE))) | |
601 | fcall << "*"; | |
602 | fcall << emit_local(i); | |
603 | i++; | |
604 | } | |
605 | p = l->get_next(); | |
606 | if (p != 0) | |
607 | fcall << ","; | |
608 | } | |
609 | fcall << ")"; | |
610 | ||
611 | if ((t->type == T_USER) && (!t->is_pointer)) { | |
612 | if (CPlusPlus) { | |
613 | fcall << ")"; | |
614 | } | |
615 | } | |
616 | fcall << ";\n"; | |
617 | ||
618 | if (t->is_reference) { | |
619 | fcall << tab4 << "_result = "<< t->print_cast() << " &_result_ref;\n"; | |
620 | } | |
621 | // Check for exception handling | |
622 | ||
623 | if ((tm = typemap_lookup("except",typemap_lang,t,decl,"_result",""))) { | |
624 | // Found a type-specific mapping | |
625 | exc << tm; | |
626 | exc.replace("$function",fcall); | |
627 | exc.replace("$name",decl); | |
628 | f.code << exc; | |
629 | } else if ((tm = fragment_lookup("except",typemap_lang, t->id))) { | |
630 | exc << tm; | |
631 | exc.replace("$function",fcall); | |
632 | exc.replace("$name",decl); | |
633 | f.code << exc; | |
634 | } else { | |
635 | f.code << fcall; | |
636 | } | |
637 | } | |
638 | ||
639 | // ----------------------------------------------------------------------------- | |
640 | // void emit_hex(FILE *f) | |
641 | // | |
642 | // Emits the default C-code to handle pointers. This is normally contained | |
643 | // in the SWIG library file 'swigptr.swg' | |
644 | // | |
645 | // Inputs : f = FILE handle | |
646 | // | |
647 | // Output : None | |
648 | // | |
649 | // Side Effects : None | |
650 | // ----------------------------------------------------------------------------- | |
651 | ||
652 | void emit_hex(FILE *f) { | |
653 | ||
654 | int stat; | |
655 | ||
656 | // Look for a pointer configuration file | |
657 | ||
658 | stat = insert_file("swigptr.swg", f); | |
659 | ||
660 | if (stat == -1) { | |
661 | fprintf(stderr,"** Fatal error. Unable to locate 'swigptr.swg'\n"); | |
662 | SWIG_exit(1); | |
663 | } | |
664 | } | |
665 | ||
666 | // ----------------------------------------------------------------------------- | |
667 | // void emit_set_get(char *name, char *iname, DataType *type) | |
668 | // | |
669 | // Emits a pair of functions to set/get the value of a variable. | |
670 | // This should be used as backup in case the target language can't | |
671 | // provide variable linking. | |
672 | // | |
673 | // double foo; | |
674 | // | |
675 | // Gets translated into the following : | |
676 | // | |
677 | // double foo_set(double x) { | |
678 | // return foo = x; | |
679 | // } | |
680 | // | |
681 | // double foo_get() { | |
682 | // return foo; | |
683 | // } | |
684 | // | |
685 | // Need to handle special cases for char * and for user | |
686 | // defined types. | |
687 | // | |
688 | // 1. char * | |
689 | // | |
690 | // Will free previous contents (if any) and allocate | |
691 | // new storage. Could be risky, but it's a reasonably | |
692 | // natural thing to do. | |
693 | // | |
694 | // 2. User_Defined | |
695 | // Will assign value from a pointer. | |
696 | // Will return a pointer to current value. | |
697 | // | |
698 | // | |
699 | // Inputs : | |
700 | // name = Name of variable | |
701 | // iname = Renamed version of variable | |
702 | // type = Datatype of the variable | |
703 | // | |
704 | // Output : None | |
705 | // | |
706 | // Side Effects : None | |
707 | // ----------------------------------------------------------------------------- | |
708 | ||
709 | void emit_set_get(char *name, char *iname, DataType *t) { | |
710 | ||
711 | Parm *p; | |
712 | ParmList *l; | |
713 | String new_name; | |
714 | String new_iname; | |
715 | String wname; | |
716 | ||
717 | // First write a function to set the variable of the variable | |
718 | ||
719 | if (!(Status & STAT_READONLY)) { | |
720 | if ((t->type == T_USER) && (!t->is_pointer)) { | |
721 | t->is_pointer++; | |
722 | fprintf(f_header,"static %s %s(%s val) {\n", | |
723 | t->print_type(), name_set(name), t->print_type()); | |
724 | t->is_pointer--; | |
725 | } else { | |
726 | fprintf(f_header,"static %s %s(%s val) {\n", | |
727 | t->print_type(), name_set(name), t->print_type()); | |
728 | } | |
729 | ||
730 | if ((t->type != T_VOID) || (t->is_pointer)) { | |
731 | if (!t->is_pointer) { | |
732 | ||
733 | // Have a real value here | |
734 | // If it's a user defined type, we'll do something special. | |
735 | // Otherwise, just assign it. | |
736 | ||
737 | if (t->type != T_USER) { | |
738 | fprintf(f_header,"\t return (%s) (%s = val);\n", t->print_type(), name); | |
739 | } else { | |
740 | fprintf(f_header,"\t %s = *(val);\n", name); | |
741 | t->is_pointer++; | |
742 | fprintf(f_header,"\t return (%s) &%s;\n", t->print_type(),name); | |
743 | t->is_pointer--; | |
744 | } | |
745 | } else { | |
746 | ||
747 | // Is a pointer type here. If string, we do something | |
748 | // special. Otherwise. No problem. | |
749 | ||
750 | if ((t->type == T_CHAR) && (t->is_pointer == 1)) { | |
751 | if (CPlusPlus) { | |
752 | fprintf(f_header,"\t if (%s) delete %s;\n", name,name); | |
753 | fprintf(f_header,"\t %s = new char[strlen(val)+1];\n",name); | |
754 | fprintf(f_header,"\t strcpy(%s,val);\n", name); | |
755 | fprintf(f_header,"\t return %s;\n", name); | |
756 | } else { | |
757 | fprintf(f_header,"\t if (%s) free(%s);\n", name,name); | |
758 | fprintf(f_header,"\t %s = (char *) malloc(strlen(val)+1);\n",name); | |
759 | fprintf(f_header,"\t strcpy(%s,val);\n", name); | |
760 | fprintf(f_header,"\t return %s;\n", name); | |
761 | } | |
762 | } else { | |
763 | fprintf(f_header,"\t return (%s) (%s = val);\n", t->print_type(), name); | |
764 | } | |
765 | } | |
766 | } | |
767 | ||
768 | fprintf(f_header,"}\n"); | |
769 | ||
770 | // Now wrap it. | |
771 | ||
772 | l = new ParmList; | |
773 | p = new Parm(t,0); | |
774 | if ((t->type == T_USER) && (!t->is_pointer)) p->t->is_pointer++; | |
775 | p->name = new char[1]; | |
776 | p->name[0] = 0; | |
777 | l->append(p); | |
778 | ||
779 | new_name = name_set(name); | |
780 | new_iname = name_set(iname); | |
781 | ||
782 | if ((t->type == T_USER) && (!t->is_pointer)) { | |
783 | t->is_pointer++; | |
784 | lang->create_function(new_name, new_iname, t, l); | |
785 | t->is_pointer--; | |
786 | } else { | |
787 | lang->create_function(new_name, new_iname, t, l); | |
788 | } | |
789 | delete l; | |
790 | delete p; | |
791 | if (doc_entry) doc_entry->usage << "\n"; | |
792 | } | |
793 | ||
794 | // Now write a function to get the value of the variable | |
795 | ||
796 | if ((t->type == T_USER) && (!t->is_pointer)) { | |
797 | t->is_pointer++; | |
798 | fprintf(f_header,"static %s %s() { \n", | |
799 | t->print_type(), name_get(name)); | |
800 | fprintf(f_header,"\t return (%s) &%s;\n", t->print_type(), name); | |
801 | t->is_pointer--; | |
802 | } else { | |
803 | fprintf(f_header,"static %s %s() { \n", | |
804 | t->print_type(), name_get(name)); | |
805 | fprintf(f_header,"\t return (%s) %s;\n", t->print_type(), name); | |
806 | } | |
807 | ||
808 | fprintf(f_header,"}\n"); | |
809 | ||
810 | // Wrap this function | |
811 | ||
812 | l = new ParmList; | |
813 | ||
814 | new_name = name_get(name); | |
815 | new_iname = name_get(iname); | |
816 | ||
817 | if ((t->type == T_USER) && (!t->is_pointer)) { | |
818 | t->is_pointer++; | |
819 | lang->create_function(new_name, new_iname, t, l); | |
820 | t->is_pointer--; | |
821 | } else { | |
822 | lang->create_function(new_name, new_iname, t, l); | |
823 | } | |
824 | delete l; | |
825 | } | |
826 | ||
827 | ||
828 | ||
829 |