]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wxSWIG/SWIG/types.cxx
Updates for building wxSWIG on Linux
[wxWidgets.git] / wxPython / wxSWIG / SWIG / types.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 /***********************************************************************
17 * $Header$
18 *
19 * types.cxx
20 *
21 * This file contains functions for dealing with datatypes. This
22 * is a combination of the file typedef.cc (now obsolete) and functions
23 * that used to be in the swig.h header.
24 *
25 ***********************************************************************/
26
27 #include "internal.h"
28
29 // -------------------------------------------------------------------
30 // class DataType member functions.
31 // -------------------------------------------------------------------
32
33 DataType::DataType() {
34 type = 1;
35 name[0] = 0;
36 is_pointer = 0;
37 implicit_ptr = 0;
38 qualifier = 0;
39 is_reference = 0;
40 status = 0;
41 arraystr = 0;
42 id = type_id++;
43 }
44
45 // Create a data type only from the type code (used to form constants)
46
47 DataType::DataType(int t) {
48 switch(t) {
49 case T_BOOL:
50 strcpy(name,"bool");
51 break;
52 case T_INT: case T_SINT:
53 strcpy(name,"int");
54 break;
55 case T_UINT:
56 strcpy(name,"unsigned int");
57 break;
58 case T_SHORT: case T_SSHORT:
59 strcpy(name,"short");
60 break;
61 case T_USHORT:
62 strcpy(name,"unsigned short");
63 break;
64 case T_LONG: case T_SLONG:
65 strcpy(name,"long");
66 break;
67 case T_ULONG:
68 strcpy(name,"unsigned long");
69 break;
70 case T_FLOAT:
71 strcpy(name, "float");
72 break;
73 case T_DOUBLE:
74 strcpy(name, "double");
75 break;
76 case T_CHAR: case T_SCHAR:
77 strcpy(name, "char");
78 break;
79 case T_UCHAR:
80 strcpy(name,"unsigned char");
81 break;
82 case T_VOID:
83 strcpy(name,"void");
84 break;
85 case T_USER:
86 strcpy(name,"USER");
87 break;
88 default :
89 strcpy(name,"UNKNOWN");
90 break;
91 }
92 type = t;
93 is_pointer = 0;
94 implicit_ptr = 0;
95 qualifier = 0;
96 is_reference = 0;
97 status = 0;
98 arraystr = 0;
99 id = type_id++;
100 }
101
102 DataType::DataType(DataType *t) {
103 type = t->type;
104 strcpy(name,t->name);
105 is_pointer = t->is_pointer;
106 implicit_ptr = t->implicit_ptr;
107 qualifier = copy_string(t->qualifier);
108 is_reference = t->is_reference;
109 status = t->status;
110 arraystr = copy_string(t->arraystr);
111 id = t->id;
112 }
113
114 DataType::~DataType() {
115 if (qualifier) delete qualifier;
116 if (arraystr) delete arraystr;
117 }
118
119 // --------------------------------------------------------------------
120 // DataType::primitive()
121 //
122 // Turns a datatype into its bare-bones primitive type. Rarely used,
123 // but sometimes used for typemaps. Permanently alters the datatype!
124 // --------------------------------------------------------------------
125
126 void DataType::primitive() {
127 switch(type) {
128 case T_BOOL:
129 strcpy(name,"bool");
130 break;
131 case T_INT: case T_SINT:
132 strcpy(name,"int");
133 break;
134 case T_SHORT: case T_SSHORT:
135 strcpy(name,"short");
136 break;
137 case T_LONG: case T_SLONG:
138 strcpy(name,"long");
139 break;
140 case T_CHAR:
141 strcpy(name,"char");
142 break;
143 case T_SCHAR:
144 strcpy(name,"signed char");
145 break;
146 case T_UINT:
147 strcpy(name,"unsigned int");
148 break;
149 case T_USHORT:
150 strcpy(name,"unsigned short");
151 break;
152 case T_ULONG:
153 strcpy(name,"unsigned long");
154 break;
155 case T_UCHAR:
156 strcpy(name,"unsigned char");
157 break;
158 case T_FLOAT:
159 strcpy(name,"float");
160 break;
161 case T_DOUBLE:
162 strcpy(name,"double");
163 break;
164 case T_VOID:
165 strcpy(name,"void");
166 break;
167 case T_USER:
168 strcpy(name,"USER");
169 break;
170 default:
171 strcpy(name,"UNKNOWN");
172 break;
173 }
174 // if (is_pointer) {
175 // if (!((is_pointer == 1) && (type == T_CHAR))) {
176 // is_pointer = 1;
177 // strcpy(name,"POINTER");
178 // }
179 // }
180
181 implicit_ptr = 0; // Gets rid of typedef'd pointers
182
183 // Ditch qualifiers (const, volatile, etc...)
184
185 if (qualifier) {
186 delete qualifier;
187 qualifier = 0;
188 }
189 qualifier = 0;
190 status = 0;
191 }
192
193 // --------------------------------------------------------------------
194 // char *print_type()
195 //
196 // Print the datatype, but without qualifiers (ie. const, volatile)
197 // Returns a string containing the result.
198 //
199 // If a datatype is marked as an implicit ptr it means that is_pointer
200 // is at least one, but we don't print '*'.
201 //
202 // If the type status is STAT_REPLACETYPE, it means that we can't
203 // use this type as a valid type. We'll substitute it's old name in.
204 // --------------------------------------------------------------------
205
206 char *DataType::print_type() {
207 static String result[8];
208 static int ri = 0;
209
210 DataType *t = this;
211
212 if (status & STAT_REPLACETYPE) {
213 t = new DataType(this);
214 t->typedef_replace(); // Upgrade type
215 }
216
217 ri = ri % 8;
218 result[ri] = "";
219 result[ri] << t->name << " ";
220 for (int i = 0; i < (t->is_pointer-t->implicit_ptr); i++)
221 result[ri] << '*';
222
223 if (status & STAT_REPLACETYPE) {
224 delete t;
225 };
226
227 return result[ri++].get();
228
229 }
230
231 // --------------------------------------------------------------------
232 // char *print_full()
233 //
234 // Prints full type, with qualifiers.
235 // --------------------------------------------------------------------
236
237 char *DataType::print_full() {
238 static String result[8];
239 static int ri = 0;
240
241 ri = ri % 8;
242 result[ri] = "";
243 if (qualifier)
244 result[ri] << qualifier << " " << print_type();
245 else
246 result[ri] << print_type();
247
248 return result[ri++].get();
249
250 }
251
252 // --------------------------------------------------------------------
253 // char *print_real()
254 //
255 // Prints real type, with qualifiers and arrays if necessary.
256 // --------------------------------------------------------------------
257
258 char *DataType::print_real(char *local) {
259 static String result[8];
260 static int ri = 0;
261 int oldstatus;
262
263 oldstatus = status;
264 status = status & (~STAT_REPLACETYPE);
265 ri = ri % 8;
266 result[ri] = "";
267 if (arraystr) is_pointer--;
268 result[ri] << print_full();
269 if (local) result[ri] << local;
270 if (arraystr) {
271 result[ri] << arraystr;
272 is_pointer++;
273 }
274 status = oldstatus;
275 return result[ri++].get();
276 }
277
278 // --------------------------------------------------------------------
279 // char *print_cast()
280 //
281 // Prints a cast. (Basically just a type but with parens added).
282 // --------------------------------------------------------------------
283
284 char *DataType::print_cast() {
285 static String result[8];
286 static int ri = 0;
287
288 ri = ri % 8;
289 result[ri] = "";
290 result[ri] << "(" << print_type() << ")";
291 return result[ri++].get();
292
293 }
294
295 // --------------------------------------------------------------------
296 // char *print_arraycast()
297 //
298 // Prints a cast, but for array datatypes. Super ugly, but necessary
299 // for multidimensional arrays.
300 // --------------------------------------------------------------------
301
302 char *DataType::print_arraycast() {
303 static String result[8];
304 static int ri = 0;
305 int ndim;
306 char *c;
307 DataType *t;
308
309 t = this;
310 if (status & STAT_REPLACETYPE) {
311 t = new DataType(this);
312 t->typedef_replace(); // Upgrade type
313 }
314
315 ri = ri % 8;
316 result[ri] = "";
317
318 if (t->arraystr) {
319 ndim = 0;
320 c = t->arraystr;
321 while (*c) {
322 if (*c == '[') ndim++;
323 c++;
324 }
325 if (ndim > 1) {
326 // a Multidimensional array. Provide a special cast for it
327 int oldstatus = status;
328 t->status = t->status & (~STAT_REPLACETYPE);
329 t->is_pointer--;
330 result[ri] << "(" << t->print_type();
331 t->is_pointer++;
332 t->status = oldstatus;
333 result[ri] << " (*)";
334 c = t->arraystr;
335 while (*c) {
336 if (*c == ']') break;
337 c++;
338 }
339 if (*c) c++;
340 result[ri] << c << ")";
341 }
342 }
343 if (status & STAT_REPLACETYPE) {
344 delete t;
345 }
346 return result[ri++].get();
347 }
348
349 // --------------------------------------------------------------------
350 // char *print_mangle_default()
351 //
352 // Prints a mangled version of this datatype. Used for run-time type
353 // checking in order to print out a "language friendly" version (ie. no
354 // spaces and no weird characters).
355 // --------------------------------------------------------------------
356
357 char *DataType::print_mangle_default() {
358 static String result[8];
359 static int ri = 0;
360 int i;
361 char *c;
362
363 ri = ri % 8;
364 result[ri] = "";
365 c = name;
366
367 result[ri] << '_';
368 for (; *c; c++) {
369 if (*c == ' ') result[ri] << '_';
370 else result[ri] << *c;
371 }
372 if ((is_pointer-implicit_ptr)) result[ri] << '_';
373 for (i = 0; i < (is_pointer-implicit_ptr); i++)
374 result[ri] << 'p';
375
376 return result[ri++].get();
377 }
378
379 // This is kind of ugly but needed for each language to support a
380 // custom name mangling mechanism. (ie. Perl5).
381
382 char *DataType::print_mangle() {
383
384 // Call into target language for name mangling.
385 return lang->type_mangle(this);
386 }
387
388 // --------------------------------------------------------------------
389 // int DataType::array_dimensions()
390 //
391 // Returns the number of dimensions in an array or 0 if not an array.
392 // --------------------------------------------------------------------
393 int DataType::array_dimensions() {
394 char *c;
395 int ndim = 0;
396
397 if (!arraystr) return 0;
398 c = arraystr;
399 while (*c) {
400 if (*c == '[') {
401 ndim++;
402 }
403 c++;
404 }
405 return ndim;
406 }
407
408 // --------------------------------------------------------------------
409 // char *DataType::get_dimension(int n)
410 //
411 // Returns a string containing the value specified for dimension n.
412 // --------------------------------------------------------------------
413
414 char *DataType::get_dimension(int n) {
415 static String dim;
416 char *c;
417
418 dim = "";
419 if (n >= array_dimensions()) return dim;
420
421 // Attemp to locate the right dimension
422
423 c = arraystr;
424 while ((*c) && (n >= 0)) {
425 if (*c == '[') n--;
426 c++;
427 }
428
429 // c is now at start of array dimension
430 if (*c) {
431 while ((*c) && (*c != ']')) {
432 dim << *c;
433 c++;
434 }
435 }
436 return dim;
437 }
438
439 // --------------------------------------------------------------------
440 // char *DataType::get_array()
441 //
442 // Returns the array string for a datatype.
443 // --------------------------------------------------------------------
444
445 char *DataType::get_array() {
446 return arraystr;
447 }
448
449 // --------------------------------------------------------------------
450 // typedef support. This needs to be scoped.
451 // --------------------------------------------------------------------
452
453 Hash *DataType::typedef_hash[MAXSCOPE];
454 int DataType::scope = 0; // Current scope
455
456 static Hash undefined_types; // Hash table containing undefined datatypes.
457
458 // -----------------------------------------------------------------------------
459 // int DataType::check_defined()
460 //
461 // Checks to see if a datatype is defined. If not, returns -1 and puts an entry
462 // into an internal hash table
463 // -----------------------------------------------------------------------------
464
465 int DataType::check_defined() {
466 if (type == T_USER) {
467
468 // Type might be in typedef hash. Check for that
469 int s = scope;
470 while (s >= 0) {
471 if (typedef_hash[s]->lookup(name)) return 0;
472 s--;
473 }
474
475 // Nope. Add as an undefined type and continue.
476
477 char *st;
478 st = copy_string(name);
479 undefined_types.add(st,st);
480 return -1;
481 }
482 return 0;
483 }
484
485 // -----------------------------------------------------------------------------
486 // void DataType::init_typedef()
487 //
488 // Inputs : None
489 //
490 // Output : None
491 //
492 // Side Effects : Initializes the typedef hash tables
493 // -----------------------------------------------------------------------------
494
495 void DataType::init_typedef() {
496 int i;
497 for (i = 0; i < MAXSCOPE; i++)
498 typedef_hash[i] = 0;
499 scope = 0;
500 // Create a new hash
501 typedef_hash[scope] = new Hash;
502 }
503
504 // --------------------------------------------------------------------
505 // void DataType::typedef_add(char *typename, int mode = 0)
506 //
507 // Adds this datatype to the typedef hash table. mode is an optional
508 // flag that can be used to only add the symbol as a typedef, but not
509 // generate any support code for the SWIG typechecker. This is used
510 // for some of the more obscure datatypes like function pointers,
511 // arrays, and enums.
512 // --------------------------------------------------------------------
513
514 void DataType::typedef_add(char *tname, int mode) {
515 String name1,name2;
516 DataType *nt, t1;
517 void typeeq_addtypedef(char *name, char *eqname);
518
519 // Check to see if this typedef already defined
520 // We only check in the local scope. C++ classes may make typedefs
521 // that shadow global ones.
522
523 if (typedef_hash[scope]->lookup(tname)) {
524 fprintf(stderr,"%s : Line %d. Warning. Datatype %s already defined (2nd definition ignored).\n",
525 input_file, line_number, tname);
526 return;
527 }
528
529 // Make a new datatype that we will place in our hash table
530
531 nt = new DataType(this);
532 nt->implicit_ptr = (is_pointer-implicit_ptr); // Record if mapped type is a pointer
533 nt->is_pointer = (is_pointer-implicit_ptr); // Adjust pointer value to be correct
534 nt->typedef_resolve(); // Resolve any other mappings of this type
535 // strcpy(nt->name,tname); // Copy over the new name
536
537 // Add this type to our hash table
538 typedef_hash[scope]->add(tname,(void *) nt);
539
540 // Now add this type mapping to our type-equivalence table
541
542 if (mode == 0) {
543 if ((type != T_VOID) && (strcmp(name,tname) != 0)) {
544 strcpy(t1.name,tname);
545 name2 << t1.print_mangle();
546 name1 << print_mangle();
547 typeeq_addtypedef(name1,name2);
548 typeeq_addtypedef(name2,name1);
549 }
550 }
551 // Call into the target language with this typedef
552 lang->add_typedef(this,tname);
553 }
554
555
556 // --------------------------------------------------------------------
557 // void DataType::typedef_resolve(int level = 0)
558 //
559 // Checks to see if this datatype is in the typedef hash and
560 // resolves it if necessary. This will check all of the typedef
561 // hash tables we know about.
562 //
563 // level is an optional parameter that determines which scope to use.
564 // Usually this is only used with a bare :: operator in a datatype.
565 //
566 // The const headache :
567 //
568 // Normally SWIG will fail if a const variable is used in a typedef
569 // like this :
570 //
571 // typedef const char *String;
572 //
573 // This is because future occurrences of "String" will be treated like
574 // a char *, but without regard to the "constness". To work around
575 // this problem. The resolve() method checks to see if these original
576 // data type is const. If so, we'll substitute the name of the original
577 // datatype instead. Got it? Whew. In a nutshell, this means that
578 // all future occurrences of "String" will really be "const char *".
579 // --------------------------------------------------------------------
580
581 void DataType::typedef_resolve(int level) {
582
583 DataType *td;
584 int s = scope - level;
585
586 while (s >= 0) {
587 if ((td = (DataType *) typedef_hash[s]->lookup(name))) {
588 type = td->type;
589 is_pointer += td->is_pointer;
590 implicit_ptr += td->implicit_ptr;
591 status = status | td->status;
592
593 // Check for constness, and replace type name if necessary
594
595 if (td->qualifier) {
596 if (strcmp(td->qualifier,"const") == 0) {
597 strcpy(name,td->name);
598 qualifier = copy_string(td->qualifier);
599 implicit_ptr -= td->implicit_ptr;
600 }
601 }
602 return;
603 }
604 s--;
605 }
606 // Not found, do nothing
607 return;
608 }
609
610 // --------------------------------------------------------------------
611 // void DataType::typedef_replace()
612 //
613 // Checks to see if this datatype is in the typedef hash and
614 // replaces it with the hash entry. Only applies to current scope.
615 // --------------------------------------------------------------------
616
617 void DataType::typedef_replace () {
618 DataType *td;
619 String temp;
620
621 if ((td = (DataType *) typedef_hash[scope]->lookup(name))) {
622 type = td->type;
623 is_pointer = td->is_pointer;
624 implicit_ptr -= td->implicit_ptr;
625 strcpy(name, td->name);
626 if (td->arraystr) {
627 if (arraystr) {
628 temp << arraystr;
629 delete arraystr;
630 }
631 temp << td->arraystr;
632 arraystr = copy_string(temp);
633 }
634 }
635 // Not found, do nothing
636 return;
637 }
638
639 // ---------------------------------------------------------------
640 // int DataType::is_typedef(char *t)
641 //
642 // Checks to see whether t is the name of a datatype we know
643 // about. Returns 1 if there's a match, 0 otherwise
644 // ---------------------------------------------------------------
645
646 int DataType::is_typedef(char *t) {
647 int s = scope;
648 while (s >= 0) {
649 if (typedef_hash[s]->lookup(t)) return 1;
650 s--;
651 }
652 return 0;
653 }
654
655 // ---------------------------------------------------------------
656 // void DataType::typedef_updatestatus(int newstatus)
657 //
658 // Checks to see if this datatype is in the hash table. If
659 // so, we'll update its status. This is sometimes used with
660 // typemap handling. Only applies to current scope.
661 // ---------------------------------------------------------------
662
663 void DataType::typedef_updatestatus(int newstatus) {
664
665 DataType *t;
666 if ((t = (DataType *) typedef_hash[scope]->lookup(name))) {
667 t->status = newstatus;
668 }
669 }
670
671
672 // -----------------------------------------------------------------------------
673 // void DataType::merge_scope(Hash *h)
674 //
675 // Copies all of the entries in scope h into the current scope. This is
676 // primarily done with C++ inheritance.
677 //
678 // Inputs : Hash table h.
679 //
680 // Output : None
681 //
682 // Side Effects : Copies all of the entries in h to current scope.
683 // -----------------------------------------------------------------------------
684
685 void DataType::merge_scope(Hash *h) {
686 char *key;
687 DataType *t, *nt;
688
689 if (h) {
690 // Copy all of the entries in the given hash table to this new one
691 key = h->firstkey();
692 while (key) {
693 // printf("%s\n", key);
694 t = (DataType *) h->lookup(key);
695 nt = new DataType(t);
696 typedef_hash[scope]->add(key,(void *) nt);
697 key = h->nextkey();
698 }
699 }
700 }
701
702 // -----------------------------------------------------------------------------
703 // void DataType::new_scope(Hash *h = 0)
704 //
705 // Creates a new scope for handling typedefs. This is used in C++ handling
706 // to create typedef local to a class definition.
707 //
708 // Inputs : h = Optional hash table scope (Used for C++ inheritance).
709 //
710 // Output : None
711 //
712 // Side Effects : Creates a new hash table and increments the scope counter
713 // -----------------------------------------------------------------------------
714
715 void DataType::new_scope(Hash *h) {
716 scope++;
717 typedef_hash[scope] = new Hash;
718
719 if (h) {
720 merge_scope(h);
721 }
722 }
723
724 // -----------------------------------------------------------------------------
725 // Hash *DataType::collapse_scope(char *prefix)
726 //
727 // Collapses the current scope into the previous one, but applies a prefix to
728 // all of the datatypes. This is done in order to properly handle C++ stuff.
729 // For example :
730 //
731 // class Foo {
732 // ...
733 // typedef double Real;
734 // }
735 //
736 // will have a type mapping of "double --> Real" within the class itself.
737 // When we collapse the scope, this mapping will become "double --> Foo::Real"
738 //
739 // Inputs : None
740 //
741 // Output : None
742 //
743 // Side Effects : Returns the hash table corresponding to the current scope
744 // -----------------------------------------------------------------------------
745
746 Hash *DataType::collapse_scope(char *prefix) {
747 DataType *t,*nt;
748 char *key;
749 char *temp;
750 Hash *h;
751
752 if (scope > 0) {
753 if (prefix) {
754 key = typedef_hash[scope]->firstkey();
755 while (key) {
756 t = (DataType *) typedef_hash[scope]->lookup(key);
757 nt = new DataType(t);
758 temp = new char[strlen(prefix)+strlen(key)+3];
759 sprintf(temp,"%s::%s",prefix,key);
760 // printf("creating %s\n", temp);
761 typedef_hash[scope-1]->add(temp,(void *) nt);
762 delete temp;
763 key = typedef_hash[scope]->nextkey();
764 }
765 }
766 h = typedef_hash[scope];
767 typedef_hash[scope] = 0;
768 scope--;
769 return h;
770 }
771 return (Hash *) 0;
772 }
773
774 // -------------------------------------------------------------
775 // Class equivalency lists
776 //
777 // These are used to keep track of which datatypes are equivalent.
778 // This information can be dumped in tabular form upon completion
779 // for use in the pointer type checker.
780 //
781 // cast is an extension needed to properly handle multiple inheritance
782 // --------------------------------------------------------------
783
784 struct EqEntry {
785 char *name;
786 char *cast;
787 EqEntry *next;
788 char *sz;
789 };
790
791 static Hash typeeq_hash;
792 static int te_init = 0;
793
794 void typeeq_init() {
795 void typeeq_standard();
796 te_init = 1;
797 typeeq_standard();
798 }
799
800
801 // --------------------------------------------------------------
802 // typeeq_add(char *name, char *eqname, char *cast)
803 //
804 // Adds a new name to the type-equivalence tables.
805 // Creates a new entry if it doesn't exit.
806 //
807 // Cast is an optional name for a pointer casting function.
808 // --------------------------------------------------------------
809
810 void typeeq_add(char *name, char *eqname, char *cast = 0) {
811 EqEntry *e1,*e2;
812
813 if (!te_init) typeeq_init();
814
815 if (strcmp(name,eqname) == 0) return; // If they're the same, forget it.
816
817 // Search for "name" entry in the hash table
818
819 e1 = (EqEntry *) typeeq_hash.lookup(name);
820
821 if (!e1) {
822 // Create a new entry
823 e1 = new EqEntry;
824 e1->name = copy_string(name);
825 e1->next = 0;
826 e1->cast = 0;
827 // Add it to the hash table
828 typeeq_hash.add(name,(void *) e1);
829 }
830
831
832
833 // Add new type to the list
834 // We'll first check to see if it's already been added
835
836 e2 = e1->next;
837 while (e2) {
838 if (strcmp(e2->name, eqname) == 0) {
839 if (cast)
840 e2->cast = copy_string(cast);
841 return;
842 }
843 e2 = e2->next;
844 }
845
846 e2 = new EqEntry;
847 e2->name = copy_string(eqname);
848 e2->cast = copy_string(cast);
849 e2->next = e1->next; // Add onto the linked list for name
850 e1->next = e2;
851
852 }
853
854 // --------------------------------------------------------------
855 // typeeq_addtypedef(char *name, char *eqname)
856 //
857 // Adds a new typedef declaration to the equivelency list.
858 // --------------------------------------------------------------
859
860 void typeeq_addtypedef(char *name, char *eqname) {
861 EqEntry *e1,*e2;
862
863 if (!te_init) typeeq_init();
864
865 // First we're going to add the equivalence, no matter what
866
867 typeeq_add(name,eqname);
868
869 // Now find the hash entry
870
871 e1 = (EqEntry *) typeeq_hash.lookup(name);
872 if (!e1) return;
873
874 // Walk down the list and make other equivalences
875
876 e2 = e1->next;
877 while (e2) {
878 if (strcmp(e2->name, eqname) != 0) {
879 typeeq_add(e2->name, eqname,e2->cast);
880 typeeq_add(eqname, e2->name,e2->cast);
881 }
882 e2 = e2->next;
883 }
884 }
885
886 // ----------------------------------------------------------------
887 // void emit_ptr_equivalence(FILE *f)
888 //
889 // Dump out the pointer equivalence table to file.
890 //
891 // Changed to register datatypes with the type checker in order
892 // to support proper type-casting (needed for multiple inheritance)
893 // ----------------------------------------------------------------
894
895 void emit_ptr_equivalence(FILE *f) {
896
897 EqEntry *e1,*e2;
898 void typeeq_standard();
899 String ttable;
900
901 if (!te_init) typeeq_init();
902
903 ttable << "\
904 /*\n\
905 * This table is used by the pointer type-checker\n\
906 */\n\
907 static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {\n";
908
909 e1 = (EqEntry *) typeeq_hash.first();
910 while (e1) {
911 e2 = e1->next;
912 // Walk through the equivalency list
913 while (e2) {
914 if (e2->cast)
915 ttable << tab4 << "{ \"" << e1->name << "\",\"" << e2->name << "\"," << e2->cast << "},\n";
916 else
917 ttable << tab4 << "{ \"" << e1->name << "\",\"" << e2->name << "\",0},\n";
918 e2 = e2->next;
919 }
920 e1 = (EqEntry *) typeeq_hash.next();
921 }
922 ttable << "{0,0,0}};\n";
923 fprintf(f_wrappers,"%s\n", ttable.get());
924 fprintf(f,"{\n");
925 fprintf(f," int i;\n");
926 fprintf(f," for (i = 0; _swig_mapping[i].n1; i++)\n");
927 fprintf(f," SWIG_RegisterMapping(_swig_mapping[i].n1,_swig_mapping[i].n2,_swig_mapping[i].pcnv);\n");
928 fprintf(f,"}\n");
929 }
930
931 // ------------------------------------------------------------------------------
932 // typeeq_derived(char *n1, char *n2, char *cast=)
933 //
934 // Adds a one-way mapping between datatypes.
935 // ------------------------------------------------------------------------------
936
937 void typeeq_derived(char *n1, char *n2, char *cast=0) {
938 DataType t,t1;
939 String name,name2;
940 EqEntry *e1;
941
942 if (!te_init) typeeq_init();
943
944 strcpy(t.name,n1);
945 strcpy(t1.name,n2);
946 name << t.print_mangle();
947 name2 << t1.print_mangle();
948 typeeq_add(name,name2,cast);
949
950 // Now find the hash entry
951
952 e1 = (EqEntry *) typeeq_hash.lookup(name);
953
954 // Walk down the list and make other equivalences
955
956 /* I don't think this is necessary, but we'll keep this code in case
957
958 e2 = e1->next;
959 while (e2) {
960 if (strcmp(e2->name, name2) != 0) {
961 typeeq_add(e2->name, name2,e2->cast);
962 }
963 e2 = e2->next;
964 }
965 */
966
967 }
968
969 // ------------------------------------------------------------------------------
970 // typeeq_mangle(char *n1, char *n2, char *cast=)
971 //
972 // Adds a single type equivalence
973 // ------------------------------------------------------------------------------
974
975 void typeeq_mangle(char *n1, char *n2, char *cast=0) {
976 DataType t,t1;
977 String name,name2;
978
979 if (!te_init) typeeq_init();
980
981 strcpy(t.name,n1);
982 strcpy(t1.name,n2);
983 name << t.print_mangle();
984 name2 << t1.print_mangle();
985 typeeq_add(name,name2,cast);
986 }
987
988 // ------------------------------------------------------------------------------
989 // typeeq_standard(void)
990 //
991 // Generate standard type equivalences (well, pointers that can map into
992 // other pointers naturally).
993 //
994 // -------------------------------------------------------------------------------
995
996 void typeeq_standard(void) {
997
998 typeeq_mangle("int", "signed int");
999 typeeq_mangle("int", "unsigned int");
1000 typeeq_mangle("signed int", "int");
1001 typeeq_mangle("unsigned int", "int");
1002 typeeq_mangle("short","signed short");
1003 typeeq_mangle("signed short","short");
1004 typeeq_mangle("short","unsigned short");
1005 typeeq_mangle("unsigned short","short");
1006 typeeq_mangle("long","signed long");
1007 typeeq_mangle("signed long","long");
1008 typeeq_mangle("long","unsigned long");
1009 typeeq_mangle("unsigned long","long");
1010
1011 }
1012
1013 // ------------------------------------------------------------------------------
1014 // type_undefined_check(void)
1015 //
1016 // Checks the hash table for undefined datatypes and prints a warning message.
1017 // -------------------------------------------------------------------------------
1018
1019 void type_undefined_check(void) {
1020 char *s;
1021
1022 s = (char *) undefined_types.first();
1023 if (s) {
1024 fprintf(stderr,"The following datatypes were used, but undefined.\n");
1025 while (s) {
1026 fprintf(stderr," %s\n",s);
1027 s = (char *) undefined_types.next();
1028 }
1029 }
1030 }
1031