]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wxSWIG/SWIG/cplus.cxx
Since I have made several changes to SWIG over the years to accomodate
[wxWidgets.git] / wxPython / wxSWIG / SWIG / cplus.cxx
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 /*******************************************************************************
19 * $Header$
20 *
21 * File : cplus.cxx
22 *
23 * This module defines parser entry points for supporting C++. Primarily
24 * this module is in charge of keeping track of the contents of C++ classes,
25 * organizing inheritance, and other things.
26 *
27 * Eventually this module will be merged with the type handling mechanism
28 * in SWIG 2.0 so it's a little messy right now.
29 *
30 * General comments :
31 *
32 * 1. The words "simple" and "C++" are rarely used in the same
33 * sentence. Therefore this module is going to be some sort
34 * of compromise.
35 *
36 * 2. I'm using the "Annotated C++ Reference Manual" (ARM) as my
37 * reference for handling certain cases. Of course, there
38 * is a high probability that I have misinterpreted or overlooked
39 * certain cases.
40 *
41 * 3. It is not my intent to write a full C++ compiler.
42 *
43 * My goals are simple :
44 * - Support simple ANSI C-like class member functions and data.
45 * - Support constructors and destructors.
46 * - static member functions.
47 * - basic inheritance.
48 * - virtual functions.
49 * - References
50 *
51 * I do not plan to support the following anytime in the near future
52 * - Operator overloading
53 * - templates
54 *
55 * Caution :
56 *
57 * The control flow in this module is completely insane. But here's the
58 * rough outline.
59 *
60 * Stage 1 : SWIG Parsing
61 * cplus_open_class() - Open up a new class
62 * cplus_* - Add members to class
63 * cplus_inherit() - Inherit from base classes
64 * cplus_class_close() - Close class
65 *
66 * ...
67 * cplus_open_class()
68 * ...
69 * cplus_class_close()
70 *
71 * ... and so on, until the end of the file
72 *
73 * After stage 1, all classes have been read, but nothing has been
74 * sent to the language module yet.
75 *
76 * Stage 2 : Code generation
77 * For each class we've saved, do this :
78 * lang->cpp_open_class() - Open class
79 * lang->cpp_* - Emit members
80 * lang->cpp_inherit() - Inherit
81 * lang->cpp_close_class() - Close class
82 *
83 * This two-stage approach solves a number of problems related to working
84 * with multiple files, mutually referenced classes, add adding methods.
85 * Just keep in mind that all C++ code is emitted *after* an entire SWIG
86 * file has been parsed.
87 *
88 * Improved code generation and inheritance of added methods (2/18/97):
89 *
90 * Each C++ declaration now has an associated function name attached to it.
91 * For example :
92 *
93 * class Foo {
94 * void bar();
95 * }
96 *
97 * Generates a member function "bar()" with a accessor function named
98 * "Foo_bar()". We will use this recorded accessor function to generate
99 * better code for inheritance. For example :
100 *
101 * class Foo2 : public Foo {
102 *
103 * ...
104 * }
105 *
106 * Will create a function called "Foo2_bar()" that is really mapped
107 * onto the base-class method "Foo_bar()". This should improve
108 * code generation substantially.
109 *
110 * Tricky stuff :
111 * - Each target language is responsible for naming wrapper
112 * functions.
113 *
114 *******************************************************************************/
115
116 // Some status variables
117
118 static int Inherit_mode = 0; // Set if we're inheriting members
119 static char *ccode = 0; // Set to optional C code (if available)
120 static Hash *localtypes; // Localtype hash
121 static int abstract =0; // Status bit set during code generation
122
123 static int cpp_id = 0;
124
125 // Forward references
126
127 void cplus_member_func(char *, char *, DataType *, ParmList *, int);
128 void cplus_constructor(char *, char *, ParmList *);
129 void cplus_destructor(char *, char *);
130 void cplus_variable(char *, char *, DataType *);
131 void cplus_static_func(char *, char *, DataType *, ParmList *);
132 void cplus_declare_const(char *, char *, DataType *, char *);
133 void cplus_static_var(char *, char *, DataType *);
134 void cplus_inherit_decl(char **);
135
136 // -----------------------------------------------------------------------------
137 // void add_local_type(char *type, char *classname)
138 // void add_local_type(DataType *type, char *classname)
139 //
140 // Adds a new datatype to the local datatype hash. This is used to handle
141 // datatypes defined within a class.
142 //
143 // Inputs : Datatype to place in hash
144 //
145 // Output : None
146 //
147 // Side Effects : Updates localtypes hash.
148 // -----------------------------------------------------------------------------
149
150 static void add_local_type(char *type, char *classname) {
151 String str;
152
153 if (!localtypes) return; // No hash table initialized, ignore this
154
155 str << classname << "::" << type;
156 localtypes->add(type,copy_string(str));
157 }
158
159 void add_local_type(DataType *type, char *classname) {
160 add_local_type(type->name,classname);
161 }
162
163 // -----------------------------------------------------------------------------
164 // void update_local_type(DataType *type)
165 //
166 // Checks to see whether this datatype is part of a class definition. If so,
167 // we update the type-name by appending the class prefix to it. Uses the
168 // name stored in current_class unless unavailable.
169 //
170 // Inputs : type = Datatype
171 //
172 // Output : type is updated with a new name.
173 //
174 // Side Effects : None
175 // -----------------------------------------------------------------------------
176
177 static void update_local_type(DataType *type) {
178
179 char *newname = 0;
180
181 // Lookup the datatype in the hash table
182
183 if (!localtypes) return;
184
185 newname = (char *) localtypes->lookup(type->name);
186 if (newname) {
187 strcpy(type->name, newname);
188 }
189 }
190
191 // -----------------------------------------------------------------------------
192 // void update_parms(ParmList *l)
193 //
194 // Updates all of the parameters in a parameter list with the proper C++ prefix
195 // (if neccessary).
196 //
197 // Inputs : l = Parameter list
198 //
199 // Output : Parameter list l is updated (make sure its a copy!)
200 //
201 // Side Effects : None
202 // -----------------------------------------------------------------------------
203
204 static void update_parms(ParmList *l) {
205 Parm *p;
206 p = l->get_first();
207 while (p) {
208 update_local_type(p->t);
209
210 // Check for default arguments
211
212 if ((p->defvalue) && (localtypes)) {
213 char *s;
214 s = (char *) localtypes->lookup(p->defvalue);
215 if (s) {
216 delete p->defvalue;
217 p->defvalue = copy_string(s);
218 }
219 }
220 p = l->get_next();
221 }
222 }
223
224 // -----------------------------------------------------------------------
225 // class CPP_member
226 //
227 // Base class for various kinds of C++ members
228 // -----------------------------------------------------------------------
229 class CPP_member {
230 public:
231 char *name; // Name of the member
232 char *iname; // Name of member in the interpreter
233 int is_static; // Is this a static member?
234 int new_method; // Is this a new method (added by SWIG)?
235 int line; // What line number was this member on
236 char *file; // What file was this in?
237 char *code; // Was there any supplied code?
238 char *base; // Base class where this was defined
239 int inherited; // Was this member inherited?
240 DocEntry *de; // Documentation entry
241 CPP_member *next; // Next member (for building linked lists)
242 int id; // type id when created
243
244 virtual void inherit(int) { }; // Inheritance rule (optional)
245 virtual void emit() = 0; // Emit rule
246 };
247
248 // ----------------------------------------------------------------------
249 // class CPP_function : public CPP_member
250 //
251 // Structure for handling a C++ member function
252 // ----------------------------------------------------------------------
253
254 class CPP_function : public CPP_member {
255 public:
256 DataType *ret_type;
257 ParmList *parms;
258 int new_object;
259 int is_virtual;
260
261 CPP_function(char *n, char *i, DataType *t, ParmList *l, int s, int v = 0) {
262 name = copy_string(n);
263 iname = copy_string(i);
264 ret_type = new DataType(t);
265 parms = new ParmList(l);
266 is_static = s;
267 is_virtual = v;
268 new_method = AddMethods;
269 new_object = NewObject;
270 inherited = Inherit_mode;
271 de = 0;
272 next = 0;
273 line = line_number;
274 file = input_file;
275 if (Inherit_mode) {
276 id = cpp_id;
277 } else {
278 id = type_id;
279 }
280 if (AddMethods) {
281 if (strlen(CCode.get()))
282 code = copy_string(CCode.get());
283 else
284 code = 0;
285 } else {
286 code = 0;
287 }
288 }
289 void inherit(int mode) {
290 doc_entry = 0; // No documentation for an inherited member
291 if (mode & INHERIT_FUNC) {
292 // Set up the proper addmethods mode and provide C code (if provided)
293 int oldaddmethods = AddMethods;
294 int oldnewobject = NewObject;
295 AddMethods = new_method;
296 NewObject = new_object;
297 CCode = code;
298 if (is_static) {
299 cplus_static_func(name, iname, ret_type, parms);
300 } else {
301 cplus_member_func(name, iname, ret_type, parms, is_virtual);
302 }
303 AddMethods = oldaddmethods;
304 NewObject = oldnewobject;
305 CCode = "";
306 }
307 }
308 void emit() {
309 ParmList *l;
310 DataType *t;
311 AddMethods = new_method;
312 NewObject = new_object;
313 doc_entry = de; // Restore documentation entry
314 line_number = line; // Restore line and file
315 input_file = file;
316 ccode = code;
317
318 // Make a copy of the parameter list and upgrade its types
319
320 l = new ParmList(parms);
321 t = new DataType(ret_type);
322 update_parms(l);
323 update_local_type(t);
324 if (is_static) {
325 lang->cpp_static_func(name, iname, t, l);
326 } else {
327 lang->cpp_member_func(name, iname, t, l);
328 }
329 l->check_defined();
330 t->check_defined();
331 delete l;
332 delete t;
333 }
334 };
335
336 // --------------------------------------------------------------------------
337 // class CPP_constructor : public CPP_member
338 //
339 // Class for holding a C++ constructor definition.
340 // --------------------------------------------------------------------------
341
342 class CPP_constructor : public CPP_member {
343 public:
344 ParmList *parms;
345 CPP_constructor(char *n, char *i, ParmList *l) {
346 name = copy_string(n);
347 iname = copy_string(i);
348 parms = new ParmList(l);
349 new_method = AddMethods;
350 inherited = 0;
351 de = 0;
352 next = 0;
353 line = line_number;
354 file = input_file;
355 id = type_id;
356 if (AddMethods) {
357 if (strlen(CCode.get()))
358 code = copy_string(CCode.get());
359 else
360 code = 0;
361 } else {
362 code = 0;
363 }
364 }
365 void emit() {
366 if (1) {
367 ParmList *l;
368 AddMethods = new_method;
369 doc_entry = de;
370 line_number = line;
371 input_file = file;
372 ccode = code;
373
374 // Make a copy of the parameter list and upgrade its types
375
376 l = new ParmList(parms);
377 update_parms(l);
378 lang->cpp_constructor(name,iname,l);
379 l->check_defined();
380 delete l;
381 } else {
382 if (Verbose) {
383 fprintf(stderr,"%s:%d: Constructor for abstract base class ignored.\n",
384 file,line);
385 }
386 }
387 }
388 };
389
390
391 // --------------------------------------------------------------------------
392 // class CPP_destructor : public CPP_member
393 //
394 // Class for holding a destructor definition
395 // --------------------------------------------------------------------------
396
397 class CPP_destructor : public CPP_member {
398 public:
399
400 CPP_destructor(char *n, char *i) {
401 name = copy_string(n);
402 iname = copy_string(i);
403 new_method = AddMethods;
404 de = 0;
405 next = 0;
406 inherited = 0;
407 line = line_number;
408 file = input_file;
409 id = type_id;
410 if (AddMethods) {
411 if (strlen(CCode.get()))
412 code = copy_string(CCode.get());
413 else
414 code = 0;
415 } else {
416 code = 0;
417 }
418
419 }
420 void emit() {
421 AddMethods = new_method;
422 doc_entry = de;
423 line_number = line;
424 input_file = file;
425 ccode = code;
426 lang->cpp_destructor(name, iname);
427 }
428 };
429
430 // -------------------------------------------------------------------------
431 // class CPP_variable : public CPP_member
432 //
433 // Class for a managing a data member
434 // -------------------------------------------------------------------------
435
436 class CPP_variable : public CPP_member {
437 public:
438 DataType *type;
439 int status;
440 CPP_variable(char *n, char *i, DataType *t, int s) {
441 name = copy_string(n);
442 iname = copy_string(i);
443 type = new DataType(t);
444 is_static = s;
445 status = Status;
446 de = 0;
447 next = 0;
448 new_method = AddMethods;
449 line = line_number;
450 file = input_file;
451 if (Inherit_mode) {
452 id = cpp_id;
453 } else {
454 id = type_id;
455 }
456 code = 0;
457 inherited = 0;
458 }
459
460 // Emit code for this
461
462 void emit() {
463 DataType *t;
464 int old_status = Status;
465 doc_entry = de;
466 AddMethods = new_method;
467 Status = status;
468 line_number = line;
469 input_file = file;
470 ccode = code;
471
472 t = new DataType(type);
473 if (t->qualifier) {
474 // if (strcmp(t->qualifier,"const") == 0) Status = Status | STAT_READONLY;
475 }
476 update_local_type(t);
477 if (!is_static) {
478 lang->cpp_variable(name,iname,t);
479 } else {
480 lang->cpp_static_var(name,iname,t);
481 }
482 t->check_defined();
483 Status = old_status;
484 delete t;
485 }
486
487 // Inherit into another class
488
489 void inherit(int mode) {
490 int oldstatus = Status;
491 Status = status;
492 doc_entry = 0;
493 if (mode & INHERIT_VAR) {
494 if (!is_static) {
495 int oldaddmethods = AddMethods;
496 AddMethods = new_method;
497 CCode = code;
498 cplus_variable(name,iname,type);
499 AddMethods = oldaddmethods;
500 CCode = "";
501 } else {
502 cplus_static_var(name,iname,type);
503 }
504 }
505 Status = oldstatus;
506 }
507 };
508
509 // -------------------------------------------------------------------------
510 // class CPP_constant : public CPP_member
511 //
512 // Class for managing constant values
513 // -------------------------------------------------------------------------
514
515 class CPP_constant : public CPP_member {
516 public:
517 char *value;
518 DataType *type;
519 CPP_constant(char *n, char *i, DataType *t, char *v) {
520 name = copy_string(n);
521 iname = copy_string(i);
522 type = new DataType(t);
523 value = copy_string(v);
524 de = 0;
525 new_method = AddMethods;
526 next = 0;
527 line = line_number;
528 file = input_file;
529 if (Inherit_mode)
530 id = cpp_id;
531 else
532 id = type_id;
533 code = 0;
534 inherited = 0;
535 }
536
537 void emit() {
538 doc_entry = de;
539 AddMethods = new_method;
540 line_number = line;
541 input_file = file;
542 ccode = code;
543 lang->cpp_declare_const(name,iname,type,value);
544 type->check_defined();
545 }
546
547 void inherit(int mode) {
548 doc_entry = 0;
549 if (mode & INHERIT_CONST)
550 cplus_declare_const(name, iname, type, value);
551 }
552 };
553
554 // ----------------------------------------------------------------------
555 // class CPP_class
556 //
557 // Class for managing class members (internally)
558 // ----------------------------------------------------------------------
559
560 static char *inherit_base_class = 0;
561
562 class CPP_class {
563 public:
564 char *classname; // Real class name
565 char *classrename; // New name of class (if applicable)
566 char *classtype; // class type (struct, union, class)
567 int strip; // Strip off class declarator
568 int wextern; // Value of extern wrapper variable for this class
569 int have_constructor; // Status bit indicating if we've seen a constructor
570 int have_destructor; // Status bit indicating if a destructor has been seen
571 int is_abstract; // Status bit indicating if this is an abstract class
572 int generate_default; // Generate default constructors
573 int objective_c; // Set if this is an objective C class
574 int error; // Set if this class can't be generated
575 int line; // Line number
576 char **baseclass; // Base classes (if any)
577 Hash *local; // Hash table for local types
578 Hash *scope; // Local scope hash table
579 DocEntry *de; // Documentation entry of class
580 CPP_member *members; // Linked list of members
581 CPP_class *next; // Next class
582 static CPP_class *classlist; // List of all classes stored
583 Pragma *pragmas; // Class pragmas
584
585 CPP_class(char *name, char *ctype) {
586 CPP_class *c;
587 classname = copy_string(name);
588 classtype = copy_string(ctype);
589 classrename = 0;
590 baseclass = 0;
591 de = doc_entry;
592 local = new Hash; // Create hash table for storing local datatypes
593 scope = 0;
594 error = 0;
595 pragmas = 0;
596 line = line_number;
597
598 // Walk down class list and add to end
599
600 c = classlist;
601 if (c) {
602 while (c->next) {
603 c = c->next;
604 }
605 c->next = this;
606 } else {
607 classlist = this;
608 }
609 next = 0;
610 members = 0;
611 strip = 0;
612 wextern = WrapExtern;
613 have_constructor = 0;
614 have_destructor = 0;
615 is_abstract = 0;
616 generate_default = GenerateDefault;
617 objective_c = ObjCClass;
618 }
619
620 // ------------------------------------------------------------------------------
621 // Add a new C++ member to this class
622 // ------------------------------------------------------------------------------
623
624 void add_member(CPP_member *m) {
625 CPP_member *cm;
626
627 // Set base class where this was defined
628 if (inherit_base_class)
629 m->base = inherit_base_class;
630 else
631 m->base = classname;
632 if (!members) {
633 members = m;
634 return;
635 }
636 cm = members;
637 while (cm->next) {
638 cm = cm->next;
639 }
640 cm->next = m;
641 }
642 // ------------------------------------------------------------------------------
643 // Search for a member with the given name. Returns the member on success, 0 on failure
644 // ------------------------------------------------------------------------------
645
646 CPP_member *search_member(char *name) {
647 CPP_member *m;
648 char *c;
649 m = members;
650 while (m) {
651 c = m->iname ? m->iname : m->name;
652 if (strcmp(c,name) == 0) return m;
653 m = m->next;
654 }
655 return 0;
656 }
657
658 // ------------------------------------------------------------------------------
659 // Inherit. Put all the declarations associated with this class into the current
660 // ------------------------------------------------------------------------------
661
662 void inherit_decls(int mode) {
663 CPP_member *m;
664 m = members;
665 while (m) {
666 inherit_base_class = m->base;
667 cpp_id = m->id;
668 m->inherit(mode);
669 m = m->next;
670 }
671 inherit_base_class = 0;
672 }
673
674 // ------------------------------------------------------------------------------
675 // Emit all of the declarations associated with this class
676 // ------------------------------------------------------------------------------
677
678 void emit_decls() {
679 CPP_member *m = members;
680 int last_scope = name_scope(0);
681 abstract = is_abstract;
682 while (m) {
683 cpp_id = m->id;
684 name_scope(cpp_id); // Set proper naming scope
685 m->emit();
686 m = m->next;
687 }
688 name_scope(last_scope);
689 }
690
691 // ------------------------------------------------------------------------------
692 // Search for a given class in the list
693 // ------------------------------------------------------------------------------
694
695 static CPP_class *search(char *name) {
696 CPP_class *c;
697 c = classlist;
698 if (!name) return 0;
699 while (c) {
700 if (strcmp(name,c->classname) == 0) return c;
701 c = c->next;
702 }
703 return 0;
704 }
705
706 // ------------------------------------------------------------------------------
707 // Add default constructors and destructors
708 //
709 // ------------------------------------------------------------------------------
710
711 void create_default() {
712 if (!generate_default) return;
713
714 // Try to generate a constructor if not available.
715 CCode = "";
716 AddMethods = 0;
717 if ((!have_constructor) && (1)) {
718 ParmList *l;
719 l = new ParmList();
720 doc_entry = new DocDecl(classname,this->de);
721 cplus_constructor(classname,0,l);
722 };
723
724 if (!have_destructor) {
725 doc_entry = new DocDecl(classname,this->de);
726 cplus_destructor(classname,0);
727 }
728 }
729
730 // ------------------------------------------------------------------------------
731 // Dump *all* of the classes saved out to the various
732 // language modules (this does what cplus_close_class used to do)
733 // ------------------------------------------------------------------------------
734 static void create_all();
735 };
736
737 CPP_class *CPP_class::classlist = 0;
738 static CPP_class *current_class;
739
740 void CPP_class::create_all() {
741 CPP_class *c;
742 c = classlist;
743 while (c) {
744 if (!c->error) {
745 current_class = c;
746 localtypes = c->local;
747 if ((!c->wextern) && (c->classtype)) {
748 ObjCClass = c->objective_c;
749 doc_entry = c->de;
750 lang->cpp_open_class(c->classname,c->classrename,c->classtype,c->strip);
751 lang->cpp_pragma(c->pragmas);
752 c->create_default();
753 if (c->baseclass)
754 cplus_inherit_decl(c->baseclass);
755 c->emit_decls();
756 doc_entry = c->de;
757 lang->cpp_close_class();
758 }
759 }
760 c = c->next;
761 }
762 }
763
764 // -----------------------------------------------------------------------------
765 // char *cplus_base_class(char *name)
766 //
767 // Given a member name, return the base class that it belongs to.
768 // -----------------------------------------------------------------------------
769
770 char *cplus_base_class(char *name) {
771 CPP_member *m = current_class->search_member(name);
772 if (m) {
773 return m->base;
774 }
775 return 0;
776 }
777
778 // -----------------------------------------------------------------------------
779 // void cplus_open_class(char *name, char *rname, char *ctype)
780 //
781 // Opens up a new C++ class. If rname is given, we'll be renaming the
782 // class. This also sets up some basic type equivalence for the
783 // type checker.
784 //
785 // Inputs :
786 // name = Name of the class
787 // rname = New name of the class (using %name() directive)
788 // ctype = Class type ("class","struct", or "union")
789 //
790 // Output : None
791 //
792 // Side Effects :
793 // Creates a new class obect internally.
794 // Added type-mappings to the SWIG type-checker module.
795 // Sets a number of internal state variables for later use.
796 //
797 // -----------------------------------------------------------------------------
798
799 void cplus_open_class(char *name, char *rname, char *ctype) {
800
801 extern void typeeq_derived(char *, char *, char *cast=0);
802 char temp[256];
803 CPP_class *c;
804
805 // Add some symbol table management here
806
807 // Search for a previous class definition
808
809 c = CPP_class::search(name);
810 if (c) {
811 if (c->classtype) {
812 // Hmmm. We already seem to have defined this class so we'll
813 // create a new class object for whatever reason
814 current_class = new CPP_class(name, ctype);
815 } else {
816 // Looks like a reference was made to this class earlier
817 // somehow, but no other information is known. We'll
818 // make it our current class and fix it up a bit
819 current_class = c;
820 c->classtype = copy_string(ctype);
821 }
822 } else {
823 // Create a new class
824 current_class = new CPP_class(name, ctype);
825 current_class->de = doc_entry;
826 }
827
828 // Set localtypes hash to our current class
829
830 localtypes = current_class->local;
831
832 // If renaming the class, set the new name
833
834 if (rname) {
835 current_class->classrename = copy_string(rname);
836 }
837
838 // Make a typedef for both long and short versions of this datatype
839
840 if (name) {
841 if (strlen(name)) {
842 if (strlen(ctype) > 0 && strcmp(ctype, "class") != 0) {
843 sprintf(temp,"%s %s", ctype, name);
844 typeeq_derived(temp,name); // Map "struct foo" to "foo"
845 typeeq_derived(name,temp); // Map "foo" to "struct foo"
846 }
847 }
848 }
849
850 AddMethods = 0; // Reset add methods flag
851
852 }
853
854 // -----------------------------------------------------------------------------
855 // DocEntry *cplus_set_class(char *name)
856 //
857 // This function sets the current class to a given name. If the class
858 // doesn't exist, this function will create one. If it already exists,
859 // we'll just use that.
860 //
861 // This function is used primarily to add or manipulate an already
862 // existing class, but in a different location. For example :
863 //
864 // %include "class.h" // Grab some classes
865 // ...
866 // %addmethods MyClass { // Add some members for shadow classes
867 // ... members ...
868 // }
869 //
870 // Sounds weird, but returns the documentation entry to class if it exists.
871 // The parser needs this so we can generate documentation correctly.
872 //
873 // Inputs : name = Name of the class
874 //
875 // Output : Documentation entry of class or NULL if it doesn't exist.
876 // The parser needs the documentation entry to properly associate
877 // new members.
878 //
879 // Side Effects :
880 // Changes the current class object. Resets a number of internal
881 // state variables. Should not be called inside of a open class
882 // declaration.
883 // -----------------------------------------------------------------------------
884
885 DocEntry *cplus_set_class(char *name) {
886
887 CPP_class *c;
888
889 // Look for a previous class definition
890
891 c = CPP_class::search(name);
892 if (c) {
893 current_class = c;
894 localtypes = c->local;
895 return c->de;
896 } else {
897 fprintf(stderr,"%s:%d: Warning class %s undefined.\n",input_file,line_number,name);
898 current_class = new CPP_class(name,0);
899 localtypes = current_class->local;
900 return 0;
901 }
902 };
903
904 // This function closes a class open with cplus_set_class()
905
906 void cplus_unset_class() {
907 current_class = 0;
908 }
909
910 // -----------------------------------------------------------------------------
911 // void cplus_class_close(char *name)
912 //
913 // Close a C++ class definition. Up to this point, we've only been collecting
914 // member definitions. This function merely closes the class object and
915 // stores it in a list. All classes are dumped after processing has completed.
916 //
917 // If name is non-null, it means that the name of the class has actually been
918 // set after all of the definitions. For example :
919 //
920 // typedef struct {
921 // double x,y,z
922 // } Vector;
923 //
924 // If this is the case, we'll use that as our classname and datatype.
925 // Otherwise, we'll just go with the classname and classtype set earlier.
926 //
927 // Inputs : name = optional "new name" for the class.
928 //
929 // Output : None
930 //
931 // Side Effects : Resets internal variables. Saves class in internal list.
932 // Registers the class with the language module, but doesn't
933 // emit any code.
934 // -----------------------------------------------------------------------------
935
936 void cplus_class_close(char *name) {
937
938 if (name) {
939 // The name of our class suddenly changed by typedef. Fix things up
940 current_class->classname = copy_string(name);
941
942 // This flag indicates that the class needs to have it's type stripped off
943 current_class->strip = 1;
944 }
945
946 // If we're in C++ or Objective-C mode. We're going to drop the class specifier
947
948 if ((CPlusPlus) || (ObjCClass)) {
949 current_class->strip = 1;
950 }
951
952 // Register our class with the target language module, but otherwise
953 // don't do anything yet.
954
955 char *iname;
956 if (current_class->classrename) iname = current_class->classrename;
957 else iname = current_class->classname;
958
959 lang->cpp_class_decl(current_class->classname, iname, current_class->classtype);
960
961 // Clear current class variable and reset
962 current_class = 0;
963 localtypes = 0;
964
965 }
966
967 // -----------------------------------------------------------------------------
968 // void cplus_abort(void)
969 //
970 // Voids the current class--some kind of unrecoverable parsing error occurred.
971 // -----------------------------------------------------------------------------
972
973 void cplus_abort(void) {
974 current_class->error = 1;
975 current_class = 0;
976 localtypes = 0;
977 }
978
979 // -----------------------------------------------------------------------------
980 // void cplus_cleanup(void)
981 //
982 // This function is called after all parsing has been completed. It dumps all
983 // of the stored classes out to the language module.
984 //
985 // Inputs : None
986 //
987 // Output : None
988 //
989 // Side Effects : Emits all C++ wrapper code.
990 // -----------------------------------------------------------------------------
991
992 void cplus_cleanup(void) {
993
994 // Dump all classes created at once (yikes!)
995
996 CPP_class::create_all();
997 lang->cpp_cleanup();
998 }
999
1000 // -----------------------------------------------------------------------------
1001 // void cplus_inherit(int count, char **baseclass)
1002 //
1003 // Inherit from a baseclass. This function only really registers
1004 // the inheritance, but doesn't do anything with it yet.
1005 //
1006 // Inputs : baseclass = A NULL terminated array of strings with the names
1007 // of baseclasses. For multiple inheritance, there
1008 // will be multiple entries in this list.
1009 //
1010 // Output : None
1011 //
1012 // Side Effects : Sets the baseclass variable of the current class.
1013 // -----------------------------------------------------------------------------
1014
1015 void cplus_inherit(int count, char **baseclass) {
1016 int i;
1017
1018 // printf("Inheriting : count = %d, baseclass = %x\n",count,baseclass);
1019 // If there are baseclasses, make copy of them
1020 if (count) {
1021 current_class->baseclass = (char **) new char*[count+1];
1022 for (i = 0; i < count; i++)
1023 current_class->baseclass[i] = copy_string(baseclass[i]);
1024 current_class->baseclass[i] = 0;
1025 } else {
1026 baseclass = 0;
1027 }
1028 }
1029
1030 // -----------------------------------------------------------------------------
1031 // cplus_generate_types(char **baseclass)
1032 //
1033 // Generates the type-mappings between the current class and any associated
1034 // base classes. This is done by performing a depth first search of the
1035 // class hierarchy. Functions for performing correct type-casting are
1036 // generated for each base-derived class pair.
1037 //
1038 // Inputs : baseclass = NULL terminated list of base classes
1039 //
1040 // Output : None
1041 //
1042 // Side Effects : Emits pointer conversion functions. Registers type-mappings
1043 // with the type checking module.
1044 //
1045 // -----------------------------------------------------------------------------
1046
1047 static Hash convert; // Hash table of conversion functions
1048
1049 void cplus_generate_types(char **baseclass) {
1050 CPP_class *bc;
1051 int i;
1052 String cfunc, temp1, temp2, temp3;
1053 extern void typeeq_derived(char *, char *, char *);
1054
1055 if (!baseclass) {
1056 return;
1057 }
1058
1059 // Generate type-conversion functions and type-equivalence
1060
1061 i = 0;
1062 while(baseclass[i]) {
1063 cfunc = "";
1064
1065 bc = CPP_class::search(baseclass[i]);
1066 if (bc) {
1067 // Generate a conversion function (but only for C++)
1068
1069 if (!current_class->objective_c) {
1070 temp3 = "";
1071 temp3 << "Swig" << current_class->classname << "To" << bc->classname;
1072
1073 if (convert.add(temp3,(void *) 1) != -1) {
1074
1075 // Write a function for casting derived type to parent class
1076
1077 cfunc << "static void *Swig" << current_class->classname << "To" << bc->classname
1078 << "(void *ptr) {\n"
1079 << tab4 << current_class->classname << " *src;\n"
1080 << tab4 << bc->classname << " *dest;\n"
1081 << tab4 << "src = (" << current_class->classname << " *) ptr;\n"
1082 << tab4 << "dest = (" << bc->classname << " *) src;\n"
1083 // << tab4 << "printf(\"casting...\\n\");\n"
1084 << tab4 << "return (void *) dest;\n"
1085 << "}\n";
1086
1087 fprintf(f_wrappers,"%s\n",cfunc.get());
1088 }
1089 } else {
1090 temp3 = "0";
1091 }
1092
1093 // Make a type-equivalence allowing derived classes to be used in functions of the
1094
1095 if (strlen(current_class->classtype) > 0 &&
1096 strcmp(current_class->classtype, "class") != 0) {
1097 temp1 = "";
1098 temp1 << current_class->classtype << " " << current_class->classname;
1099 temp2 = "";
1100 temp2 << bc->classtype << " " << bc->classname;
1101 // Add various equivalences to the pointer table
1102
1103 typeeq_derived(bc->classname, current_class->classname,temp3.get());
1104 typeeq_derived(temp2.get(), current_class->classname,temp3.get());
1105 typeeq_derived(temp2.get(), temp1.get(),temp3.get());
1106 typeeq_derived(bc->classname, temp1.get(),temp3.get());
1107 } else {
1108 typeeq_derived(bc->classname, current_class->classname,temp3.get());
1109 }
1110 // Now traverse the hierarchy some more
1111 cplus_generate_types(bc->baseclass);
1112 }
1113 i++;
1114 }
1115 }
1116
1117 // -----------------------------------------------------------------------------
1118 // void cplus_inherit_decl(char **baseclass)
1119 //
1120 // This function is called internally to handle inheritance between classes.
1121 // Basically, we're going to generate type-checking information and call
1122 // out to the target language to handle the inheritance.
1123 //
1124 // This function is only called when emitting classes to the language modules
1125 // (after all parsing has been complete).
1126 //
1127 // Inputs : baseclass = NULL terminated list of base-class names.
1128 //
1129 // Output : None
1130 //
1131 // Side Effects : Generates type-mappings. Calls the language-specific
1132 // inheritance function.
1133 // -----------------------------------------------------------------------------
1134
1135 void cplus_inherit_decl(char **baseclass) {
1136
1137 // If not base-classes, bail out
1138
1139 if (!baseclass) return;
1140
1141 Inherit_mode = 1;
1142 lang->cpp_inherit(baseclass); // Pass inheritance onto the various languages
1143 Inherit_mode = 0;
1144
1145 // Create type-information for class hierarchy
1146
1147 cplus_generate_types(baseclass);
1148 }
1149 // -----------------------------------------------------------------------------
1150 // void cplus_inherit_members(char *baseclass, int mode)
1151 //
1152 // Inherits members from a class. This is called by specific language modules
1153 // to bring in members from base classes. It may or may not be called.
1154 //
1155 // This function is called with a *single* base-class, not multiple classes
1156 // like other functions. To do multiple inheritance, simply call this
1157 // with each of the associated base classes.
1158 //
1159 // Inputs :
1160 // baseclass = Name of baseclass
1161 // mode = Inheritance handling flags
1162 // INHERIT_FUNC - Import functions in base class
1163 // INHERIT_VAR - Import variables in base class
1164 // INHERIT_CONST - Inherit constants
1165 // INHERIT_ALL - Inherit everything (grossly inefficient)
1166 //
1167 // Output : None
1168 //
1169 // Side Effects : Imports methods from base-classes into derived classes.
1170 //
1171 // -----------------------------------------------------------------------------
1172
1173 void cplus_inherit_members(char *baseclass, int mode) {
1174 CPP_class *bc;
1175
1176 bc = CPP_class::search(baseclass);
1177 if (bc) {
1178 bc->inherit_decls(mode);
1179 } else {
1180 fprintf(stderr,"%s:%d: Warning. Base class %s undefined (ignored).\n", input_file, current_class->line, baseclass);
1181 }
1182 }
1183
1184 // -----------------------------------------------------------------------------
1185 // void cplus_member_func(char *name, char *iname, DataType *type, ParmList *, is_virtual)
1186 //
1187 // Parser entry point to creating a C++ member function. This function primarily
1188 // just records the function and does a few symbol table checks.
1189 //
1190 // Inputs :
1191 // name = Real name of the member function
1192 // iname = Renamed version (may be NULL)
1193 // type = Return datatype
1194 // l = Parameter list
1195 // is_virtual = Set if this is a pure virtual function (ignored)
1196 //
1197 // Output : None
1198 //
1199 // Side Effects :
1200 // Adds member function to current class.
1201 // -----------------------------------------------------------------------------
1202
1203 void cplus_member_func(char *name, char *iname, DataType *type, ParmList *l,
1204 int is_virtual) {
1205
1206 CPP_function *f;
1207 char *temp_iname;
1208
1209 // First, figure out if we're renaming this function or not
1210
1211 if (!iname)
1212 temp_iname = name;
1213 else
1214 temp_iname = iname;
1215
1216 // If we're in inherit mode, we need to check for duplicates.
1217 // Issue a warning.
1218
1219 if (Inherit_mode) {
1220 if (current_class->search_member(temp_iname)) {
1221 return;
1222 }
1223 }
1224
1225 // Add it to our C++ class list
1226
1227 f = new CPP_function(name,temp_iname,type,l,0,is_virtual);
1228 f->de = doc_entry;
1229 current_class->add_member(f);
1230
1231 // If this is a pure virtual function, the class is abstract
1232
1233 if (is_virtual)
1234 current_class->is_abstract = 1;
1235
1236 }
1237
1238 // -----------------------------------------------------------------------------
1239 // void cplus_constructor(char *name, char *iname, ParmList *l)
1240 //
1241 // Parser entry point for creating a constructor.
1242 //
1243 // Inputs :
1244 // name = Real name of the constructor (usually the same as the class)
1245 // iname = Renamed version (may be NULL)
1246 // l = Parameter list
1247 //
1248 // Output : None
1249 //
1250 // Side Effects :
1251 // Adds a constructor to the current class.
1252 // -----------------------------------------------------------------------------
1253
1254 void cplus_constructor(char *name, char *iname, ParmList *l) {
1255
1256 CPP_constructor *c;
1257
1258 // May want to check the naming scheme here
1259
1260 c = new CPP_constructor(name,iname,l);
1261 c->de = doc_entry;
1262 current_class->add_member(c);
1263 current_class->have_constructor = 1;
1264
1265 }
1266
1267 // -----------------------------------------------------------------------------
1268 // void cplus_destructor(char *name, char *iname)
1269 //
1270 // Parser entry point for adding a destructor.
1271 //
1272 // Inputs :
1273 // name = Real name of the destructor (usually same as class name)
1274 // iname = Renamed version (may be NULL)
1275 //
1276 // Output : None
1277 //
1278 // Side Effects :
1279 // Adds a destructor to the current class
1280 //
1281 // -----------------------------------------------------------------------------
1282
1283 void cplus_destructor(char *name, char *iname) {
1284
1285 CPP_destructor *d;
1286
1287 d = new CPP_destructor(name,iname);
1288 d->de = doc_entry;
1289 current_class->add_member(d);
1290 current_class->have_destructor = 1;
1291 }
1292
1293 // -----------------------------------------------------------------------------
1294 // void cplus_variable(char *name, char *iname, DataType *t)
1295 //
1296 // Parser entry point for creating a new member variable.
1297 //
1298 // Inputs :
1299 // name = name of the variable
1300 // iname = Renamed version (may be NULL)
1301 // t = Datatype
1302 //
1303 // Output : None
1304 //
1305 // Side Effects :
1306 // Adds a member variable to the current class
1307 // -----------------------------------------------------------------------------
1308
1309 void cplus_variable(char *name, char *iname, DataType *t) {
1310
1311 CPP_variable *v;
1312 char *temp_iname;
1313
1314 // If we're in inherit mode, we need to check for duplicates.
1315
1316 if (iname)
1317 temp_iname = iname;
1318 else
1319 temp_iname = name;
1320
1321 if (Inherit_mode) {
1322 if (current_class->search_member(temp_iname)) {
1323 return;
1324 }
1325 }
1326
1327 v = new CPP_variable(name,iname,t,0);
1328 v->de = doc_entry;
1329 current_class->add_member(v);
1330 }
1331
1332 // -----------------------------------------------------------------------------
1333 // void cplus_static_func(char *name, char *iname, DataType *type, ParmList *l)
1334 //
1335 // Parser entry point for creating a new static member function.
1336 //
1337 // Inputs :
1338 // name = Real name of the function
1339 // iname = Renamed version (may be NULL)
1340 // type = Return datatype
1341 // l = Parameter list
1342 //
1343 // Output : None
1344 //
1345 // Side Effects :
1346 // Adds a static function to the current class.
1347 //
1348 // -----------------------------------------------------------------------------
1349
1350 void cplus_static_func(char *name, char *iname, DataType *type, ParmList *l) {
1351
1352 char *temp_iname;
1353
1354 // If we're in inherit mode, we need to check for duplicates.
1355
1356 if (iname) temp_iname = iname;
1357 else temp_iname = name;
1358
1359 if (Inherit_mode) {
1360 if (current_class->search_member(iname)) {
1361 // Have a duplication
1362 return;
1363 }
1364 }
1365
1366 CPP_function *f = new CPP_function(name, temp_iname, type, l, 1);
1367 f->de = doc_entry;
1368 current_class->add_member(f);
1369 }
1370
1371 // -----------------------------------------------------------------------------
1372 // void cplus_declare_const(char *name, char *iname, DataType *type, char *value)
1373 //
1374 // Parser entry point for creating a C++ constant (usually contained in an
1375 // enum).
1376 //
1377 // Inputs :
1378 // name = Real name of the constant
1379 // iname = Renamed constant (may be NULL)
1380 // type = Datatype of the constant
1381 // value = String representation of the value
1382 //
1383 // Output : None
1384 //
1385 // Side Effects :
1386 // Adds a constant to the current class.
1387 // -----------------------------------------------------------------------------
1388
1389 void cplus_declare_const(char *name, char *iname, DataType *type, char *value) {
1390
1391 char *temp_iname;
1392
1393 if (iname) temp_iname = iname;
1394 else temp_iname = name;
1395
1396 // If we're in inherit mode, we need to check for duplicates.
1397 // Possibly issue a warning or perhaps a remapping
1398
1399 if (Inherit_mode) {
1400 if (current_class->search_member(temp_iname)) {
1401 return;
1402 }
1403 }
1404
1405 CPP_constant *c = new CPP_constant(name, temp_iname, type, value);
1406 c->de = doc_entry;
1407 current_class->add_member(c);
1408
1409 // Update this symbol in the symbol table
1410 update_symbol(name, type, value);
1411
1412 // Add this symbol to local scope of a class
1413 add_local_type(name, current_class->classname);
1414 }
1415
1416 // -----------------------------------------------------------------------------
1417 // void cplus_static_var(char *name, char *iname, DataType *type)
1418 //
1419 // Parser entry point for adding a static variable
1420 //
1421 // Inputs :
1422 // name = Name of the member
1423 // iname = Renamed version (may be NULL)
1424 // type = Datatype
1425 //
1426 // Output : None
1427 //
1428 // Side Effects :
1429 // Adds a static variable to the current class.
1430 // -----------------------------------------------------------------------------
1431
1432 void cplus_static_var(char *name, char *iname, DataType *type) {
1433
1434 char *temp_iname;
1435
1436 if (iname) temp_iname = iname;
1437 else temp_iname = name;
1438
1439 // If we're in inherit mode, we need to check for duplicates.
1440 // Possibly issue a warning or perhaps a remapping
1441
1442 if (Inherit_mode) {
1443 if (current_class->search_member(temp_iname)) {
1444 return;
1445 }
1446 }
1447
1448 CPP_variable *v = new CPP_variable(name, temp_iname, type, 1);
1449 v->de = doc_entry;
1450 current_class->add_member(v);
1451 }
1452
1453 // -----------------------------------------------------------------------------
1454 // cplus_add_pragma(char *lang, char *name, char *value)
1455 //
1456 // Add a pragma to a class
1457 // -----------------------------------------------------------------------------
1458
1459 void cplus_add_pragma(char *lang, char *name, char *value)
1460 {
1461 Pragma *pp;
1462 Pragma *p = new Pragma;
1463 p->filename = input_file;
1464 p->lineno = line_number;
1465 p->lang = lang;
1466 p->name = name;
1467 p->value = value;
1468
1469 if (!current_class->pragmas) {
1470 current_class->pragmas = p;
1471 return;
1472 }
1473 pp = current_class->pragmas;
1474 while (pp->next) {
1475 pp = pp->next;
1476 }
1477 pp->next = p;
1478 }
1479
1480 // ------------------------------------------------------------------------------
1481 // C++/Objective-C code generation functions
1482 //
1483 // The following functions are responsible for generating the wrapper functions
1484 // for C++ and Objective-C methods and variables. These functions are usually
1485 // called by specific language modules, but individual language modules can
1486 // choose to do something else.
1487 //
1488 // The C++ module sets a number of internal state variables before emitting various
1489 // pieces of code. These variables are often checked implicitly by these
1490 // procedures even though nothing is passed on the command line.
1491 //
1492 // The code generator tries to be somewhat intelligent about what its doing.
1493 // The member_hash Hash table keeps track of wrapped members and is used for
1494 // sharing code between base and derived classes.
1495 // -----------------------------------------------------------------------------
1496
1497 static Hash member_hash; // Hash wrapping member function wrappers to scripting wrappers
1498
1499 // -----------------------------------------------------------------------------
1500 // void cplus_emit_member_func(char *classname, char *classtype, char *classrename,
1501 // char *mname, char *mrename, DataType *type,
1502 // ParmList *l, int mode)
1503 //
1504 // This is a generic function to produce a C wrapper around a C++ member function.
1505 // This function does the following :
1506 //
1507 // 1. Create a C wrapper function
1508 // 2. Wrap the C wrapper function like a normal C function in SWIG
1509 // 3. Add the function to the scripting language
1510 // 4. Fill in the documentation entry
1511 //
1512 // Specific languages can choose to provide a different mechanism, but this
1513 // function is used to provide a low-level C++ interface.
1514 //
1515 // The mode variable determines whether to create a new function or only to
1516 // add it to the interpreter. This is used to support the %addmethods directive
1517 //
1518 // mode = 0 : Create a wrapper and add it (the normal mode)
1519 // mode = 1 : Assume wrapper was already made and add it to the
1520 // interpreter (%addmethods mode)
1521 //
1522 // Wrapper functions are usually created as follows :
1523 //
1524 // class Foo {
1525 // int bar(args)
1526 // }
1527 //
1528 // becomes ....
1529 // Foo_bar(Foo *obj, args) {
1530 // obj->bar(args);
1531 // }
1532 //
1533 // if %addmethods mode is set AND there is supporting C code detected, make
1534 // a function from it. The object is always called 'obj'.
1535 //
1536 // Then we wrap Foo_bar(). The name "Foo_bar" is actually contained in the parameter
1537 // cname. This is so language modules can provide their own names (possibly for
1538 // function overloading).
1539 //
1540 // This function makes no internal checks of the SWIG symbol table. This is
1541 // up to the caller.
1542 //
1543 // Objective-C support (added 5/24/97) :
1544 //
1545 // If the class member function is part of an objective-C interface, everything
1546 // works the same except that we change the calling mechanism to issue an
1547 // Objective-C message.
1548 //
1549 // Optimizations (added 12/31/97) :
1550 //
1551 // For automatically generated wrapper functions. We now generate macros such
1552 // as
1553 // #define Foo_bar(a,b,c) (a->bar(b,c))
1554 //
1555 // This should make the wrappers a little faster as well as reducing the amount
1556 // of wrapper code.
1557 //
1558 // Inputs :
1559 // classname = Name of C++ class
1560 // classtype = Type of class (struct, union, class)
1561 // classrename = Renamed class (if any)
1562 // mname = Member name
1563 // mrename = Renamed member
1564 // type = Return type of the function
1565 // l = Parameter list
1566 // mode = addmethods mode
1567 //
1568 // Output : None
1569 //
1570 // Side Effects :
1571 // Creates C accessor function in the wrapper file.
1572 // Calls the language module to create a wrapper function.
1573 // -----------------------------------------------------------------------------
1574
1575 void cplus_emit_member_func(char *classname, char *classtype, char *classrename,
1576 char *mname, char *mrename, DataType *type, ParmList *l,
1577 int mode) {
1578 Parm *p;
1579 ParmList *newparms;
1580 int i;
1581 String wrap;
1582 String cname,iname;
1583 String key;
1584 String argname;
1585 char *prefix;
1586 char *prev_wrap = 0;
1587 char *temp_mname;
1588
1589 cname = "";
1590 iname = "";
1591 key = "";
1592
1593 // First generate a proper name for the member function
1594
1595 // Get the base class of this member
1596 if (!mrename) temp_mname = mname;
1597 else temp_mname = mrename;
1598
1599 char *bc = cplus_base_class(temp_mname);
1600 if (!bc) bc = classname;
1601 if (strlen(bc) == 0) bc = classname;
1602
1603 // Generate the name of the C wrapper function (is always the same, regardless
1604 // of renaming).
1605
1606 cname << name_member(mname,bc);
1607
1608 // Generate the scripting name of this function
1609 if (classrename)
1610 prefix = classrename;
1611 else
1612 prefix = classname;
1613
1614 if (mrename)
1615 iname << name_member(mrename,prefix);
1616 else
1617 iname << name_member(mname,prefix);
1618
1619 // Now check to see if we have already wrapped a function like this.
1620 // If so, we'll just use the existing wrapper.
1621
1622 key << cname << "+";
1623 l->print_types(key);
1624 // printf("key = %s\n", (char *) key);
1625 char *temp = copy_string(iname);
1626 if ((member_hash.add(key,temp)) == -1) {
1627 delete [] temp;
1628 prev_wrap = (char *) member_hash.lookup(key);
1629 }
1630
1631 // Only generate code if an already existing wrapper doesn't exist
1632
1633 if (!prev_wrap) {
1634
1635 // If mode = 0: Then we go ahead and create a wrapper macro
1636
1637 if (!mode) {
1638 cname = "";
1639 cname << iname;
1640 wrap << "#define " << cname << "(_swigobj";
1641
1642 // Walk down the parameter list and Spit out arguments
1643
1644 i = 0;
1645 p = l->get_first();
1646 while (p != 0) {
1647 if ((p->t->type != T_VOID) || (p->t->is_pointer)) {
1648 wrap << ",_swigarg" << i;
1649 i++;
1650 }
1651 p = l->get_next();
1652 }
1653
1654 wrap << ") (";
1655
1656 if (!ObjCClass) {
1657 wrap << "_swigobj->" << mname << "("; // C++ invocation
1658 } else {
1659 wrap << "[ _swigobj " << mname; // Objective C invocation
1660 }
1661 i = 0;
1662 p = l->get_first();
1663 while(p != 0) {
1664 if (ObjCClass) wrap << " " << p->objc_separator;
1665 if ((p->t->type != T_VOID) || (p->t->is_pointer)) {
1666 wrap << "_swigarg" << i;
1667 i++;
1668 }
1669 p = l->get_next();
1670 if ((p != 0) && (!ObjCClass))
1671 wrap << ",";
1672 }
1673 if (!ObjCClass)
1674 wrap << "))\n";
1675 else
1676 wrap << "])\n";
1677
1678 // Emit it
1679 fprintf(f_wrappers,"%s",wrap.get());
1680 } else {
1681 if (ccode) {
1682 wrap << "static ";
1683 if (type->is_reference) {
1684 type->is_pointer--;
1685 }
1686 wrap << type->print_full();
1687 if (type->is_reference) {
1688 wrap << "&";
1689 type->is_pointer++;
1690 }
1691 wrap << " " << cname << "(" << classtype << classname << " *self";
1692
1693 // Walk down the parameter list and Spit out arguments
1694
1695 p = l->get_first();
1696 while (p != 0) {
1697 if ((p->t->type != T_VOID) || (p->t->is_pointer)) {
1698 wrap << ",";
1699 if ((p->call_type & CALL_REFERENCE) || (p->t->is_reference)) {
1700 p->t->is_pointer--;
1701 }
1702 wrap << p->t->print_full();
1703 if ((p->call_type & CALL_REFERENCE) || (p->t->is_reference)) {
1704 p->t->is_pointer++;
1705 if (p->t->is_reference)
1706 wrap << "&";
1707 }
1708 wrap << " " << p->name;
1709 }
1710 p = l->get_next();
1711 }
1712
1713 wrap << ") " << ccode;
1714 fprintf(f_wrappers,"%s\n",wrap.get());
1715 }
1716 }
1717
1718 // Now add a parameter to the beginning of the function and call
1719 // a language specific function to add it.
1720
1721 newparms = new ParmList(l);
1722 p = new Parm(0,0);
1723 p->t = new DataType;
1724 p->t->type = T_USER;
1725 p->t->is_pointer = 1;
1726 p->t->id = cpp_id;
1727 p->call_type = 0;
1728
1729 sprintf(p->t->name,"%s%s", classtype,classname);
1730 p->name = "self";
1731 newparms->insert(p,0); // Attach parameter to beginning of list
1732
1733 // Now wrap the thing. The name of the function is iname
1734
1735 lang->create_function(cname, iname, type, newparms);
1736 delete newparms;
1737 } else {
1738 // Already wrapped this function. Just patch it up
1739 lang->create_command(prev_wrap, iname);
1740 }
1741 }
1742
1743
1744 // -----------------------------------------------------------------------------
1745 // void cplus_emit_static_func(char *classname, char *classtype, char *classrename,
1746 // char *mname, char *mrename, DataType *type,
1747 // ParmList *l, int mode)
1748 //
1749 // This is a generic function to produce a wrapper for a C++ static member function
1750 // or an Objective-C class method.
1751 //
1752 // Specific languages can choose to provide a different mechanism, but this
1753 // function is used to provide a low-level C++ interface.
1754 //
1755 // The mode variable determines whether to create a new function or only to
1756 // add it to the interpreter. This is used to support the %addmethods directive
1757 //
1758 // mode = 0 : Create a wrapper and add it (the normal mode)
1759 // mode = 1 : Assume wrapper was already made and add it to the
1760 // interpreter (%addmethods mode)
1761 //
1762 // Wrapper functions are usually created as follows :
1763 //
1764 // class Foo {
1765 // static int bar(args)
1766 // }
1767 //
1768 // becomes a command called Foo_bar()
1769 //
1770 // if %addmethods mode is set AND there is supporting C code detected, make
1771 // a function from it.
1772 //
1773 // Then we wrap Foo_bar(). The name "Foo_bar" is actually contained in the parameter
1774 // cname. This is so language modules can provide their own names (possibly for
1775 // function overloading).
1776 //
1777 // This function makes no internal checks of the SWIG symbol table. This is
1778 // up to the caller.
1779 //
1780 // Inputs :
1781 // classname = Name of C++ class
1782 // classtype = Type of class (struct, union, class)
1783 // classrename = Renamed version of class (optional)
1784 // mname = Member name
1785 // mrename = Renamed member (optional)
1786 // type = Return type of the function
1787 // l = Parameter list
1788 // mode = addmethods mode
1789 //
1790 // Output : None
1791 //
1792 // -----------------------------------------------------------------------------
1793
1794 void cplus_emit_static_func(char *classname, char *, char *classrename,
1795 char *mname, char *mrename, DataType *type, ParmList *l,
1796 int mode) {
1797 Parm *p;
1798 String wrap;
1799 String cname, iname, key;
1800 int i;
1801 char *prefix;
1802 char *prev_wrap = 0;
1803 char *temp_mname;
1804
1805 cname = "";
1806 iname = "";
1807 key = "";
1808
1809 // Generate a function name for the member function
1810
1811 if (!mrename) temp_mname = mname;
1812 else temp_mname = mrename;
1813 char *bc = cplus_base_class(temp_mname);
1814 if (!bc) bc = classname;
1815 if (strlen(bc) == 0) bc = classname;
1816
1817 // Generate the name of the C wrapper function
1818 if ((!mode) && (!ObjCClass)) {
1819 cname << bc << "::" << mname;
1820 } else {
1821 cname << name_member(mname,bc);
1822 }
1823
1824 // Generate the scripting name of this function
1825 if (classrename)
1826 prefix = classrename;
1827 else
1828 prefix = classname;
1829
1830 if (mrename)
1831 iname << name_member(mrename,prefix);
1832 else
1833 iname << name_member(mname,prefix);
1834
1835 // Perform a hash table lookup to see if we've wrapped anything like this before
1836
1837 key << cname << "+";
1838 l->print_types(key);
1839 char *temp = copy_string(iname);
1840 if ((member_hash.add(key,temp)) == -1) {
1841 delete [] temp;
1842 prev_wrap = (char *) member_hash.lookup(key);
1843 }
1844
1845 if (!prev_wrap) {
1846 if (!((mode) || (ObjCClass))) {
1847 // Not an added method and not objective C, just wrap it
1848 lang->create_function(cname,iname, type, l);
1849 } else {
1850 // This is either an added method or an objective C class function
1851 //
1852 // If there is attached code, use it.
1853 // Otherwise, assume the function has been written already and
1854 // wrap it.
1855
1856 wrap << "static " << type->print_full() << " " << cname << "(";
1857
1858 // Walk down the parameter list and Spit out arguments
1859 p = l->get_first();
1860 while (p != 0) {
1861 if ((p->t->type != T_VOID) || (p->t->is_pointer)) {
1862 if (p->t->is_reference) {
1863 p->t->is_pointer--;
1864 }
1865 wrap << p->t->print_full();
1866 if (p->t->is_reference) {
1867 p->t->is_pointer++;
1868 wrap << "&";
1869 }
1870 wrap << " " << p->name;
1871 }
1872 p = l->get_next();
1873 if (p) wrap << ",";
1874 }
1875 wrap << ") ";
1876 if ((mode) && (ccode)) {
1877 wrap << ccode;
1878 } else if (ObjCClass) {
1879 // This is an objective-C method
1880
1881 wrap << "{\n" << tab4;
1882
1883 // Emit the function call.
1884
1885 if ((type->type != T_VOID) || (type->is_pointer)) {
1886 // Declare the return value
1887
1888 if (type->is_reference) {
1889 type->is_pointer--;
1890 wrap << tab4 << type->print_full() << "& _result = ";
1891 type->is_pointer++;
1892 } else {
1893 wrap << tab4 << type->print_type() << " _result = " << type->print_cast();
1894 }
1895 } else {
1896 wrap << tab4;
1897 }
1898 wrap << "[ " << classname << " " << mname; // Objective C invocation
1899 i = 0;
1900 p = l->get_first();
1901 while(p != 0) {
1902 wrap << " " << p->objc_separator;
1903 if ((p->t->type != T_VOID) || (p->t->is_pointer)) {
1904 if (p->t->is_reference) {
1905 wrap << "*";
1906 }
1907 wrap << p->name;
1908 i++;
1909 }
1910 p = l->get_next();
1911 }
1912 wrap << "];\n";
1913
1914 if ((type->type != T_VOID) || (type->is_pointer)) {
1915 if (type->is_reference) {
1916 wrap << tab4 << "return " << type->print_cast() << " &_result;\n";
1917 } else {
1918 wrap << tab4 << "return _result;\n";
1919 }
1920 }
1921 wrap << "}\n";
1922 }
1923 if (ObjCClass || (mode && ccode))
1924 fprintf(f_wrappers,"%s\n",wrap.get());
1925 lang->create_function(cname,iname,type,l);
1926 }
1927 } else {
1928 // Already wrapped this function. Just hook up to it.
1929 lang->create_command(prev_wrap, iname);
1930 }
1931 }
1932
1933 // -----------------------------------------------------------------------------
1934 // void cplus_emit_destructor(char *classname, char *classtype, char *classrename,
1935 // char *mname, char *mrename, int mode)
1936 //
1937 // Emit a C wrapper around a C++ destructor.
1938 //
1939 // Usually this function is used to do the following :
1940 // class Foo {
1941 // ...
1942 // ~Foo();
1943 // }
1944 //
1945 // becomes ....
1946 // void delete_Foo(Foo *f) {
1947 // delete f;
1948 // }
1949 //
1950 // Then we wrap delete_Foo().
1951 //
1952 // Inputs :
1953 // classname = Name of the C++ class
1954 // classtype = Type of class (struct,class,union)
1955 // classrename = Renamed class (optional)
1956 // mname = Name of the destructor
1957 // mrename = Name of the function in the interpreter
1958 // mode = addmethods mode (0 or 1)
1959 //
1960 // Output : None
1961 //
1962 // Side Effects :
1963 // Creates a destructor function and wraps it.
1964 // -----------------------------------------------------------------------------
1965
1966 void cplus_emit_destructor(char *classname, char *classtype, char *classrename,
1967 char *mname, char *mrename, int mode)
1968 {
1969 Parm *p;
1970 DataType *type;
1971 ParmList *l;
1972 String wrap;
1973 String cname,iname;
1974 char *prefix;
1975
1976 // Construct names for the function
1977
1978 if (classrename)
1979 prefix = classrename;
1980 else
1981 prefix = classname;
1982
1983 cname << name_destroy(classname);
1984 if (mrename)
1985 iname << name_destroy(mrename);
1986 else
1987 iname << name_destroy(prefix);
1988
1989 if (!mode) {
1990 // Spit out a helper function for this member function
1991 wrap << "#define " << cname << "(_swigobj) (";
1992 if (ObjCClass) {
1993 wrap << "[_swigobj " << mname << "])\n"; // Name of the member is the destructor
1994 } else if (CPlusPlus)
1995 wrap << "delete _swigobj)\n";
1996 else
1997 wrap << "free ((char *) _swigobj))\n";
1998 fprintf(f_wrappers,"%s", wrap.get());
1999 } else {
2000 if (ccode) {
2001 wrap << "static void " << cname << "(" << classtype << classname << " *self) " << ccode;
2002 fprintf(f_wrappers,"%s\n",wrap.get());
2003 }
2004 }
2005
2006 // Make a parameter list for this function
2007
2008 l = new ParmList;
2009 p = new Parm(0,0);
2010 p->t = new DataType;
2011 p->t->type = T_USER;
2012 p->t->is_pointer = 1;
2013 p->t->id = cpp_id;
2014 p->call_type = 0;
2015 sprintf(p->t->name,"%s%s", classtype, classname);
2016 p->name = "self";
2017 l->insert(p,0);
2018
2019 type = new DataType;
2020 type->type = T_VOID;
2021 sprintf(type->name,"void");
2022 type->is_pointer = 0;
2023 type->id = cpp_id;
2024
2025 // iname is the desired name of the function in the target language
2026
2027 lang->create_function(cname,iname,type,l);
2028
2029 delete type;
2030 delete l;
2031
2032 }
2033
2034 // -----------------------------------------------------------------------------
2035 // void cplus_emit_constructor(char *classname, char *classtype, char *classrename,
2036 // char *mname, char *mrename, ParmList *l, int mode)
2037 //
2038 // Creates a C wrapper around a C++ constructor
2039 //
2040 // Inputs :
2041 // classname = name of class
2042 // classtype = type of class (struct,class,union)
2043 // classrename = Renamed class (optional)
2044 // mname = Name of constructor
2045 // mrename = Renamed constructor (optional)
2046 // l = Parameter list
2047 // mode = addmethods mode
2048 //
2049 // Output : None
2050 //
2051 // Side Effects :
2052 // Creates a C wrapper and calls the language module to wrap it.
2053 // -----------------------------------------------------------------------------
2054
2055 void cplus_emit_constructor(char *classname, char *classtype, char *classrename,
2056 char *mname, char *mrename, ParmList *l, int mode)
2057 {
2058 Parm *p;
2059 int i;
2060 DataType *type;
2061 String wrap;
2062 String fcall,cname,iname,argname;
2063 char *prefix;
2064
2065 // Construct names for the function
2066
2067 if (classrename)
2068 prefix = classrename;
2069 else
2070 prefix = classname;
2071
2072 cname << name_construct(classname);
2073 if (mrename)
2074 iname << name_construct(mrename);
2075 else
2076 iname << name_construct(prefix);
2077
2078 // Create a return type
2079
2080 type = new DataType;
2081 type->type = T_USER;
2082 sprintf(type->name,"%s%s", classtype,classname);
2083 type->is_pointer = 1;
2084 type->id = cpp_id;
2085
2086 if (!mode) {
2087 wrap << "#define " << iname << "(";
2088 cname = "";
2089 cname << iname;
2090 if (ObjCClass) {
2091 fcall << type->print_cast() << "[" << classname << " " << mname;
2092 } else if (CPlusPlus) {
2093 fcall << "new " << classname << "(";
2094 } else {
2095 fcall << type->print_cast() << " calloc(1,sizeof("
2096 << classtype << classname << "))";
2097 }
2098
2099 // Walk down the parameter list and spit out arguments
2100
2101 i = 0;
2102 p = l->get_first();
2103 while (p != 0) {
2104 if (ObjCClass) fcall << " " << p->objc_separator;
2105 if ((p->t->type != T_VOID) || (p->t->is_pointer)) {
2106 wrap << "_swigarg" << i;
2107
2108 // Emit an argument in the function call if in C++ mode
2109
2110 if ((CPlusPlus) || (ObjCClass)) {
2111 fcall << "_swigarg" << i;
2112 }
2113 }
2114 i++;
2115 p = l->get_next();
2116 if (p) {
2117 wrap << ",";
2118 if ((CPlusPlus) && (!ObjCClass))
2119 fcall << ",";
2120 }
2121 }
2122
2123 wrap << ") ";
2124 if (ObjCClass) fcall << "]";
2125 else if (CPlusPlus) fcall << ")";
2126
2127 wrap << "(" << fcall << ")\n";
2128 fprintf(f_wrappers,"%s",wrap.get());
2129 } else {
2130 if (ccode) {
2131 wrap << "static " << classtype << classname << " *" << cname << "(";
2132
2133 // Walk down the parameter list and spit out arguments
2134
2135 p = l->get_first();
2136 while (p != 0) {
2137 if ((p->t->type != T_VOID) || (p->t->is_pointer)) {
2138 if (p->call_type & CALL_REFERENCE) {
2139 p->t->is_pointer--;
2140 }
2141 wrap << p->t->print_real(p->name);
2142 if (p->call_type & CALL_REFERENCE) {
2143 p->t->is_pointer++;
2144 }
2145 p = l->get_next();
2146 if (p) {
2147 wrap << ",";
2148 }
2149 } else {
2150 p = l->get_next();
2151 }
2152 }
2153 wrap << ") " << ccode << "\n";
2154 fprintf(f_wrappers,"%s\n",wrap.get());
2155 }
2156 }
2157
2158 // If we had any C++ references, get rid of them now
2159
2160 if (!mode) {
2161 p = l->get_first();
2162 while (p) {
2163 // p->t->is_reference = 0;
2164 p = l->get_next();
2165 }
2166 }
2167
2168 // We've now created a C wrapper. We're going to add it to the interpreter
2169
2170 lang->create_function(cname, iname, type, l);
2171 delete type;
2172 }
2173
2174 // -----------------------------------------------------------------------------
2175 // void cplus_emit_variable_get(char *classname, char *classtype, char *classrename,
2176 // char *mname, char *mrename, DataType *type, int mode)
2177 //
2178 // Writes a C wrapper to extract a data member
2179 //
2180 // Usually this function works as follows :
2181 //
2182 // class Foo {
2183 // double x;
2184 // }
2185 //
2186 // becomes :
2187 //
2188 // double Foo_x_get(Foo *obj) {
2189 // return obj->x;
2190 // }
2191 //
2192 // Optimization : 12/31/97
2193 //
2194 // Now emits a macro like this :
2195 //
2196 // #define Foo_x_get(obj) (obj->x)
2197 //
2198 // Inputs :
2199 // classname = name of C++ class
2200 // classtype = type of class (struct, class, union)
2201 // classrename = Renamed class
2202 // mname = Member name
2203 // mrename = Renamed member
2204 // type = Datatype of the member
2205 // mode = Addmethods mode
2206 //
2207 // Output : None
2208 //
2209 // Side Effects :
2210 // Creates a C accessor function and calls the language module
2211 // to make a wrapper around it.
2212 // -----------------------------------------------------------------------------
2213
2214 void cplus_emit_variable_get(char *classname, char *classtype, char *classrename,
2215 char *mname, char *mrename, DataType *type, int mode) {
2216
2217 Parm *p;
2218 ParmList *l;
2219 String wrap;
2220 String cname, iname, key;
2221 char *prefix;
2222 char *tm;
2223 String source;
2224 char *temp_mname;
2225 char *prev_wrap = 0;
2226
2227 cname = "";
2228 iname = "";
2229 key = "";
2230
2231 // First generate a proper name for the get function
2232
2233 // Get the base class of this member
2234 if (!mrename) temp_mname = mname;
2235 else temp_mname = mrename;
2236
2237 char *bc = cplus_base_class(temp_mname);
2238 if (!bc) bc = classname;
2239 if (strlen(bc) == 0) bc = classname;
2240
2241 // Generate the name of the C wrapper function (is always the same, regardless
2242 // of renaming).
2243
2244 cname << name_get(name_member(mname,bc));
2245
2246 // Generate the scripting name of this function
2247 if (classrename)
2248 prefix = classrename;
2249 else
2250 prefix = classname;
2251
2252 if (mrename)
2253 iname << name_get(name_member(mrename,prefix));
2254 else
2255 iname << name_get(name_member(mname,prefix));
2256
2257 // Now check to see if we have already wrapped a variable like this.
2258
2259 key << cname;
2260 char *temp = copy_string(iname);
2261 if ((member_hash.add(key,temp)) == -1) {
2262 delete [] temp;
2263 prev_wrap = (char *) member_hash.lookup(key);
2264 }
2265
2266 // Only generate code if already existing wrapper doesn't exist
2267 if (!prev_wrap) {
2268 if (!mode) {
2269 // Get any sort of typemap that might exist
2270
2271 source << "obj->" << mname;
2272
2273 // Now write a function to get the value of the variable
2274
2275 tm = typemap_lookup("memberout",typemap_lang,type,mname,source,"result");
2276
2277 if ((type->type == T_USER) && (!type->is_pointer)) {
2278 type->is_pointer++;
2279 if (tm) {
2280 wrap << "static " << type->print_type() << " " << cname << "("
2281 << classtype << classname << " *obj) {\n"
2282 << tab4 << type->print_type() << " result;\n"
2283 << tm << "\n"
2284 << tab4 << "return result;\n"
2285 << "}\n";
2286 } else {
2287 wrap << "#define " << cname << "(_swigobj) "
2288 << "(&_swigobj->" << mname << ")\n";
2289 }
2290 type->is_pointer--;
2291 } else {
2292 if (tm) {
2293 wrap << "static " << type->print_type() << " " << cname << "("
2294 << classtype << classname << " *obj) {\n"
2295 << tab4 << type->print_type() << " result;\n"
2296 << tm << "\n"
2297 << tab4 << "return result;\n"
2298 << "}\n";
2299 } else {
2300 wrap << "#define " << cname << "(_swigobj) (";
2301 if (!type->is_reference) wrap << type->print_cast();
2302 else
2303 wrap << "&";
2304 wrap << " _swigobj->" << mname << ")\n";
2305 }
2306 }
2307 fprintf(f_wrappers,"%s",wrap.get());
2308 }
2309
2310 // Wrap this function
2311
2312 l = new ParmList;
2313 p = new Parm(0,0);
2314 p->t = new DataType;
2315 p->t->type = T_USER;
2316 p->t->is_pointer = 1;
2317 p->t->id = cpp_id;
2318 p->call_type = 0;
2319 p->name = "self";
2320 sprintf(p->t->name,"%s%s", classtype,classname);
2321 l->insert(p,0);
2322
2323 if ((type->type == T_USER) && (!type->is_pointer)) {
2324 type->is_pointer++;
2325 lang->create_function(cname,iname, type, l);
2326 type->is_pointer--;
2327 } else {
2328 int is_ref = type->is_reference;
2329 type->is_reference = 0;
2330 lang->create_function(cname,iname, type, l);
2331 type->is_reference = is_ref;
2332 }
2333 delete l;
2334 } else {
2335 // Already wrapped this function. Just patch it up
2336 lang->create_command(prev_wrap,iname);
2337 }
2338
2339 }
2340
2341 // -----------------------------------------------------------------------------
2342 // void cplus_emit_variable_set(char *classname, char *classtype, char *mname,
2343 // char *cname, char *iname, DataType *type, int mode)
2344 //
2345 // Writes a C wrapper to set a data member
2346 //
2347 // Usually this function works as follows :
2348 //
2349 // class Foo {
2350 // double x;
2351 // }
2352 //
2353 // becomes :
2354 //
2355 // double Foo_x_set(Foo *obj, double value) {
2356 // return (obj->x = value);
2357 // }
2358 //
2359 // Need to handle special cases for char * and for user defined types.
2360 //
2361 // 1. char *
2362 //
2363 // Will free previous contents (if any) and allocate
2364 // new storage. Could be risky, but it's a reasonably
2365 // natural thing to do.
2366 //
2367 // 2. User_Defined
2368 // Will assign value from a pointer.
2369 // Will return a pointer to current value.
2370 //
2371 //
2372 // Optimization, now defined as a C preprocessor macro
2373 //
2374 // Inputs :
2375 // classname = name of C++ class
2376 // classtype = type of class (struct, class, union)
2377 // mname = Member name
2378 // cname = Name of the C function for this (ie. Foo_bar_get)
2379 // iname = Interpreter name of ths function
2380 // type = Datatype of the member
2381 // mode = Addmethods mode
2382 //
2383 // Output : None
2384 //
2385 // Side Effects :
2386 // Creates a C accessor function and calls the language module
2387 // to wrap it.
2388 // -----------------------------------------------------------------------------
2389
2390 void cplus_emit_variable_set(char *classname, char *classtype, char *classrename,
2391 char *mname, char *mrename, DataType *type, int mode) {
2392
2393 Parm *p;
2394 ParmList *l;
2395 String wrap;
2396 int is_user = 0;
2397 char *tm;
2398 String target;
2399 String cname, iname, key;
2400 char *temp_mname;
2401 char *prefix;
2402 char *prev_wrap = 0;
2403
2404 cname = "";
2405 iname = "";
2406 key = "";
2407
2408 // First generate a proper name for the get function
2409
2410 // Get the base class of this member
2411 if (!mrename) temp_mname = mname;
2412 else temp_mname = mrename;
2413
2414 char *bc = cplus_base_class(temp_mname);
2415 if (!bc) bc = classname;
2416 if (strlen(bc) == 0) bc = classname;
2417
2418 // Generate the name of the C wrapper function (is always the same, regardless
2419 // of renaming).
2420
2421 cname << name_set(name_member(mname,bc));
2422
2423 // Generate the scripting name of this function
2424 if (classrename)
2425 prefix = classrename;
2426 else
2427 prefix = classname;
2428
2429 if (mrename)
2430 iname << name_set(name_member(mrename,prefix));
2431 else
2432 iname << name_set(name_member(mname,prefix));
2433
2434 // Now check to see if we have already wrapped a variable like this.
2435
2436 key << cname;
2437 char *temp = copy_string(iname);
2438 if ((member_hash.add(key,temp)) == -1) {
2439 delete [] temp;
2440 prev_wrap = (char *) member_hash.lookup(key);
2441 }
2442
2443 // Only generate code if already existing wrapper doesn't exist
2444
2445 if (!prev_wrap) {
2446 if (!mode) {
2447
2448 target << "obj->" << mname;
2449
2450 // Lookup any typemaps that might exist
2451 tm = typemap_lookup("memberin",typemap_lang,type,mname,"val",target);
2452
2453 // First write a function to set the variable
2454
2455 if (tm) {
2456 if ((type->type == T_USER) && (!type->is_pointer)) {
2457 type->is_pointer++;
2458 is_user = 1;
2459 }
2460 wrap << "static " << type->print_type() << " " << cname << "("
2461 << classtype << classname << " *obj, " << type->print_real("val") << ") {\n";
2462 if (is_user) {
2463 type->is_pointer--;
2464 }
2465 wrap << tm << "\n";
2466 // Return the member
2467 if (is_user) type->is_pointer++;
2468 wrap << tab4 << "return " << type->print_cast() << " val;\n";
2469 if (is_user) type->is_pointer--;
2470 wrap << "}\n";
2471
2472 } else {
2473 if ((type->type != T_VOID) || (type->is_pointer)){
2474 if (!type->is_pointer) {
2475
2476 wrap << "#define " << cname << "(_swigobj,_swigval) (";
2477 // Have a real value here (ie. not a pointer).
2478 // If it's a user defined type, we'll do something special.
2479 // Otherwise, just assign it.
2480
2481 if (type->type != T_USER) {
2482 wrap << "_swigobj->" << mname << " = _swigval";
2483 } else {
2484 wrap << "_swigobj->" << mname << " = *(_swigval)";
2485 }
2486 wrap << ",_swigval)\n";
2487 } else {
2488 // Is a pointer type here. If string, we do something
2489 // special. Otherwise. No problem.
2490 if ((type->type == T_CHAR) && (type->is_pointer == 1)) {
2491 String temp;
2492 wrap << "static " << type->print_type() << " " << cname << "("
2493 << classtype << classname << " *obj, " << type->print_real("val") << ") {\n";
2494 temp << "obj->" << mname;
2495 if (CPlusPlus) {
2496 wrap << tab4 << "if (" << temp << ") delete [] " << temp << ";\n"
2497 << tab4 << temp << " = new char[strlen(val)+1];\n"
2498 << tab4 << "strcpy((char *)" << temp << ",val);\n";
2499 } else {
2500 wrap << tab4 << "if (obj->" << mname << ") free(obj->" << mname << ");\n"
2501 << tab4 << "obj->" << mname << " = (char *) malloc(strlen(val)+1);\n"
2502 << tab4 << "strcpy((char *)obj->" << mname << ",val);\n";
2503 }
2504 wrap << tab4 << "return (char *) val;\n";
2505 wrap << "}\n";
2506 } else {
2507 // A normal pointer type of some sort
2508 wrap << "#define " << cname << "(_swigobj,_swigval) (";
2509 if (type->is_reference) {
2510 wrap << "_swigobj->" << mname << " = *_swigval, _swigval)\n";
2511 } else {
2512 wrap << "_swigobj->" << mname << " = _swigval,_swigval)\n";
2513 }
2514 }
2515 }
2516 }
2517 }
2518 }
2519 fprintf(f_wrappers,"%s",wrap.get());
2520 // Now wrap it.
2521
2522 l = new ParmList;
2523 p = new Parm(0,0);
2524 p->t = new DataType(type);
2525 p->t->is_reference = 0;
2526 p->call_type = 0;
2527 p->t->id = cpp_id;
2528 if ((type->type == T_USER) && (!type->is_pointer)) p->t->is_pointer++;
2529 if (mrename)
2530 p->name = mrename;
2531 else
2532 p->name = mname;
2533 l->insert(p,0);
2534 p = new Parm(0,0);
2535 p->t = new DataType;
2536 p->t->type = T_USER;
2537 p->call_type = 0;
2538 p->t->is_pointer = 1;
2539 p->t->id = cpp_id;
2540 sprintf(p->t->name,"%s%s", classtype,classname);
2541 p->name = "self";
2542 l->insert(p,0);
2543
2544 if ((type->type == T_USER) && (!type->is_pointer)) {
2545 type->is_pointer++;
2546 lang->create_function(cname,iname, type, l);
2547 type->is_pointer--;
2548 } else {
2549 int is_ref = type->is_reference;
2550 type->is_reference = 0;
2551 lang->create_function(cname,iname, type, l);
2552 type->is_reference = is_ref;
2553 }
2554 delete l;
2555 } else {
2556 lang->create_command(prev_wrap,iname);
2557 }
2558 }
2559
2560 // -----------------------------------------------------------------------------
2561 // void cplus_support_doc(String &f)
2562 //
2563 // This function adds a supporting documentation entry to the
2564 // end of a class. This should only be used if there is an
2565 // alternative interface available or if additional information is needed.
2566 //
2567 // doc_entry should be set to the class entry before calling this. Otherwise,
2568 // who knows where this text is going to end up!
2569 //
2570 // Inputs : f = String with additional text
2571 //
2572 // Output : None
2573 //
2574 // Side Effects :
2575 // Adds a text block to the current documentation entry.
2576 //
2577 // -----------------------------------------------------------------------------
2578
2579 void cplus_support_doc(String &f) {
2580
2581 DocEntry *de;
2582 if (doc_entry) {
2583 de = new DocText(f.get(),doc_entry);
2584 de->format = 0;
2585 }
2586 }
2587
2588 // -----------------------------------------------------------------------------
2589 // void cplus_register_type(char *typename)
2590 //
2591 // Registers a datatype name to be associated with the current class. This
2592 // typename is placed into a local hash table for later use. For example :
2593 //
2594 // class foo {
2595 // public:
2596 // enum ENUM { ... };
2597 // typedef double Real;
2598 // void bar(ENUM a, Real b);
2599 // }
2600 //
2601 // Then we need to access bar using fully qualified type names such as
2602 //
2603 // void wrap_bar(foo::ENUM a, foo::Real b) {
2604 // bar(a,b);
2605 // }
2606 //
2607 // Inputs : name of the datatype.
2608 //
2609 // Output : None
2610 //
2611 // Side Effects : Adds datatype to localtypes.
2612 // -----------------------------------------------------------------------------
2613
2614 void cplus_register_type(char *tname) {
2615 if (current_class)
2616 add_local_type(tname, current_class->classname);
2617 };
2618
2619 // -----------------------------------------------------------------------------
2620 // void cplus_register_scope(Hash *h)
2621 //
2622 // Saves the scope associated with a particular class. It will be needed
2623 // later if anything inherits from us.
2624 //
2625 // Inputs : Hash table h containing the scope
2626 //
2627 // Output : None
2628 //
2629 // Side Effects : Saves h with current class
2630 // -----------------------------------------------------------------------------
2631
2632 void cplus_register_scope(Hash *h) {
2633 if (current_class) {
2634 current_class->scope = h;
2635 }
2636 }
2637
2638 // -----------------------------------------------------------------------------
2639 // void cplus_inherit_scope(int count, char **baseclass)
2640 //
2641 // Given a list of base classes, this function extracts their former scopes
2642 // and merges them with the current scope. This is needed to properly handle
2643 // inheritance.
2644 //
2645 // Inputs : baseclass = NULL terminated array of base-class names
2646 //
2647 // Output : None
2648 //
2649 // Side Effects : Updates current scope with new symbols.
2650 //
2651 // Copies any special symbols if needed.
2652 // -----------------------------------------------------------------------------
2653
2654 void cplus_inherit_scope(int count, char **baseclass) {
2655 CPP_class *bc;
2656 int i;
2657 char *key, *val;
2658 String str;
2659
2660 if (count && current_class) {
2661 for (i = 0; i < count; i++) {
2662 bc = CPP_class::search(baseclass[i]);
2663 if (bc) {
2664 if (bc->scope)
2665 DataType::merge_scope(bc->scope);
2666
2667 if (bc->local) {
2668 // Copy local symbol table
2669 key = bc->local->firstkey();
2670 while (key) {
2671 val = (char *) bc->local->lookup(key);
2672 str = val;
2673 // str.replace(bc->classname,current_class->classname);
2674 localtypes->add(key,copy_string(str));
2675 key = bc->local->nextkey();
2676 }
2677 }
2678 }
2679 }
2680 }
2681 }
2682