PageRenderTime 59ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

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