]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wxSWIG/SWIG/emit.cxx
1 /*******************************************************************************
2 * Simplified Wrapper and Interface Generator (SWIG)
4 * Author : David Beazley
6 * Department of Computer Science
7 * University of Chicago
10 * beazley@cs.uchicago.edu
12 * Please read the file LICENSE for the copyright and terms by which SWIG
13 * can be used and distributed.
14 *******************************************************************************/
17 /*******************************************************************************
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
26 *******************************************************************************/
28 // -----------------------------------------------------------------------------
29 // void emit_banner(FILE *f)
31 // Emits the SWIG identifying banner in the wrapper file
33 // Inputs : f = FILE handle
37 // Side Effects : None
38 // -----------------------------------------------------------------------------
40 void emit_banner(FILE *f
) {
42 extern char *get_time();
43 extern char fn_header
[];
49 * This file was automatically generated by :\n\
50 * Simplified Wrapper and Interface Generator (SWIG)\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\
58 * Do not make changes to this file--changes will be lost!\n\
60 */\n\n", fn_header
, SWIG_MAJOR_VERSION
, SWIG_MINOR_VERSION
, SWIG_SPIN
);
62 fprintf(f
,"\n#define SWIGCODE\n");
66 // -----------------------------------------------------------------------------
67 // emit_extern_var(char *decl, DataType *t, int extern_type, FILE *f)
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
75 // decl = Name of the declaration
77 // extern_type = Numeric code indicating type of extern
79 // 1,2 - Normal extern (C/C++)
84 // Side Effects : None
85 // -----------------------------------------------------------------------------
87 void emit_extern_var(char *decl
, DataType
*t
, int extern_type
, FILE *f
) {
90 if (t
->arraystr
) arr
= t
->arraystr
;
96 // No extern. Just a forward reference
100 if (t
->is_reference
) {
102 fprintf(f
,"%s& %s%s; \n", t
->print_full(), decl
, arr
);
105 fprintf(f
,"%s %s%s; \n", t
->print_full(), decl
,arr
);
114 // Normal C/C++ extern
115 // fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
116 if (t
->is_reference
) {
118 fprintf(f
,"extern %s& %s%s; \n", t
->print_full(), decl
,arr
);
121 fprintf(f
,"extern %s %s%s; \n", t
->print_full(), decl
,arr
);
131 // -----------------------------------------------------------------------------
132 // emit_extern_func(char *decl, DataType *t, ParmList *L, int extern_type,
135 // Emits an external function declaration (similiar to emit_extern_var).
138 // decl = Name of declaration
139 // t = Return datatype
140 // L = parameter list
141 // extern_type = Type of extern
145 // 3 - Function declaration (with arg names)
150 // Side Effects : None
152 // -----------------------------------------------------------------------------
154 void emit_extern_func(char *decl
, DataType
*t
, ParmList
*L
, int extern_type
, FILE *f
) {
156 switch(extern_type
) {
158 if (t
->is_reference
) {
160 fprintf(f
,"%s&", t
->print_full());
163 fprintf(f
,"%s", t
->print_full());
166 fprintf(f
,"%s(", decl
);
171 // Normal C/C++ extern
172 // fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
173 if (t
->is_reference
) {
175 fprintf(f
,"extern %s&", t
->print_full());
178 fprintf(f
,"extern %s", t
->print_full());
180 fprintf(f
,"%s(", decl
);
185 // A C++ --- > C Extern
186 // fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
187 if (t
->is_reference
) {
189 fprintf(f
,"extern \"C\" %s&", t
->print_full());
192 fprintf(f
,"extern \"C\" %s", t
->print_full());
194 fprintf(f
,"%s(", decl
);
199 // A function declaration (for inlining )
200 if (t
->is_reference
) {
202 fprintf(f
,"%s&", t
->print_full());
205 fprintf(f
,"%s", t
->print_full());
208 fprintf(f
,"%s(", decl
);
217 // -----------------------------------------------------------------------------
218 // char *emit_local(int i)
220 // Returns the name of local variable for parameter i
222 // Inputs : i = Parameter number
224 // Output : NULL terminated ASCII string
226 // Side Effects : Result is left in a static local variable.
227 // -----------------------------------------------------------------------------
229 char *emit_local(int i
) {
232 sprintf(arg
,"_arg%d", i
);
236 // -----------------------------------------------------------------------------
237 // int emit_args(char *d, DataType *rt, ParmList *l, FILE *f)
239 // Creates a list of variable declarations for both the return value
240 // and function parameters.
242 // The return value is always called _result and arguments label as
243 // _arg0, _arg1, _arg2, etc...
245 // Returns the number of parameters associated with a function.
248 // d = Name of function
250 // l = Parameter list
253 // Output : Number of function arguments
255 // Side Effects : None
257 // Note : This function is obsolete. Use emit_args below...
258 // -----------------------------------------------------------------------------
260 int emit_args(DataType
*rt
, ParmList
*l
, FILE *f
) {
268 // Declare the return variable
270 if ((rt
->type
!= T_VOID
) || (rt
->is_pointer
)) {
271 if ((rt
->type
== T_USER
) && (!rt
->is_pointer
)) {
273 // Special case for return by "value"
276 fprintf(f
,"\t %s _result;\n", rt
->print_type());
280 // Normal return value
282 fprintf(f
,"\t %s _result;\n", rt
->print_type());
286 // Emit function arguments
291 if ((p
->t
->type
!= T_VOID
) || (p
->t
->is_pointer
)) {
292 sprintf(temp
,"_arg%d", i
);
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
);
297 fprintf(f
,"\t %s _arg%d = %s;\n", p
->t
->print_type(),i
, p
->defvalue
);
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
);
306 // Check for ignore or default typemaps
308 tm
= typemap_lookup("default",typemap_lang
,p
->t
,p
->name
,"",temp
);
311 tm
= typemap_lookup("ignore",typemap_lang
,p
->t
,p
->name
,"",temp
);
317 tm
= typemap_check("build",typemap_lang
,p
->t
,p
->name
);
326 fprintf(f
,"%s",def
.get());
328 // i now contains number of parameters
335 // -----------------------------------------------------------------------------
336 // int emit_args(char *d, DataType *rt, ParmList *l, WrapperFunction &f)
338 // Creates a list of variable declarations for both the return value
339 // and function parameters.
341 // The return value is always called _result and arguments label as
342 // _arg0, _arg1, _arg2, etc...
344 // Returns the number of parameters associated with a function.
347 // d = Name of function
349 // l = Parameter list
350 // f = Wrapper function object
352 // Output : Number of function arguments
354 // Side Effects : None
356 // -----------------------------------------------------------------------------
358 int emit_args(DataType
*rt
, ParmList
*l
, WrapperFunction
&f
) {
364 // Declare the return variable
366 if ((rt
->type
!= T_VOID
) || (rt
->is_pointer
)) {
367 if ((rt
->type
== T_USER
) && (!rt
->is_pointer
)) {
369 // Special case for return by "value"
371 f
.add_local(rt
->print_type(), "_result");
375 // Normal return value
377 f
.add_local(rt
->print_type(), "_result");
381 // Emit function arguments
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
))) {
392 deftmp
<< "(" << p
->t
->print_type() << ") &" << p
->defvalue
;
393 f
.add_local(p
->t
->print_type(),temp
,deftmp
.get());
398 deftmp
<< "(" << p
->t
->print_type() << ") " << p
->defvalue
;
401 f
.add_local(p
->t
->print_type(), temp
, dv
);
402 tm
= typemap_lookup("arginit", typemap_lang
, p
->t
,p
->name
,"",temp
,&f
);
404 f
.code
<< tm
<< "\n";
407 // Check for ignore or default typemaps
408 tm
= typemap_lookup("default",typemap_lang
,p
->t
,p
->name
,"",temp
,&f
);
410 f
.code
<< tm
<< "\n";
411 tm
= typemap_lookup("ignore",typemap_lang
,p
->t
,p
->name
,"",temp
,&f
);
413 f
.code
<< tm
<< "\n";
416 tm
= typemap_check("build",typemap_lang
,p
->t
,p
->name
);
425 // i now contains number of parameters
429 // -----------------------------------------------------------------------------
430 // int emit_func_call(char *decl, DataType *t, ParmList *l, FILE *f)
432 // Emits code for a function call.
435 // decl = name of function
436 // t = Return datatype
437 // l = Parameter list
442 // Side Effects : None
444 // Note : This function is obsolete
445 // -----------------------------------------------------------------------------
447 void emit_func_call(char *decl
, DataType
*t
, ParmList
*l
, FILE *f
) {
452 // fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
455 // First check if there is a return value
457 if ((t
->type
!= T_VOID
) || (t
->is_pointer
)) {
458 if ((t
->type
== T_USER
) && (!t
->is_pointer
)) {
460 // Special case for return by "value"
461 // Caution : This *will* cause a memory leak if not
465 fprintf(f
,"_result = new %s(", t
->print_type());
468 fprintf(f
,"_result = %s malloc(sizeof(", t
->print_cast());
470 fprintf(f
,"%s));\n", t
->print_type());
471 fprintf(f
,"\t*(_result) = ");
474 // Check if this is a C++ reference
475 if (t
->is_reference
) {
477 fprintf(f
,"%s& _result_ref = ", t
->print_full());
481 // Normal return values
482 fprintf(f
,"_result = %s", t
->print_cast());
487 // Now print out function call
489 fprintf(f
,"%s(",decl
);
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
)))
500 fprintf(f
,"_arg%d",i
);
509 if ((t
->type
== T_USER
) && (!t
->is_pointer
)) {
515 if (t
->is_reference
) {
516 fprintf(f
,"\t _result = %s &_result_ref;\n", t
->print_cast());
522 // -----------------------------------------------------------------------------
523 // int emit_func_call(char *decl, DataType *t, ParmList *l, WrapperFunction &f)
525 // Emits code for a function call (new version).
527 // Exception handling support :
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
534 // decl = name of function
535 // t = Return datatype
536 // l = Parameter list
537 // f = WrapperFunction object
541 // Side Effects : None
543 // -----------------------------------------------------------------------------
545 void emit_func_call(char *decl
, DataType
*t
, ParmList
*l
, WrapperFunction
&f
) {
553 // f.code << "#line " << line_number << " \"" << input_file << "\"\n";
556 // First check if there is a return value
558 if ((t
->type
!= T_VOID
) || (t
->is_pointer
)) {
559 if ((t
->type
== T_USER
) && (!t
->is_pointer
)) {
561 // Special case for return by "value"
562 // Caution : This *will* cause a memory leak if not
566 fcall
<< "_result = new " << t
->print_type() << "(";
569 fcall
<< "_result = " << t
->print_cast() << " malloc(sizeof(";
571 fcall
<< t
->print_type() << "));\n";
572 fcall
<< tab4
<< "*(_result) = ";
575 // Check if this is a C++ reference
576 if (t
->is_reference
) {
578 fcall
<< t
->print_full() << "& _result_ref = ";
582 // Normal return value
583 fcall
<< "_result = " << t
->print_cast();
588 // Now print out function call
590 fcall
<< decl
<< "(";
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
))
599 if ((!(p
->call_type
& CALL_VALUE
)) &&
600 ((p
->t
->is_reference
) || (p
->call_type
& CALL_REFERENCE
)))
602 fcall
<< emit_local(i
);
611 if ((t
->type
== T_USER
) && (!t
->is_pointer
)) {
618 if (t
->is_reference
) {
619 fcall
<< tab4
<< "_result = "<< t
->print_cast() << " &_result_ref;\n";
621 // Check for exception handling
623 if ((tm
= typemap_lookup("except",typemap_lang
,t
,decl
,"_result",""))) {
624 // Found a type-specific mapping
626 exc
.replace("$function",fcall
);
627 exc
.replace("$name",decl
);
629 } else if ((tm
= fragment_lookup("except",typemap_lang
, t
->id
))) {
631 exc
.replace("$function",fcall
);
632 exc
.replace("$name",decl
);
639 // -----------------------------------------------------------------------------
640 // void emit_hex(FILE *f)
642 // Emits the default C-code to handle pointers. This is normally contained
643 // in the SWIG library file 'swigptr.swg'
645 // Inputs : f = FILE handle
649 // Side Effects : None
650 // -----------------------------------------------------------------------------
652 void emit_hex(FILE *f
) {
656 // Look for a pointer configuration file
658 stat
= insert_file("swigptr.swg", f
);
661 fprintf(stderr
,"** Fatal error. Unable to locate 'swigptr.swg'\n");
666 // -----------------------------------------------------------------------------
667 // void emit_set_get(char *name, char *iname, DataType *type)
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.
675 // Gets translated into the following :
677 // double foo_set(double x) {
681 // double foo_get() {
685 // Need to handle special cases for char * and for user
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.
695 // Will assign value from a pointer.
696 // Will return a pointer to current value.
700 // name = Name of variable
701 // iname = Renamed version of variable
702 // type = Datatype of the variable
706 // Side Effects : None
707 // -----------------------------------------------------------------------------
709 void emit_set_get(char *name
, char *iname
, DataType
*t
) {
717 // First write a function to set the variable of the variable
719 if (!(Status
& STAT_READONLY
)) {
720 if ((t
->type
== T_USER
) && (!t
->is_pointer
)) {
722 fprintf(f_header
,"static %s %s(%s val) {\n",
723 t
->print_type(), name_set(name
), t
->print_type());
726 fprintf(f_header
,"static %s %s(%s val) {\n",
727 t
->print_type(), name_set(name
), t
->print_type());
730 if ((t
->type
!= T_VOID
) || (t
->is_pointer
)) {
731 if (!t
->is_pointer
) {
733 // Have a real value here
734 // If it's a user defined type, we'll do something special.
735 // Otherwise, just assign it.
737 if (t
->type
!= T_USER
) {
738 fprintf(f_header
,"\t return (%s) (%s = val);\n", t
->print_type(), name
);
740 fprintf(f_header
,"\t %s = *(val);\n", name
);
742 fprintf(f_header
,"\t return (%s) &%s;\n", t
->print_type(),name
);
747 // Is a pointer type here. If string, we do something
748 // special. Otherwise. No problem.
750 if ((t
->type
== T_CHAR
) && (t
->is_pointer
== 1)) {
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
);
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
);
763 fprintf(f_header
,"\t return (%s) (%s = val);\n", t
->print_type(), name
);
768 fprintf(f_header
,"}\n");
774 if ((t
->type
== T_USER
) && (!t
->is_pointer
)) p
->t
->is_pointer
++;
775 p
->name
= new char[1];
779 new_name
= name_set(name
);
780 new_iname
= name_set(iname
);
782 if ((t
->type
== T_USER
) && (!t
->is_pointer
)) {
784 lang
->create_function(new_name
, new_iname
, t
, l
);
787 lang
->create_function(new_name
, new_iname
, t
, l
);
791 if (doc_entry
) doc_entry
->usage
<< "\n";
794 // Now write a function to get the value of the variable
796 if ((t
->type
== T_USER
) && (!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
);
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
);
808 fprintf(f_header
,"}\n");
810 // Wrap this function
814 new_name
= name_get(name
);
815 new_iname
= name_get(iname
);
817 if ((t
->type
== T_USER
) && (!t
->is_pointer
)) {
819 lang
->create_function(new_name
, new_iname
, t
, l
);
822 lang
->create_function(new_name
, new_iname
, t
, l
);