PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/rel-1-3-25/SWIG/Source/Swig/stype.c

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