/tags/Root-branch-php-utl/SWIG/Source/Swig/stype.c
C | 1086 lines | 812 code | 71 blank | 203 comment | 274 complexity | 54b85066f07e2e47526e113a6e5da30d MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
1/* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
4 *
5 * stype.c
6 *
7 * This file provides general support for datatypes that are encoded in
8 * the form of simple strings.
9 * ----------------------------------------------------------------------------- */
10
11char cvsroot_stype_c[] = "$Header$";
12
13#include "swig.h"
14#include "cparse.h"
15#include <ctype.h>
16
17/* -----------------------------------------------------------------------------
18 * Synopsis
19 *
20 * The purpose of this module is to provide a general purpose type representation
21 * based on simple text strings.
22 *
23 * General idea:
24 *
25 * Types are represented by a base type (e.g., "int") and a collection of
26 * type operators applied to the base (e.g., pointers, arrays, etc...).
27 *
28 * Encoding:
29 *
30 * Types are encoded as strings of type constructors such as follows:
31 *
32 * String Encoding C Example
33 * --------------- ---------
34 * p.p.int int **
35 * a(300).a(400).int int [300][400]
36 * p.q(const).char char const *
37 *
38 * All type constructors are denoted by a trailing '.':
39 *
40 * 'p.' = Pointer (*)
41 * 'r.' = Reference (&)
42 * 'a(n).' = Array of size n [n]
43 * 'f(..,..).' = Function with arguments (args)
44 * 'q(str).' = Qualifier (such as const or volatile) (const, volatile)
45 * 'm(qual).' = Pointer to member (qual::*)
46 *
47 * The encoding follows the order that you might describe a type in words.
48 * For example "p.a(200).int" is "A pointer to array of int's" and
49 * "p.q(const).char" is "a pointer to a const char".
50 *
51 * This representation of types is fairly convenient because ordinary string
52 * operations can be used for type manipulation. For example, a type could be
53 * formed by combining two strings such as the following:
54 *
55 * "p.p." + "a(400).int" = "p.p.a(400).int"
56 *
57 * Similarly, one could strip a 'const' declaration from a type doing something
58 * like this:
59 *
60 * Replace(t,"q(const).","",DOH_REPLACE_ANY)
61 *
62 * For the most part, this module tries to minimize the use of special
63 * characters (*, [, <, etc...) in its type encoding. One reason for this
64 * is that SWIG might be extended to encode data in formats such as XML
65 * where you might want to do this:
66 *
67 * <function>
68 * <type>p.p.int</type>
69 * ...
70 * </function>
71 *
72 * Or alternatively,
73 *
74 * <function type="p.p.int" ...>blah</function>
75 *
76 * In either case, it's probably best to avoid characters such as '&', '*', or '<'.
77 *
78 * Why not use C syntax? Well, C syntax is fairly complicated to parse
79 * and not particularly easy to manipulate---especially for adding, deleting and
80 * composing type constructors. The string representation presented here makes
81 * this pretty easy.
82 *
83 * Why not use a bunch of nested data structures? Are you kidding? How
84 * would that be easier to use than a few simple string operations?
85 * ----------------------------------------------------------------------------- */
86
87
88SwigType *NewSwigType(int t) {
89 switch(t) {
90 case T_BOOL:
91 return NewString("bool");
92 break;
93 case T_INT:
94 return NewString("int");
95 break;
96 case T_UINT:
97 return NewString("unsigned int");
98 break;
99 case T_SHORT:
100 return NewString("short");
101 break;
102 case T_USHORT:
103 return NewString("unsigned short");
104 break;
105 case T_LONG:
106 return NewString("long");
107 break;
108 case T_ULONG:
109 return NewString("unsigned long");
110 break;
111 case T_FLOAT:
112 return NewString("float");
113 break;
114 case T_DOUBLE:
115 return NewString("double");
116 break;
117 case T_COMPLEX:
118 return NewString("complex");
119 break;
120 case T_CHAR:
121 return NewString("char");
122 break;
123 case T_SCHAR:
124 return NewString("signed char");
125 break;
126 case T_UCHAR:
127 return NewString("unsigned char");
128 break;
129 case T_STRING: {
130 SwigType *t = NewString("char");
131 SwigType_add_pointer(t);
132 return t;
133 break;
134 }
135 case T_LONGLONG:
136 return NewString("long long");
137 break;
138 case T_ULONGLONG:
139 return NewString("unsigned long long");
140 break;
141 case T_VOID:
142 return NewString("void");
143 break;
144 default :
145 break;
146 }
147 return NewStringEmpty();
148}
149
150/* -----------------------------------------------------------------------------
151 * SwigType_push()
152 *
153 * Push a type constructor onto the type
154 * ----------------------------------------------------------------------------- */
155
156void SwigType_push(SwigType *t, String *cons)
157{
158 if (!cons) return;
159 if (!Len(cons)) return;
160
161 if (Len(t)) {
162 char *c = Char(cons);
163 if (c[strlen(c)-1] != '.')
164 Insert(t,0,".");
165 }
166 Insert(t,0,cons);
167}
168
169/* -----------------------------------------------------------------------------
170 * SwigType_ispointer()
171 * SwigType_ispointer_return()
172 * SwigType_isarray()
173 * SwigType_isreference()
174 * SwigType_isfunction()
175 * SwigType_isqualifier()
176 *
177 * Testing functions for querying a raw datatype
178 * ----------------------------------------------------------------------------- */
179
180int SwigType_ispointer_return(SwigType *t) {
181 char* c;
182 int idx;
183 if (!t) return 0;
184 c = Char(t);
185 idx = strlen(c)-4;
186 if (idx >= 0) {
187 return (strcmp(c+idx, ").p.") == 0);
188 }
189 return 0;
190}
191
192int SwigType_isreference_return(SwigType *t) {
193 char* c;
194 int idx;
195 if (!t) return 0;
196 c = Char(t);
197 idx = strlen(c)-4;
198 if (idx >= 0) {
199 return (strcmp(c+idx, ").r.") == 0);
200 }
201 return 0;
202}
203
204int SwigType_isconst(SwigType *t) {
205 char *c;
206 if (!t) return 0;
207 c = Char(t);
208 if (strncmp(c,"q(",2) == 0) {
209 String *q = SwigType_parm(t);
210 if (strstr(Char(q),"const")) {
211 Delete(q);
212 return 1;
213 }
214 Delete(q);
215 }
216 /* Hmmm. Might be const through a typedef */
217 if (SwigType_issimple(t)) {
218 int ret;
219 SwigType *td = SwigType_typedef_resolve(t);
220 if (td) {
221 ret = SwigType_isconst(td);
222 Delete(td);
223 return ret;
224 }
225 }
226 return 0;
227}
228
229int SwigType_ismutable(SwigType *t) {
230 int r;
231 SwigType *qt = SwigType_typedef_resolve_all(t);
232 if (SwigType_isreference(qt) || SwigType_isarray(qt)) {
233 Delete(SwigType_pop(qt));
234 }
235 r = SwigType_isconst(qt);
236 Delete(qt);
237 return r ? 0 : 1;
238}
239
240int SwigType_isenum(SwigType *t) {
241 char *c = Char(t);
242 if (!t) return 0;
243 if (strncmp(c,"enum ",5) == 0) {
244 return 1;
245 }
246 return 0;
247}
248
249int SwigType_issimple(SwigType *t) {
250 char *c = Char(t);
251 if (!t) return 0;
252 while (*c) {
253 if (*c == '<') {
254 int nest = 1;
255 c++;
256 while (*c && nest) {
257 if (*c == '<') nest++;
258 if (*c == '>') nest--;
259 c++;
260 }
261 c--;
262 }
263 if (*c == '.') return 0;
264 c++;
265 }
266 return 1;
267}
268
269/* -----------------------------------------------------------------------------
270 * SwigType_default()
271 *
272 * Create the default string for this datatype. This takes a type and strips it
273 * down to its most primitive form--resolving all typedefs and removing operators.
274 *
275 * Rules:
276 * Pointers: p.SWIGTYPE
277 * References: r.SWIGTYPE
278 * Arrays: a().SWIGTYPE
279 * Types: SWIGTYPE
280 * MemberPointer: m(CLASS).SWIGTYPE
281 * Enums: enum SWIGTYPE
282 *
283 * Note: if this function is applied to a primitive type, it returns NULL. This
284 * allows recursive application for special types like arrays.
285 * ----------------------------------------------------------------------------- */
286
287#ifdef SWIG_DEFAULT_CACHE
288static Hash *default_cache = 0;
289#endif
290
291#define SWIG_NEW_TYPE_DEFAULT
292/* The new default type resolution method:
293
2941.- It preserves the original mixed types, then it goes 'backward'
295 first deleting the qualifier, then the inner types
296
297 typedef A *Aptr;
298 const Aptr&;
299 r.q(const).Aptr -> r.q(const).p.SWIGTYPE
300 r.q(const).p.SWIGTYPE -> r.p.SWIGTYPE
301 r.p.SWIGTYPE -> r.SWIGTYPE
302 r.SWIGTYPE -> SWIGTYPE
303
304
305 enum Hello {};
306 const Hello& hi;
307 r.q(const).Hello -> r.q(const).enum SWIGTYPE
308 r.q(const).enum SWIGTYPE -> r.enum SWIGTYPE
309 r.enum SWIGTYPE -> r.SWIGTYPE
310 r.SWIGTYPE -> SWIGTYPE
311
312 int a[2][4];
313 a(2).a(4).int -> a(ANY).a(ANY).SWIGTYPE
314 a(ANY).a(ANY).SWIGTYPE -> a(ANY).a().SWIGTYPE
315 a(ANY).a().SWIGTYPE -> a(ANY).p.SWIGTYPE
316 a(ANY).p.SWIGTYPE -> a(ANY).SWIGTYPE
317 a(ANY).SWIGTYPE -> a().SWIGTYPE
318 a().SWIGTYPE -> p.SWIGTYPE
319 p.SWIGTYPE -> SWIGTYPE
320*/
321
322static
323void SwigType_add_default(String *def, SwigType *nr)
324{
325 if (Strcmp(nr,"SWIGTYPE") == 0) {
326 StringAppend(def,"SWIGTYPE");
327 } else {
328 String *q = SwigType_isqualifier(nr) ? SwigType_pop(nr) : 0;
329 if (q && strstr(Char(nr),"SWIGTYPE")) {
330 StringAppend(def, nr);
331 } else {
332 String *nd = SwigType_default(nr);
333 if (nd) {
334 String *bdef = nd;
335 if (q) {
336 bdef = NewStringf("%s%s", q, nd);
337 if ((Strcmp(nr,bdef) == 0)) {
338 Delete(bdef);
339 bdef = nd;
340 } else {
341 Delete(nd);
342 }
343 }
344 StringAppend(def,bdef);
345 Delete(bdef);
346 } else {
347 StringAppend(def,nr);
348 }
349 }
350 Delete(q);
351 }
352}
353
354
355SwigType *SwigType_default(SwigType *t) {
356 String *r1, *def;
357 String *r = 0;
358 char *cr;
359
360#ifdef SWIG_DEFAULT_CACHE
361 if (!default_cache) default_cache = NewHash();
362
363 r = Getattr(default_cache,t);
364 if (r) {
365 return Copy(r);
366 }
367#endif
368
369 if (SwigType_isvarargs(t)) {
370 return 0;
371 }
372
373 r = t;
374 while ((r1 = SwigType_typedef_resolve(r))) {
375 if (r != t) Delete(r);
376 r = r1;
377 }
378 if (SwigType_isqualifier(r)) {
379 String *q;
380 if (r == t) r = Copy(t);
381 q = SwigType_pop(r);
382 if (strstr(Char(r),"SWIGTYPE")) {
383 Delete(q);
384 def = r;
385 return def;
386 }
387 Delete(q);
388 }
389 cr = Char(r);
390 if (strcmp(cr,"p.SWIGTYPE") == 0) {
391 def = NewString("SWIGTYPE");
392 } else if (SwigType_ispointer(r)) {
393#ifdef SWIG_NEW_TYPE_DEFAULT
394 SwigType *nr = Copy(r);
395 SwigType_del_pointer(nr);
396 def = SwigType_isfunction(nr) ?
397 NewStringEmpty() : NewString("p.");
398 SwigType_add_default(def, nr);
399 Delete(nr);
400#else
401 def = NewString("p.SWIGTYPE");
402#endif
403 } else if (strcmp(cr,"r.SWIGTYPE") == 0) {
404 def = NewString("SWIGTYPE");
405 } else if (SwigType_isreference(r)) {
406#ifdef SWIG_NEW_TYPE_DEFAULT
407 SwigType *nr = Copy(r);
408 SwigType_del_reference(nr);
409 def = NewString("r.");
410 SwigType_add_default(def, nr);
411 Delete(nr);
412#else
413 def = NewString("r.SWIGTYPE");
414#endif
415 } else if (SwigType_isarray(r)) {
416 if (strcmp(cr,"a().SWIGTYPE") == 0) {
417 def = NewString("p.SWIGTYPE");
418 } else if (strcmp(cr,"a(ANY).SWIGTYPE") == 0) {
419 def = NewString("a().SWIGTYPE");
420 } else {
421 int i, empty = 0;
422 int ndim = SwigType_array_ndim(r);
423 SwigType *nr = Copy(r);
424 for (i = 0; i < ndim; i++) {
425 String *dim = SwigType_array_getdim(r,i);
426 if (!Len(dim)) {
427 char *c = Char(nr);
428 empty = strstr(c,"a(ANY).") != c;
429 }
430 Delete(dim);
431 }
432 if (empty) {
433 def = NewString("a().");
434 } else {
435 def = NewString("a(ANY).");
436 }
437#ifdef SWIG_NEW_TYPE_DEFAULT
438 SwigType_del_array(nr);
439 SwigType_add_default(def, nr);
440#else
441 StringAppend(def,"SWIGTYPE");
442#endif
443 Delete(nr);
444 }
445 } else if (SwigType_ismemberpointer(r)) {
446 if (strcmp(cr,"m(CLASS).SWIGTYPE") == 0) {
447 def = NewString("p.SWIGTYPE");
448 } else {
449 def = NewString("m(CLASS).SWIGTYPE");
450 }
451 } else if (SwigType_isenum(r)) {
452 if (strcmp(cr,"enum SWIGTYPE") == 0) {
453 def = NewString("SWIGTYPE");
454 } else {
455 def = NewString("enum SWIGTYPE");
456 }
457 } else if (SwigType_isfunction(r)) {
458 if (strcmp(cr,"f(ANY).SWIGTYPE") == 0) {
459 def = NewString("p.SWIGTYPE");
460 } else {
461 def = NewString("p.f(ANY).SWIGTYPE");
462 }
463 } else {
464 def = NewString("SWIGTYPE");
465 }
466 if (r != t) Delete(r);
467 if (StringEqual(def,t)) {
468 Delete(def);
469 def = 0;
470 }
471
472#ifdef SWIG_DEFAULT_CACHE
473 /* The cache produces strange results, see enum_template.i case */
474 if (def) {
475 String *cdef = Copy(def);
476 Setattr(default_cache,t, cdef);
477 Delete(cdef);
478 }
479#endif
480
481 /* Printf(stderr,"type : def %s : %s\n", t, def); */
482
483 return def;
484}
485
486/* -----------------------------------------------------------------------------
487 * SwigType_namestr()
488 *
489 * Returns a string of the base type. Takes care of template expansions
490 * ----------------------------------------------------------------------------- */
491
492String *
493SwigType_namestr(const SwigType *t) {
494 String *r;
495 String *suffix;
496 List *p;
497 int i, sz;
498 char *d = Char(t);
499 char *c = strstr(d,"<(");
500
501 if (!c || !strstr(c+2,")>")) return NewString(t);
502
503 r = NewStringWithSize(d, c - d);
504 if (*(c - 1) == '<') Putc(' ',r);
505 Putc('<',r);
506
507 p = SwigType_parmlist(c+1);
508 sz = Len(p);
509 for (i = 0; i < sz; i++) {
510 String *str = SwigType_str(Getitem(p,i),0);
511 StringAppend(r,str);
512 if ((i+1) < sz) Putc(',',r);
513 Delete(str);
514 }
515 Putc(' ',r);
516 Putc('>',r);
517 suffix = SwigType_templatesuffix(t);
518 StringAppend(r,suffix);
519 Delete(suffix);
520 Delete(p);
521 return r;
522}
523
524/* -----------------------------------------------------------------------------
525 * SwigType_str()
526 *
527 * Create a C string representation of a datatype.
528 * ----------------------------------------------------------------------------- */
529
530String *
531SwigType_str(SwigType *s, const String_or_char *id)
532{
533 String *result;
534 String *element = 0, *nextelement;
535 List *elements;
536 int nelements, i;
537
538 if (id) {
539 result = NewString(id);
540 } else {
541 result = NewStringEmpty();
542 }
543
544 elements = SwigType_split(s);
545 nelements = Len(elements);
546
547 if (nelements > 0) {
548 element = Getitem(elements,0);
549 }
550 /* Now, walk the type list and start emitting */
551 for (i = 0; i < nelements; i++) {
552 if (i < (nelements - 1)) {
553 nextelement = Getitem(elements,i+1);
554 } else {
555 nextelement = 0;
556 }
557 if (SwigType_isqualifier(element)) {
558 DOH *q = 0;
559 q = SwigType_parm(element);
560 Insert(result,0," ");
561 Insert(result,0,q);
562 Delete(q);
563 } else if (SwigType_ispointer(element)) {
564 Insert(result,0,"*");
565 if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
566 Insert(result,0,"(");
567 StringAppend(result,")");
568 }
569 } else if (SwigType_ismemberpointer(element)) {
570 String *q;
571 q = SwigType_parm(element);
572 Insert(result,0,"::*");
573 Insert(result,0,q);
574 if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
575 Insert(result,0,"(");
576 StringAppend(result,")");
577 }
578 Delete(q);
579 }
580 else if (SwigType_isreference(element)) {
581 Insert(result,0,"&");
582 if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
583 Insert(result,0,"(");
584 StringAppend(result,")");
585 }
586 } else if (SwigType_isarray(element)) {
587 DOH *size;
588 StringAppend(result,"[");
589 size = SwigType_parm(element);
590 StringAppend(result,size);
591 StringAppend(result,"]");
592 Delete(size);
593 } else if (SwigType_isfunction(element)) {
594 DOH *parms, *p;
595 int j, plen;
596 StringAppend(result,"(");
597 parms = SwigType_parmlist(element);
598 plen = Len(parms);
599 for (j = 0; j < plen; j++) {
600 p = SwigType_str(Getitem(parms,j),0);
601 StringAppend(result,p);
602 if (j < (plen-1)) StringAppend(result,",");
603 }
604 StringAppend(result,")");
605 Delete(parms);
606 } else {
607 if (strcmp(Char(element),"v(...)") == 0) {
608 Insert(result,0,"...");
609 } else {
610 String *bs = SwigType_namestr(element);
611 Insert(result,0," ");
612 Insert(result,0,bs);
613 Delete(bs);
614 }
615 }
616 element = nextelement;
617 }
618 Delete(elements);
619 Chop(result);
620 return result;
621}
622
623/* -----------------------------------------------------------------------------
624 * SwigType_ltype(SwigType *ty)
625 *
626 * Create a locally assignable type
627 * ----------------------------------------------------------------------------- */
628
629SwigType *
630SwigType_ltype(SwigType *s) {
631 String *result;
632 String *element;
633 SwigType *td, *tc = 0;
634 List *elements;
635 int nelements, i;
636 int firstarray = 1;
637 int notypeconv = 0;
638
639 result = NewStringEmpty();
640 tc = Copy(s);
641 /* Nuke all leading qualifiers */
642 while (SwigType_isqualifier(tc)) {
643 Delete(SwigType_pop(tc));
644 }
645 if (SwigType_issimple(tc)) {
646 /* Resolve any typedef definitions */
647 SwigType *tt = Copy(tc);
648 td = 0;
649 while ((td = SwigType_typedef_resolve(tt))) {
650 if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) {
651 /* We need to use the typedef type */
652 Delete(tt);
653 tt = td;
654 break;
655 } else if (td) {
656 Delete(tt);
657 tt = td;
658 }
659 }
660 if (td) {
661 Delete(tc);
662 tc = td;
663 }
664 }
665 elements = SwigType_split(tc);
666 nelements = Len(elements);
667
668 /* Now, walk the type list and start emitting */
669 for (i = 0; i < nelements; i++) {
670 element = Getitem(elements,i);
671 /* when we see a function, we need to preserve the following types */
672 if (SwigType_isfunction(element)) {
673 notypeconv = 1;
674 }
675 if (SwigType_isqualifier(element)) {
676 /* Do nothing. Ignore */
677 } else if (SwigType_ispointer(element)) {
678 StringAppend(result,element);
679 firstarray = 0;
680 } else if (SwigType_ismemberpointer(element)) {
681 StringAppend(result,element);
682 firstarray = 0;
683 } else if (SwigType_isreference(element)) {
684 if (notypeconv) {
685 StringAppend(result,element);
686 } else {
687 StringAppend(result,"p.");
688 }
689 firstarray = 0;
690 } else if (SwigType_isarray(element) && firstarray) {
691 if (notypeconv) {
692 StringAppend(result,element);
693 } else {
694 StringAppend(result,"p.");
695 }
696 firstarray = 0;
697 } else if (SwigType_isenum(element)) {
698 int anonymous_enum = (Cmp(element,"enum ") == 0);
699 if (notypeconv || !anonymous_enum) {
700 StringAppend(result,element);
701 } else {
702 StringAppend(result,"int");
703 }
704 } else {
705 StringAppend(result,element);
706 }
707 }
708 Delete(elements);
709 Delete(tc);
710 return result;
711}
712
713/* -----------------------------------------------------------------------------
714 * SwigType_lstr(DOH *s, DOH *id)
715 *
716 * Produces a type-string that is suitable as a lvalue in an expression.
717 * That is, a type that can be freely assigned a value without violating
718 * any C assignment rules.
719 *
720 * - Qualifiers such as 'const' and 'volatile' are stripped.
721 * - Arrays are converted into a *single* pointer (i.e.,
722 * double [][] becomes double *).
723 * - References are converted into a pointer.
724 * - Typedef names that refer to read-only types will be replaced
725 * with an equivalent assignable version.
726 * -------------------------------------------------------------------- */
727
728String *
729SwigType_lstr(SwigType *s, const String_or_char *id)
730{
731 String *result;
732 SwigType *tc;
733
734 tc = SwigType_ltype(s);
735 result = SwigType_str(tc,id);
736 Delete(tc);
737 return result;
738}
739
740/* -----------------------------------------------------------------------------
741 * SwigType_rcaststr()
742 *
743 * Produces a casting string that maps the type returned by lstr() to the real
744 * datatype printed by str().
745 * ----------------------------------------------------------------------------- */
746
747String *SwigType_rcaststr(SwigType *s, const String_or_char *name) {
748 String *result, *cast;
749 String *element = 0, *nextelement;
750 SwigType *td, *rs, *tc = 0;
751 List *elements;
752 int nelements, i;
753 int clear = 1;
754 int firstarray = 1;
755 int isreference = 0;
756 int isarray = 0;
757
758 result = NewStringEmpty();
759
760 if (SwigType_isconst(s)) {
761 tc = Copy(s);
762 Delete(SwigType_pop(tc));
763 rs = tc;
764 } else {
765 rs = s;
766 }
767
768 if ((SwigType_isconst(rs) || SwigType_isarray(rs) || SwigType_isreference(rs))) {
769 td = 0;
770 } else {
771 td = SwigType_typedef_resolve(rs);
772 }
773
774 if (td) {
775 if ((SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) {
776 elements = SwigType_split(td);
777 } else {
778 elements = SwigType_split(rs);
779 }
780 Delete(td);
781 } else {
782 elements = SwigType_split(rs);
783 }
784 nelements = Len(elements);
785 if (nelements > 0) {
786 element = Getitem(elements,0);
787 }
788 /* Now, walk the type list and start emitting */
789 for (i = 0; i < nelements; i++) {
790 if (i < (nelements - 1)) {
791 nextelement = Getitem(elements,i+1);
792 } else {
793 nextelement = 0;
794 }
795 if (SwigType_isqualifier(element)) {
796 DOH *q = 0;
797 q = SwigType_parm(element);
798 Insert(result,0," ");
799 Insert(result,0,q);
800 Delete(q);
801 clear = 0;
802 } else if (SwigType_ispointer(element)) {
803 Insert(result,0,"*");
804 if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
805 Insert(result,0,"(");
806 StringAppend(result,")");
807 }
808 firstarray = 0;
809 } else if (SwigType_ismemberpointer(element)) {
810 String *q;
811 Insert(result,0,"::*");
812 q = SwigType_parm(element);
813 Insert(result,0,q);
814 Delete(q);
815 if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
816 Insert(result,0,"(");
817 StringAppend(result,")");
818 }
819 firstarray = 0;
820 } else if (SwigType_isreference(element)) {
821 Insert(result,0,"&");
822 if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
823 Insert(result,0,"(");
824 StringAppend(result,")");
825 }
826 isreference = 1;
827 } else if (SwigType_isarray(element)) {
828 DOH *size;
829 if (firstarray && !isreference) {
830 StringAppend(result,"(*)");
831 firstarray = 0;
832 } else {
833 StringAppend(result,"[");
834 size = SwigType_parm(element);
835 StringAppend(result,size);
836 StringAppend(result,"]");
837 Delete(size);
838 clear = 0;
839 }
840 isarray = 1;
841 } else if (SwigType_isfunction(element)) {
842 DOH *parms, *p;
843 int j, plen;
844 StringAppend(result,"(");
845 parms = SwigType_parmlist(element);
846 plen = Len(parms);
847 for (j = 0; j < plen; j++) {
848 p = SwigType_str(Getitem(parms,j),0);
849 StringAppend(result,p);
850 Delete(p);
851 if (j < (plen-1)) StringAppend(result,",");
852 }
853 StringAppend(result,")");
854 Delete(parms);
855 } else {
856 String *bs = SwigType_namestr(element);
857 Insert(result,0," ");
858 Insert(result,0,bs);
859 Delete(bs);
860 }
861 element = nextelement;
862 }
863 Delete(elements);
864 if (clear) {
865 cast = NewStringEmpty();
866 } else {
867 cast = NewStringf("(%s)",result);
868 }
869 if (name) {
870 if (isreference) {
871 if (isarray) Clear(cast);
872 StringAppend(cast,"*");
873 }
874 StringAppend(cast,name);
875 }
876 Delete(result);
877 Delete(tc);
878 return cast;
879}
880
881
882/* -----------------------------------------------------------------------------
883 * SwigType_lcaststr()
884 *
885 * Casts a variable from the real type to the local datatype.
886 * ----------------------------------------------------------------------------- */
887
888String *SwigType_lcaststr(SwigType *s, const String_or_char *name) {
889 String *result;
890
891 result = NewStringEmpty();
892
893 if (SwigType_isarray(s)) {
894 String *lstr = SwigType_lstr(s,0);
895 Printf(result,"(%s)%s", lstr,name);
896 Delete(lstr);
897 } else if (SwigType_isreference(s)) {
898 String *str = SwigType_str(s,0);
899 Printf(result,"(%s)", str);
900 Delete(str);
901 if (name)
902 StringAppend(result,name);
903 } else if (SwigType_isqualifier(s)) {
904 String *lstr = SwigType_lstr(s,0);
905 Printf(result,"(%s)%s", lstr,name);
906 Delete(lstr);
907 } else {
908 if (name)
909 StringAppend(result,name);
910 }
911 return result;
912}
913
914
915/* keep old mangling since Java codes need it */
916String *SwigType_manglestr_default(SwigType *s) {
917 char *c;
918 String *result = 0;
919 String *base = 0;
920 SwigType *lt;
921 SwigType *sr = SwigType_typedef_qualified(s);
922 SwigType *ss = SwigType_typedef_resolve_all(sr);
923
924 s = ss;
925
926 if (SwigType_istemplate(ss)) {
927 SwigType *ty = Swig_symbol_template_deftype(ss,0);
928 Delete(ss);
929 ss = ty;
930 s = ss;
931 }
932 Delete(sr);
933
934 lt = SwigType_ltype(s);
935 result = SwigType_prefix(lt);
936 base = SwigType_base(lt);
937
938 c = Char(result);
939 while (*c) {
940 if (!isalnum((int)*c)) *c = '_';
941 c++;
942 }
943 if (SwigType_istemplate(base)) {
944 String *b = SwigType_namestr(base);
945 Delete(base);
946 base = b;
947 }
948
949 Replace(base,"struct ","", DOH_REPLACE_ANY); /* This might be problematic */
950 Replace(base,"class ","", DOH_REPLACE_ANY);
951 Replace(base,"union ","", DOH_REPLACE_ANY);
952 Replace(base,"enum ","", DOH_REPLACE_ANY);
953
954 c = Char(base);
955 while (*c) {
956 if (*c == '<') *c = 'T';
957 else if (*c == '>') *c = 't';
958 else if (*c == '*') *c = 'p';
959 else if (*c == '[') *c = 'a';
960 else if (*c == ']') *c = 'A';
961 else if (*c == '&') *c = 'R';
962 else if (*c == '(') *c = 'f';
963 else if (*c == ')') *c = 'F';
964 else if (!isalnum((int)*c)) *c = '_';
965 c++;
966 }
967 StringAppend(result,base);
968 Insert(result,0,"_");
969 Delete(lt);
970 Delete(base);
971 if (ss) Delete(ss);
972 return result;
973}
974
975String *SwigType_manglestr(SwigType *s) {
976 return SwigType_manglestr_default(s);
977}
978
979/* -----------------------------------------------------------------------------
980 * SwigType_typename_replace()
981 *
982 * Replaces a typename in a type with something else. Needed for templates.
983 * ----------------------------------------------------------------------------- */
984
985void
986SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
987 String *nt;
988 int i, ilen;
989 List *elem;
990
991 if (!Strstr(t,pat)) return;
992
993 if (StringEqual(t,pat)) {
994 Replace(t,pat,rep,DOH_REPLACE_ANY);
995 return;
996 }
997 nt = NewStringEmpty();
998 elem = SwigType_split(t);
999 ilen = Len(elem);
1000 for (i = 0; i < ilen; i++) {
1001 String *e = Getitem(elem,i);
1002 if (SwigType_issimple(e)) {
1003 if (StringEqual(e,pat)) {
1004 /* Replaces a type of the form 'pat' with 'rep<args>' */
1005 Replace(e,pat,rep,DOH_REPLACE_ANY);
1006 } else if (SwigType_istemplate(e)) {
1007 /* Replaces a type of the form 'pat<args>' with 'rep' */
1008 if (StringEqual(e,pat)) {
1009 String *repbase = SwigType_templateprefix(rep);
1010 Replace(e,pat,repbase,DOH_REPLACE_ID | DOH_REPLACE_FIRST);
1011 Delete(repbase);
1012 }
1013 {
1014 String *tsuffix;
1015 List *tparms = SwigType_parmlist(e);
1016 int j, jlen;
1017 String *nt = SwigType_templateprefix(e);
1018 StringAppend(nt,"<(");
1019 jlen = Len(tparms);
1020 for (j = 0; j < jlen; j++) {
1021 SwigType_typename_replace(Getitem(tparms,j), pat, rep);
1022 StringAppend(nt,Getitem(tparms,j));
1023 if (j < (jlen-1)) Putc(',',nt);
1024 }
1025 tsuffix = SwigType_templatesuffix(e);
1026 Printf(nt,")>%s", tsuffix);
1027 Delete(tsuffix);
1028 Clear(e);
1029 StringAppend(e,nt);
1030 Delete(nt);
1031 Delete(tparms);
1032 }
1033 } else if (Swig_scopename_check(e)) {
1034 String *first, *rest;
1035 first = Swig_scopename_first(e);
1036 rest = Swig_scopename_suffix(e);
1037 SwigType_typename_replace(rest,pat,rep);
1038 SwigType_typename_replace(first,pat,rep);
1039 Clear(e);
1040 Printv(e,first,"::",rest,NIL);
1041 Delete(first);
1042 Delete(rest);
1043 }
1044 } else if (SwigType_isfunction(e)) {
1045 int j, jlen;
1046 List *fparms = SwigType_parmlist(e);
1047 Clear(e);
1048 StringAppend(e,"f(");
1049 jlen = Len(fparms);
1050 for (j = 0; j < jlen; j++) {
1051 SwigType_typename_replace(Getitem(fparms,j), pat, rep);
1052 StringAppend(e,Getitem(fparms,j));
1053 if (j < (jlen-1)) Putc(',',e);
1054 }
1055 StringAppend(e,").");
1056 Delete(fparms);
1057 } else if (SwigType_isarray(e)) {
1058 Replace(e,pat,rep, DOH_REPLACE_ID);
1059 }
1060 StringAppend(nt,e);
1061 }
1062 Clear(t);
1063 StringAppend(t,nt);
1064 Delete(nt);
1065 Delete(elem);
1066}
1067
1068/* -----------------------------------------------------------------------------
1069 * SwigType_check_decl()
1070 *
1071 * Checks type declarators for a match
1072 * ----------------------------------------------------------------------------- */
1073
1074int
1075SwigType_check_decl(SwigType *ty, const SwigType *decl) {
1076 SwigType *t,*t1,*t2;
1077 int r;
1078 t = SwigType_typedef_resolve_all(ty);
1079 t1 = SwigType_strip_qualifiers(t);
1080 t2 = SwigType_prefix(t1);
1081 r = Equal(t2,decl);
1082 Delete(t);
1083 Delete(t1);
1084 Delete(t2);
1085 return r == 1;
1086}