PageRenderTime 68ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/tags/main-premerge/SWIG/Source/Modules1.1/perl5.cxx

#
C++ | 1956 lines | 1375 code | 302 blank | 279 comment | 216 complexity | 62f30ac45d09bb43315bda309ae9a8e0 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /* -----------------------------------------------------------------------------
  2. * perl5.cxx
  3. *
  4. * Generate Perl5 wrappers
  5. *
  6. * Author(s) : David Beazley (beazley@cs.uchicago.edu)
  7. * Loic Dachary (loic@ceic.com)
  8. * David Fletcher
  9. * Gary Holt
  10. *
  11. * Copyright (C) 1999-2000. The University of Chicago
  12. * See the file LICENSE for information on usage and redistribution.
  13. * ----------------------------------------------------------------------------- */
  14. /* DB: I had to take some features related to package naming out of this to
  15. get the new type system to work. These need to be put back in at some point. */
  16. static char cvsroot[] = "$Header$";
  17. #include "swig11.h"
  18. #include "perl5.h"
  19. static char *usage = (char*)"\
  20. Perl5 Options (available with -perl5)\n\
  21. -module name - Set module name\n\
  22. -interface name - Set interface name\n\
  23. -package name - Set package prefix\n\
  24. -static - Omit code related to dynamic loading.\n\
  25. -shadow - Create shadow classes.\n\
  26. -compat - Compatibility mode.\n\n";
  27. static String *smodule = 0;
  28. static int compat = 0;
  29. static int export_all = 0;
  30. static String *package = 0;
  31. static String *module = 0;
  32. static String *interface = 0;
  33. static String *cmodule = 0;
  34. static String *vinit = 0;
  35. static FILE *f_pm = 0;
  36. static String *pm; /* Package initialization code */
  37. static String *magic; /* Magic variable wrappers */
  38. static int is_static = 0;
  39. /* The following variables are used to manage Perl5 classes */
  40. static int blessed = 0; /* Enable object oriented features */
  41. static Hash *classes = 0; /* A hash table for storing the classes we've seen so far */
  42. static Hash *symbols = 0;
  43. static int have_constructor = 0;
  44. static int have_destructor= 0;
  45. static int have_data_members = 0;
  46. static String *class_name = 0; /* Name of the class (what Perl thinks it is) */
  47. static String *class_type = 0; /* Type of class "struct", "class", "union" */
  48. static String *real_classname = 0; /* Real name of C/C++ class */
  49. static String *base_class = 0; /* Base class (if using inheritance) */
  50. static int class_renamed = 0;
  51. static String *fullclassname = 0;
  52. static String *pcode = 0; /* Perl code associated with each class */
  53. static String *blessedmembers = 0; /* Member data associated with each class */
  54. static int member_func = 0; /* Set to 1 when wrapping a member function */
  55. static String *realpackage = 0; /* Name of real module */
  56. static String *func_stubs = 0; /* Function stubs */
  57. static String *var_stubs = 0; /* Variable stubs */
  58. static String *member_keys = 0; /* Keys for all member data */
  59. static String *exported = 0; /* Exported symbols */
  60. static String *pragma_include = 0;
  61. /* Test to see if a type corresponds to something wrapped with a shadow class */
  62. static DOH *is_shadow(SwigType *t) {
  63. DOH *r;
  64. SwigType *lt = Swig_clocal_type(t);
  65. r = Getattr(classes,lt);
  66. Delete(lt);
  67. return r;
  68. }
  69. /* -----------------------------------------------------------------------------
  70. * PERL5::parse_args()
  71. * ----------------------------------------------------------------------------- */
  72. void
  73. PERL5::parse_args(int argc, char *argv[]) {
  74. int i = 1;
  75. cmodule = NewString("");
  76. Swig_swiglib_set("perl5");
  77. for (i = 1; i < argc; i++) {
  78. if (argv[i]) {
  79. if(strcmp(argv[i],"-package") == 0) {
  80. if (argv[i+1]) {
  81. package = NewString(argv[i+1]);
  82. Swig_mark_arg(i);
  83. Swig_mark_arg(i+1);
  84. i++;
  85. } else {
  86. Swig_arg_error();
  87. }
  88. } else if(strcmp(argv[i],"-interface") == 0) {
  89. if (argv[i+1]) {
  90. interface = NewString(argv[i+1]);
  91. Swig_mark_arg(i);
  92. Swig_mark_arg(i+1);
  93. i++;
  94. } else {
  95. Swig_arg_error();
  96. }
  97. } else if (strcmp(argv[i],"-exportall") == 0) {
  98. export_all = 1;
  99. Swig_mark_arg(i);
  100. } else if (strcmp(argv[i],"-static") == 0) {
  101. is_static = 1;
  102. Swig_mark_arg(i);
  103. } else if (strcmp(argv[i],"-shadow") == 0) {
  104. blessed = 1;
  105. Swig_mark_arg(i);
  106. } else if (strcmp(argv[i],"-compat") == 0) {
  107. compat = 1;
  108. Swig_mark_arg(i);
  109. } else if (strcmp(argv[i],"-help") == 0) {
  110. fputs(usage,stderr);
  111. }
  112. }
  113. }
  114. Preprocessor_define((void *) "SWIGPERL 1", 0);
  115. Preprocessor_define((void *) "SWIGPERL5 1", 0);
  116. }
  117. /* -----------------------------------------------------------------------------
  118. * PERL5::initialize()
  119. * ----------------------------------------------------------------------------- */
  120. void
  121. PERL5::initialize(String *modname)
  122. {
  123. char filen[256];
  124. classes = NewHash();
  125. symbols = NewHash();
  126. vinit = NewString("");
  127. pm = NewString("");
  128. func_stubs = NewString("");
  129. var_stubs = NewString("");
  130. exported = NewString("");
  131. magic = NewString("");
  132. pragma_include = NewString("");
  133. Swig_banner(f_runtime);
  134. if (NoInclude) {
  135. Printf(f_header,"#define SWIG_NOINCLUDE\n");
  136. }
  137. if (Swig_insert_file("common.swg", f_runtime) == -1) {
  138. Printf(stderr,"SWIG : Fatal error. Unable to locate 'common.swg' in SWIG library.\n");
  139. Swig_exit (EXIT_FAILURE);
  140. }
  141. if (Swig_insert_file("perl5.swg", f_runtime) == -1) {
  142. Printf(stderr,"SWIG : Fatal error. Unable to locate 'perl5.swg' in SWIG library.\n");
  143. Swig_exit (EXIT_FAILURE);
  144. }
  145. if (!module) module = NewString(modname);
  146. /* Create a C module name and put it in 'cmodule' */
  147. Clear(cmodule);
  148. Append(cmodule,module);
  149. Replace(cmodule,":","_",DOH_REPLACE_ANY);
  150. if (!package) {
  151. package = NewString(module);
  152. }
  153. /* If we're in blessed mode, change the package name to "packagec" */
  154. if (blessed) {
  155. realpackage = package;
  156. package = interface ? interface : NewStringf("%sc",package);
  157. } else {
  158. realpackage = NewString(package);
  159. }
  160. /* Create a .pm file
  161. * Need to strip off any prefixes that might be found in
  162. * the module name */
  163. {
  164. char *m = Char(module) + Len(module);
  165. while (m != Char(module)) {
  166. if (*m == ':') {
  167. m++;
  168. break;
  169. }
  170. m--;
  171. }
  172. sprintf(filen,"%s%s.pm", output_dir,m);
  173. if ((f_pm = fopen(filen,"w")) == 0) {
  174. Printf(stderr,"Unable to open %s\n", filen);
  175. Swig_exit (EXIT_FAILURE);
  176. }
  177. }
  178. if (!blessed) {
  179. smodule = NewString(module);
  180. } else if (is_static) {
  181. smodule = NewStringf("%sc",module);
  182. Append(cmodule,"c");
  183. Append(cmodule,"c");
  184. } else {
  185. smodule = NewString(module);
  186. }
  187. {
  188. String *tmp = NewString(realpackage);
  189. Replace(tmp,":","_", DOH_REPLACE_ANY);
  190. Printf(f_header,"#define SWIG_init boot_%s\n\n", tmp);
  191. Printf(f_header,"#define SWIG_name \"%s::boot_%s\"\n", package, tmp);
  192. Delete(tmp);
  193. }
  194. Printf(f_header,"#define SWIG_varinit \"%s::var_%s_init();\"\n", package, cmodule);
  195. Printf(f_header,"#ifdef __cplusplus\n");
  196. Printf(f_header,"extern \"C\"\n");
  197. Printf(f_header,"#endif\n");
  198. Printf(f_header,"#ifndef PERL_OBJECT\n");
  199. Printf(f_header,"SWIGEXPORT(void) SWIG_init (CV* cv);\n");
  200. Printf(f_header,"#else\n");
  201. Printf(f_header,"SWIGEXPORT(void) SWIG_init (CV *cv, CPerlObj *);\n");
  202. Printf(f_header,"#endif\n");
  203. Printf(f_init,"#ifdef __cplusplus\n");
  204. Printf(f_init,"extern \"C\"\n");
  205. Printf(f_init,"#endif\n");
  206. Printf(f_init,"XS(SWIG_init) {\n");
  207. Printf(f_init,"\t dXSARGS;\n");
  208. Printf(f_init,"\t int i;\n");
  209. Printf(f_init,"\t char *file = __FILE__;\n");
  210. Printv(f_init,
  211. "for (i = 0; swig_types_initial[i]; i++) {\n",
  212. "swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n",
  213. "}\n", 0);
  214. Printf(f_init,"\t newXS(\"%s::var_%s_init\", _wrap_perl5_%s_var_init, file);\n",package,cmodule, cmodule);
  215. Printv(vinit,
  216. "XS(_wrap_perl5_", cmodule, "_var_init) {\n",
  217. tab4, "dXSARGS;\n",
  218. tab4, "SV *sv;\n",
  219. 0);
  220. Printf(f_pm,"# This file was automatically generated by SWIG\n");
  221. Printf(f_pm,"package %s;\n",realpackage);
  222. Printf(f_pm,"require Exporter;\n");
  223. if (!is_static) {
  224. Printf(f_pm,"require DynaLoader;\n");
  225. Printf(f_pm,"@ISA = qw(Exporter DynaLoader);\n");
  226. } else {
  227. Printf(f_pm,"@ISA = qw(Exporter);\n");
  228. }
  229. /* Start creating magic code */
  230. Printv(magic,
  231. "#ifdef PERL_OBJECT\n",
  232. "#define MAGIC_CLASS _wrap_", module, "_var::\n",
  233. "class _wrap_", module, "_var : public CPerlObj {\n",
  234. "public:\n",
  235. "#else\n",
  236. "#define MAGIC_CLASS\n",
  237. "#endif\n",
  238. "SWIGCLASS_STATIC int swig_magic_readonly(SV *sv, MAGIC *mg) {\n",
  239. tab4, "MAGIC_PPERL\n",
  240. tab4, "sv = sv; mg = mg;\n",
  241. tab4, "croak(\"Value is read-only.\");\n",
  242. tab4, "return 0;\n",
  243. "}\n",
  244. 0);
  245. }
  246. /* -----------------------------------------------------------------------------
  247. * PERL5::import()
  248. * ----------------------------------------------------------------------------- */
  249. void
  250. PERL5::import(String *modname) {
  251. if (blessed) {
  252. Printf(f_pm,"require %s;\n", modname);
  253. }
  254. }
  255. /* -----------------------------------------------------------------------------
  256. * PERL5::close()
  257. * ----------------------------------------------------------------------------- */
  258. void
  259. PERL5::close(void) {
  260. String *base = NewString("");
  261. /* Dump out variable wrappers */
  262. Printv(magic,
  263. "\n\n#ifdef PERL_OBJECT\n",
  264. "};\n",
  265. "#endif\n",
  266. 0);
  267. Printf(f_header,"%s\n", magic);
  268. String *type_table = NewString("");
  269. SwigType_emit_type_table(f_runtime,type_table);
  270. /* Patch the type table to reflect the names used by shadow classes */
  271. if (blessed) {
  272. SwigType *type;
  273. for (type = Firstkey(classes); type; type = Nextkey(classes)) {
  274. String *mangle = NewStringf("\"%s\"", SwigType_manglestr(type));
  275. String *rep = NewStringf("\"%s\"", Getattr(classes,type));
  276. Replace(type_table,mangle,rep,DOH_REPLACE_ANY);
  277. Delete(mangle);
  278. Delete(rep);
  279. }
  280. }
  281. Printf(f_wrappers,"%s",type_table);
  282. Delete(type_table);
  283. /* Printf(stdout,"::: Perl shadow :::\n\n%s",classes); */
  284. Printf(f_init,"\t ST(0) = &PL_sv_yes;\n");
  285. Printf(f_init,"\t XSRETURN(1);\n");
  286. Printf(f_init,"}\n");
  287. Printv(vinit,tab4, "XSRETURN(1);\n", "}\n", 0);
  288. Printf(f_wrappers,"%s", vinit);
  289. Printf(f_pm,"package %s;\n", package);
  290. if (!is_static) {
  291. Printf(f_pm,"bootstrap %s;\n", realpackage);
  292. } else {
  293. String *tmp = NewString(realpackage);
  294. Replace(tmp,":","_",DOH_REPLACE_ANY);
  295. Printf(f_pm,"boot_%s();\n", tmp);
  296. Delete(tmp);
  297. }
  298. Printf(f_pm,"var_%s_init();\n", cmodule);
  299. Printf(f_pm,"%s",pragma_include);
  300. Printf(f_pm,"package %s;\n", realpackage);
  301. Printf(f_pm,"@EXPORT = qw(%s );\n",exported);
  302. if (blessed) {
  303. Printv(base,
  304. "\n# ---------- BASE METHODS -------------\n\n",
  305. "package ", realpackage, ";\n\n",
  306. 0);
  307. /* Write out the TIE method */
  308. Printv(base,
  309. "sub TIEHASH {\n",
  310. tab4, "my ($classname,$obj) = @_;\n",
  311. tab4, "return bless $obj, $classname;\n",
  312. "}\n\n",
  313. 0);
  314. /* Output a CLEAR method. This is just a place-holder, but by providing it we
  315. * can make declarations such as
  316. * %$u = ( x => 2, y=>3, z =>4 );
  317. *
  318. * Where x,y,z are the members of some C/C++ object. */
  319. Printf(base,"sub CLEAR { }\n\n");
  320. /* Output default firstkey/nextkey methods */
  321. Printf(base, "sub FIRSTKEY { }\n\n");
  322. Printf(base, "sub NEXTKEY { }\n\n");
  323. /* Output a 'this' method */
  324. Printv(base,
  325. "sub this {\n",
  326. tab4, "my $ptr = shift;\n",
  327. tab4, "return tied(%$ptr);\n",
  328. "}\n\n",
  329. 0);
  330. Printf(f_pm,"%s",base);
  331. /* Emit function stubs for stand-alone functions */
  332. Printf(f_pm,"\n# ------- FUNCTION WRAPPERS --------\n\n");
  333. Printf(f_pm,"package %s;\n\n",realpackage);
  334. Printf(f_pm,"%s",func_stubs);
  335. /* Emit package code for different classes */
  336. Printf(f_pm,"%s",pm);
  337. /* Emit variable stubs */
  338. Printf(f_pm,"\n# ------- VARIABLE STUBS --------\n\n");
  339. Printf(f_pm,"package %s;\n\n",realpackage);
  340. Printf(f_pm,"%s",var_stubs);
  341. }
  342. Printf(f_pm,"1;\n");
  343. fclose(f_pm);
  344. Delete(base);
  345. }
  346. /* -----------------------------------------------------------------------------
  347. * get_pointer()
  348. * ----------------------------------------------------------------------------- */
  349. static void
  350. get_pointer(char *iname, char *srcname, char *src, char *dest,
  351. SwigType *t, String *f, char *ret) {
  352. SwigType_remember(t);
  353. SwigType *lt = Swig_clocal_type(t);
  354. Printv(f, "if (SWIG_ConvertPtr(", src, ",(void **) &", dest, ",", 0);
  355. /* If we're passing a void pointer, we give the pointer conversion a NULL
  356. pointer, otherwise pass in the expected type. */
  357. if (Cmp(lt,"p.void") == 0) {
  358. Printf(f, " 0 ) < 0) {\n");
  359. } else {
  360. Printv(f, "SWIGTYPE", SwigType_manglestr(t), ") < 0) {\n",0);
  361. }
  362. Printv(f,
  363. "croak(\"Type error in ", srcname, " of ", iname,". Expected %s\", SWIGTYPE",
  364. SwigType_manglestr(t), "->name);\n",
  365. ret, ";\n",
  366. "}\n",
  367. 0);
  368. Delete(lt);
  369. }
  370. /* -----------------------------------------------------------------------------
  371. * PERL5::create_command()
  372. * ----------------------------------------------------------------------------- */
  373. void
  374. PERL5::create_command(String *cname, String *iname) {
  375. Printf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package, iname, Swig_name_wrapper(cname));
  376. if (export_all) {
  377. Printf(exported,"%s ",iname);
  378. }
  379. }
  380. /* -----------------------------------------------------------------------------
  381. * PERL5::create_function()
  382. * ----------------------------------------------------------------------------- */
  383. void
  384. PERL5::function(DOH *node)
  385. {
  386. char *name, *iname;
  387. SwigType *d;
  388. ParmList *l;
  389. Parm *p;
  390. int pcount,i,j;
  391. Wrapper *f;
  392. char source[256],target[256],temp[256], argnum[32];
  393. char *tm;
  394. String *cleanup, *outarg;
  395. int numopt = 0;
  396. int need_save, num_saved = 0;
  397. name = GetChar(node,"name");
  398. iname = GetChar(node,"scriptname");
  399. d = Getattr(node,"type");
  400. l = Getattr(node,"parms");
  401. f = NewWrapper();
  402. cleanup = NewString("");
  403. outarg = NewString("");
  404. Printv(f, "XS(", Swig_name_wrapper(iname), ") {\n", 0);
  405. pcount = emit_args(node, f);
  406. numopt = check_numopt(l);
  407. Wrapper_add_local(f,"argvi","int argvi = 0");
  408. /* Check the number of arguments */
  409. Printf(f," if ((items < %d) || (items > %d)) \n", pcount-numopt, ParmList_numarg(l));
  410. Printf(f," croak(\"Usage: %s\");\n", usage_func(iname,d,l));
  411. /* Write code to extract parameters. */
  412. i = 0;
  413. j = 0;
  414. for (p = l; p; p = Getnext(p)) {
  415. SwigType *pt = Gettype(p);
  416. String *pn = Getname(p);
  417. /* Produce string representation of source and target arguments */
  418. sprintf(source,"ST(%d)",j);
  419. sprintf(target,"%s", Char(Getlname(p)));
  420. sprintf(argnum,"%d",j+1);
  421. /* Check to see if this argument is being ignored */
  422. if (!Getignore(p)) {
  423. /* Check for optional argument */
  424. if (j>= (pcount-numopt))
  425. Printf(f," if (items > %d) {\n", j);
  426. if ((tm = Swig_typemap_lookup((char*)"in",pt,pn,source,target,f))) {
  427. Printf(f,"%s\n",tm);
  428. Replace(f,"$argnum",argnum,DOH_REPLACE_ANY);
  429. Replace(f,"$arg",source,DOH_REPLACE_ANY);
  430. } else {
  431. switch(SwigType_type(pt)) {
  432. case T_BOOL:
  433. case T_INT :
  434. case T_SHORT :
  435. case T_LONG :
  436. case T_SCHAR:
  437. case T_UINT:
  438. case T_USHORT:
  439. case T_ULONG:
  440. case T_UCHAR:
  441. Printf(f," %s = (%s)SvIV(ST(%d));\n", target, SwigType_lstr(pt,0),j);
  442. break;
  443. case T_CHAR :
  444. Printf(f," %s = (char) *SvPV(ST(%d),PL_na);\n", target, j);
  445. break;
  446. case T_DOUBLE :
  447. case T_FLOAT :
  448. Printf(f," %s = (%s)SvNV(ST(%d));\n", target, SwigType_lstr(pt,0), j);
  449. break;
  450. case T_VOID :
  451. break;
  452. case T_USER:
  453. SwigType_add_pointer(pt);
  454. sprintf(temp,"argument %d", i+1);
  455. get_pointer(iname, temp, source, target, pt, f, (char *)"XSRETURN(1)");
  456. SwigType_del_pointer(pt);
  457. break;
  458. case T_STRING:
  459. Printf(f," if (! SvOK((SV*) ST(%d))) { %s = 0; }\n", j, target);
  460. Printf(f," else { %s = (char *) SvPV(ST(%d),PL_na); }\n", target,j);
  461. break;
  462. case T_POINTER: case T_ARRAY: case T_REFERENCE:
  463. sprintf(temp,"argument %d", i+1);
  464. get_pointer(iname,temp,source,target, pt, f, (char*)"XSRETURN(1)");
  465. break;
  466. default :
  467. Printf(stderr,"%s:%d. Unable to use type %s as a function argument.\n",Getfile(node), Getline(node), SwigType_str(pt,0));
  468. break;
  469. }
  470. }
  471. /* The source is going to be an array of saved values. */
  472. sprintf(temp,"_saved[%d]",num_saved);
  473. if (j>= (pcount-numopt))
  474. Printf(f," } \n");
  475. j++;
  476. } else {
  477. temp[0] = 0;
  478. }
  479. /* Check if there is any constraint code */
  480. if ((tm = Swig_typemap_lookup((char*)"check",pt,pn,source,target,0))) {
  481. Printf(f,"%s\n", tm);
  482. Replace(f,"$argnum",argnum, DOH_REPLACE_ANY);
  483. }
  484. need_save = 0;
  485. if ((tm = Swig_typemap_lookup((char*)"freearg",pt,pn,target,temp,0))) {
  486. Printf(cleanup,"%s\n", tm);
  487. Replace(cleanup,"$argnum",argnum,DOH_REPLACE_ANY);
  488. Replace(cleanup,"$arg",temp,DOH_REPLACE_ANY);
  489. need_save = 1;
  490. }
  491. if ((tm = Swig_typemap_lookup((char*)"argout",pt,pn,target,(char*)"ST(argvi)",0))) {
  492. String *tempstr = NewString(tm);
  493. Replace(tempstr,"$argnum",argnum, DOH_REPLACE_ANY);
  494. Replace(tempstr,"$arg",temp, DOH_REPLACE_ANY);
  495. Printf(outarg,"%s\n", tempstr);
  496. Delete(tempstr);
  497. need_save = 1;
  498. }
  499. /* If we need a saved variable, we need to emit to emit some code for that
  500. This only applies if the argument actually existed (not ignore) */
  501. if ((need_save) && (!Getignore(p))) {
  502. Printv(f, tab4, temp, " = ", source, ";\n", 0);
  503. num_saved++;
  504. }
  505. i++;
  506. }
  507. /* If there were any saved arguments, emit a local variable for them */
  508. if (num_saved) {
  509. sprintf(temp,"_saved[%d]",num_saved);
  510. Wrapper_add_localv(f,"_saved","SV *",temp,0);
  511. }
  512. /* Now write code to make the function call */
  513. emit_func_call(node,f);
  514. if ((tm = Swig_typemap_lookup((char*)"out",d,iname,(char*)"result",(char*)"ST(argvi)",0))) {
  515. Printf(f, "%s\n", tm);
  516. } else {
  517. if (SwigType_type(d) != T_VOID) {
  518. Printf(f," ST(argvi) = sv_newmortal();\n");
  519. switch (SwigType_type(d)) {
  520. case T_INT: case T_BOOL: case T_UINT:
  521. case T_SHORT: case T_USHORT:
  522. case T_LONG : case T_ULONG:
  523. case T_SCHAR: case T_UCHAR :
  524. Printf(f," sv_setiv(ST(argvi++),(IV) result);\n");
  525. break;
  526. case T_DOUBLE :
  527. case T_FLOAT :
  528. Printf(f," sv_setnv(ST(argvi++), (double) result);\n");
  529. break;
  530. case T_CHAR :
  531. Wrapper_add_local(f,"_ctemp", "char ctemp[2]");
  532. Printv(f,
  533. tab4, "ctemp[0] = result;\n",
  534. tab4, "ctemp[1] = 0;\n",
  535. tab4, "sv_setpv((SV*)ST(argvi++),ctemp);\n",
  536. 0);
  537. break;
  538. case T_USER:
  539. SwigType_add_pointer(d);
  540. SwigType_remember(d);
  541. Printv(f,
  542. tab4, "SWIG_MakePtr(ST(argvi++), (void *) result, SWIGTYPE", SwigType_manglestr(d),");\n", 0);
  543. SwigType_del_pointer(d);
  544. break;
  545. case T_STRING:
  546. Printf(f," sv_setpv((SV*)ST(argvi++),(char *) result);\n");
  547. break;
  548. case T_POINTER: case T_ARRAY: case T_REFERENCE:
  549. SwigType_remember(d);
  550. Printv(f, tab4, "SWIG_MakePtr(ST(argvi++), (void *) result, SWIGTYPE", SwigType_manglestr(d), ");\n", 0);
  551. break;
  552. default :
  553. Printf(stderr,"%s:%d. Unable to use return type %s in function %s.\n", Getfile(node), Getline(node), SwigType_str(d,0), name);
  554. break;
  555. }
  556. }
  557. }
  558. /* If there were any output args, take care of them. */
  559. Printv(f,outarg,0);
  560. /* If there was any cleanup, do that. */
  561. Printv(f,cleanup,0);
  562. if (NewObject) {
  563. if ((tm = Swig_typemap_lookup((char*)"newfree",d,iname,(char*)"result",(char*)"",0))) {
  564. Printf(f,"%s\n",tm);
  565. }
  566. }
  567. if ((tm = Swig_typemap_lookup((char*)"ret",d,iname,(char*)"result",(char*)"",0))) {
  568. Printf(f,"%s\n", tm);
  569. }
  570. Printf(f," XSRETURN(argvi);\n}\n");
  571. /* Add the dXSARGS last */
  572. Wrapper_add_local(f,"dXSARGS","dXSARGS");
  573. /* Substitute the cleanup code */
  574. Replace(f,"$cleanup",cleanup,DOH_REPLACE_ANY);
  575. Replace(f,"$name",iname,DOH_REPLACE_ANY);
  576. /* Dump the wrapper function */
  577. Printf(f_wrappers,"%s", f);
  578. /* Now register the function */
  579. Printf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package, iname, Swig_name_wrapper(iname));
  580. if (export_all) {
  581. Printf(exported,"%s ", iname);
  582. }
  583. /* --------------------------------------------------------------------
  584. * Create a stub for this function, provided it's not a member function
  585. *
  586. * Really we only need to create a stub if this function involves
  587. * complex datatypes. If it does, we'll make a small wrapper to
  588. * process the arguments. If it doesn't, we'll just make a symbol
  589. * table entry.
  590. * -------------------------------------------------------------------- */
  591. if ((blessed) && (!member_func)) {
  592. int need_stub = 0;
  593. String *func = NewString("");
  594. /* We'll make a stub since we may need it anyways */
  595. Printv(func, "sub ", iname, " {\n",
  596. tab4, "my @args = @_;\n",
  597. 0);
  598. /* Now we have to go through and patch up the argument list. If any
  599. * arguments to our function correspond to other Perl objects, we
  600. * need to extract them from a tied-hash table object.*/
  601. Parm *p = l;
  602. int i = 0;
  603. while(p) {
  604. SwigType *pt = Gettype(p);
  605. if (!Getignore(p)) {
  606. /* Look up the datatype name here */
  607. char sourceNtarget[256];
  608. sprintf(sourceNtarget,"$args[%d]",i);
  609. if ((tm = Swig_typemap_lookup((char*)"perl5in",pt,(char*)"",sourceNtarget,sourceNtarget,0))) {
  610. Printf(func,"%s\n", tm);
  611. } else if (is_shadow(pt)) {
  612. /*
  613. if (i >= (pcount - numopt))
  614. Printf(func," if (scalar(@args) >= %d) {\n ", i);
  615. Printf(func," $args[%d] = tied(%%{$args[%d]});\n", i, i);
  616. if (i >= (pcount - numopt))
  617. Printf(func," }\n");
  618. need_stub = 1;
  619. */
  620. }
  621. i++;
  622. }
  623. p = Getnext(p);
  624. }
  625. Printv(func, tab4, "my $result = ", package, "::", iname, "(@args);\n", 0);
  626. /* Now check to see what kind of return result was found.
  627. * If this function is returning a result by 'value', SWIG did an
  628. * implicit malloc/new. We'll mark the object like it was created
  629. * in Perl so we can garbage collect it. */
  630. if ((tm = Swig_typemap_lookup((char*)"perl5out",d,(char*)"",name,(char*)"sv",0))) {
  631. Printv(func,
  632. tm, "\n",
  633. tab4, "return $result;\n",
  634. "}\n",
  635. 0);
  636. need_stub = 1;
  637. } else if (is_shadow(d)) {
  638. Printv(func, tab4, "return undef if (!defined($result));\n", 0);
  639. /* If we're returning an object by value, put it's reference
  640. into our local hash table */
  641. if ((!SwigType_ispointer(d)) || NewObject) {
  642. Printv(func, tab4, "$", is_shadow(d), "::OWNER{$result} = 1;\n", 0);
  643. }
  644. /* We're returning a Perl "object" of some kind. Turn it into a tied hash */
  645. Printv(func,
  646. tab4, "my %resulthash;\n",
  647. tab4, "tie %resulthash, ref($result), $result;\n",
  648. tab4, "return bless \\%resulthash, ref($result);\n",
  649. "}\n",
  650. 0);
  651. need_stub = 1;
  652. } else {
  653. /* Hmmm. This doesn't appear to be anything I know about */
  654. Printv(func, tab4, "return $result;\n", "}\n", 0);
  655. }
  656. /* Now check if we needed the stub. If so, emit it, otherwise
  657. * Emit code to hack Perl's symbol table instead */
  658. if (need_stub) {
  659. Printf(func_stubs,"%s",func);
  660. } else {
  661. Printv(func_stubs,"*", iname, " = *", package, "::", iname, ";\n", 0);
  662. }
  663. Delete(func);
  664. }
  665. Delete(cleanup);
  666. Delete(outarg);
  667. Delete(f);
  668. }
  669. /* -----------------------------------------------------------------------------
  670. * PERL5::link_variable()
  671. * ----------------------------------------------------------------------------- */
  672. void PERL5::variable(DOH *node) {
  673. char *name, *iname;
  674. SwigType *t;
  675. char set_name[256];
  676. char val_name[256];
  677. Wrapper *getf, *setf;
  678. char *tm;
  679. int setable = 1;
  680. name = GetChar(node,"name");
  681. iname = GetChar(node,"scriptname");
  682. t = Getattr(node,"type");
  683. sprintf(set_name,"_wrap_set_%s",iname);
  684. sprintf(val_name,"_wrap_val_%s",iname);
  685. getf = NewWrapper();
  686. setf = NewWrapper();
  687. /* Create a new scalar that we will attach magic to */
  688. Printv(vinit, tab4, "sv = perl_get_sv(\"", package, "::", iname, "\",TRUE | 0x2);\n", 0);
  689. /* Create a Perl function for setting the variable value */
  690. if (!ReadOnly) {
  691. Printf(setf,"SWIGCLASS_STATIC int %s(SV* sv, MAGIC *mg) {\n", set_name);
  692. Printv(setf,
  693. tab4, "MAGIC_PPERL\n",
  694. tab4, "mg = mg;\n",
  695. 0);
  696. /* Check for a few typemaps */
  697. if ((tm = Swig_typemap_lookup((char*)"varin",t,(char*)"",(char*)"sv",name,0))) {
  698. Printf(setf,"%s\n", tm);
  699. } else if ((tm = Swig_typemap_lookup((char*)"in",t,(char*)"",(char*)"sv",name,0))) {
  700. Printf(setf,"%s\n", tm);
  701. } else {
  702. switch(SwigType_type(t)) {
  703. case T_INT : case T_BOOL: case T_UINT:
  704. case T_SHORT : case T_USHORT:
  705. case T_LONG : case T_ULONG:
  706. case T_UCHAR: case T_SCHAR:
  707. Printv(setf,tab4, name, " = (", SwigType_str(t,0), ") SvIV(sv);\n", 0);
  708. break;
  709. case T_DOUBLE :
  710. case T_FLOAT :
  711. Printv(setf, tab4, name, " = (", SwigType_str(t,0), ") SvNV(sv);\n", 0);
  712. break;
  713. case T_CHAR :
  714. Printv(setf, tab4, name, " = (char) *SvPV(sv,PL_na);\n", 0);
  715. break;
  716. case T_USER:
  717. SwigType_add_pointer(t);
  718. Wrapper_add_local(setf,"_temp", "void *_temp");
  719. get_pointer(iname,(char*)"value",(char*)"sv",(char*)"_temp", t, setf, (char*)"return(1)");
  720. Printv(setf, tab4, name, " = *((", SwigType_str(t,0), ") _temp);\n", 0);
  721. SwigType_del_pointer(t);
  722. break;
  723. case T_STRING:
  724. Wrapper_add_local(setf,"_a","char *_a");
  725. Printf(setf," _a = (char *) SvPV(sv,PL_na);\n");
  726. if (CPlusPlus)
  727. Printv(setf,
  728. tab4, "if (", name, ") delete [] ", name, ";\n",
  729. tab4, name, " = new char[strlen(_a)+1];\n",
  730. 0);
  731. else
  732. Printv(setf,
  733. tab4, "if (", name, ") free((char*)", name, ");\n",
  734. tab4, name, " = (char *) malloc(strlen(_a)+1);\n",
  735. 0);
  736. Printv(setf,"strcpy((char*)", name, ",_a);\n", 0);
  737. break;
  738. case T_ARRAY:
  739. {
  740. SwigType *aop;
  741. SwigType *ta = Copy(t);
  742. aop = SwigType_pop(ta);
  743. if (SwigType_type(ta) == T_CHAR) {
  744. String *dim = SwigType_array_getdim(aop,0);
  745. if (dim && Len(dim)) {
  746. Printf(setf, "strncpy(%s,(char*) SvPV(sv,PL_na), %s);\n", name,dim);
  747. setable = 1;
  748. } else {
  749. setable = 0;
  750. }
  751. } else {
  752. setable = 0;
  753. }
  754. Delete(ta);
  755. Delete(aop);
  756. }
  757. break;
  758. case T_POINTER: case T_REFERENCE:
  759. Wrapper_add_local(setf,"_temp","void *_temp");
  760. get_pointer(iname,(char*)"value",(char*)"sv",(char*)"_temp", t, setf, (char*)"return(1)");
  761. Printv(setf,tab4, name, " = (", SwigType_str(t,0), ") _temp;\n", 0);
  762. break;
  763. default :
  764. Printf(stderr,"%s:%d. Unable to link with datatype %s (ignored).\n", Getfile(node), Getline(node), SwigType_str(t,0));
  765. return;
  766. }
  767. }
  768. Printf(setf," return 1;\n}\n");
  769. Replace(setf,"$name",iname, DOH_REPLACE_ANY);
  770. Printf(magic,"%s", setf);
  771. }
  772. /* Now write a function to evaluate the variable */
  773. Printf(getf,"SWIGCLASS_STATIC int %s(SV *sv, MAGIC *mg) {\n", val_name);
  774. Printv(getf,
  775. tab4, "MAGIC_PPERL\n",
  776. tab4, "mg = mg;\n",
  777. 0);
  778. if ((tm = Swig_typemap_lookup((char*)"varout",t,(char*)"",name, (char*)"sv",0))) {
  779. Printf(getf,"%s\n", tm);
  780. } else if ((tm = Swig_typemap_lookup((char*)"out",t,(char*)"",name,(char*)"sv",0))) {
  781. Printf(getf,"%s\n", tm);
  782. } else {
  783. switch(SwigType_type(t)) {
  784. case T_INT : case T_BOOL: case T_UINT:
  785. case T_SHORT : case T_USHORT:
  786. case T_LONG : case T_ULONG:
  787. case T_UCHAR: case T_SCHAR:
  788. Printv(getf,tab4, "sv_setiv(sv, (IV) ", name, ");\n", 0);
  789. Printv(vinit, tab4, "sv_setiv(sv,(IV)", name, ");\n",0);
  790. break;
  791. case T_DOUBLE :
  792. case T_FLOAT :
  793. Printv(getf, tab4,"sv_setnv(sv, (double) ", name, ");\n", 0);
  794. Printv(vinit, tab4, "sv_setnv(sv,(double)", name, ");\n",0);
  795. break;
  796. case T_CHAR :
  797. Wrapper_add_local(getf,"_ptemp","char _ptemp[2]");
  798. Printv(getf,
  799. tab4, "_ptemp[0] = ", name, ";\n",
  800. tab4, "_ptemp[1] = 0;\n",
  801. tab4, "sv_setpv((SV*) sv, _ptemp);\n",
  802. 0);
  803. break;
  804. case T_USER:
  805. SwigType_add_pointer(t);
  806. Printv(getf,
  807. tab4, "rsv = SvRV(sv);\n",
  808. tab4, "sv_setiv(rsv,(IV) &", name, ");\n",
  809. 0);
  810. Wrapper_add_local(getf,"rsv","SV *rsv");
  811. Printv(vinit, tab4, "SWIG_MakePtr(sv, (void *) &", name, ",SWIGTYPE", SwigType_manglestr(t), ");\n",0);
  812. SwigType_del_pointer(t);
  813. break;
  814. case T_STRING:
  815. Printv(getf, tab4, "sv_setpv((SV*) sv, ", name, ");\n", 0);
  816. break;
  817. case T_ARRAY:
  818. {
  819. SwigType *aop;
  820. SwigType *ta = Copy(t);
  821. aop = SwigType_pop(ta);
  822. if (SwigType_type(ta) == T_CHAR) {
  823. Printv(getf, "sv_setpv((SV*)sv, ", name, ");\n", 0);
  824. Delete(ta);
  825. Delete(aop);
  826. break;
  827. }
  828. Delete(ta);
  829. Delete(aop);
  830. }
  831. /* No break here is intentional */
  832. case T_POINTER: case T_REFERENCE:
  833. Printv(getf,
  834. tab4, "rsv = SvRV(sv);\n",
  835. tab4, "sv_setiv(rsv,(IV) ", name, ");\n",
  836. 0);
  837. Wrapper_add_local(getf,"rsv","SV *rsv");
  838. Printv(vinit, tab4, "SWIG_MakePtr(sv,(void *) 1, SWIGTYPE", SwigType_manglestr(t), ");\n",0);
  839. break;
  840. default :
  841. break;
  842. }
  843. }
  844. Printf(getf," return 1;\n}\n");
  845. Replace(getf,"$name",iname, DOH_REPLACE_ANY);
  846. Printf(magic,"%s", getf);
  847. /* Now add symbol to the PERL interpreter */
  848. if ((ReadOnly) || (!setable)) {
  849. Printv(vinit, tab4, "swig_create_magic(sv,\"", package, "::", iname, "\",MAGIC_CAST MAGIC_CLASS swig_magic_readonly, MAGIC_CAST MAGIC_CLASS ", val_name, ");\n",0);
  850. } else {
  851. Printv(vinit, tab4, "swig_create_magic(sv,\"", package, "::", iname, "\", MAGIC_CAST MAGIC_CLASS ", set_name, ", MAGIC_CAST MAGIC_CLASS ", val_name, ");\n",0);
  852. }
  853. /* If we're blessed, try to figure out what to do with the variable
  854. 1. If it's a Perl object of some sort, create a tied-hash
  855. around it.
  856. 2. Otherwise, just hack Perl's symbol table */
  857. if (blessed) {
  858. if (is_shadow(t)) {
  859. Printv(var_stubs,
  860. "\nmy %__", iname, "_hash;\n",
  861. "tie %__", iname, "_hash,\"", is_shadow(t), "\", $",
  862. package, "::", iname, ";\n",
  863. "$", iname, "= \\%__", iname, "_hash;\n",
  864. "bless $", iname, ", ", is_shadow(t), ";\n",
  865. 0);
  866. } else {
  867. Printv(var_stubs, "*", iname, " = *", package, "::", iname, ";\n", 0);
  868. }
  869. if (export_all)
  870. Printf(exported,"$%s ", name);
  871. }
  872. Delete(setf);
  873. Delete(getf);
  874. }
  875. /* -----------------------------------------------------------------------------
  876. * PERL5::constant()
  877. * ----------------------------------------------------------------------------- */
  878. /* Functions used to create constants */
  879. static const char *setiv = "#ifndef PERL_OBJECT\
  880. \n#define swig_setiv(a,b) _swig_setiv(a,b)\
  881. \nstatic void _swig_setiv(char *name, long value) { \
  882. \n#else\
  883. \n#define swig_setiv(a,b) _swig_setiv(pPerl,a,b)\
  884. \nstatic void _swig_setiv(CPerlObj *pPerl, char *name, long value) { \
  885. \n#endif\
  886. \n SV *sv; \
  887. \n sv = perl_get_sv(name,TRUE | 0x2);\
  888. \n sv_setiv(sv, (IV) value);\
  889. \n SvREADONLY_on(sv);\
  890. \n}\n";
  891. static const char *setnv = "#ifndef PERL_OBJECT\
  892. \n#define swig_setnv(a,b) _swig_setnv(a,b)\
  893. \nstatic void _swig_setnv(char *name, double value) { \
  894. \n#else\
  895. \n#define swig_setnv(a,b) _swig_setnv(pPerl,a,b)\
  896. \nstatic void _swig_setnv(CPerlObj *pPerl, char *name, double value) { \
  897. \n#endif\
  898. \n SV *sv; \
  899. \n sv = perl_get_sv(name,TRUE | 0x2);\
  900. \n sv_setnv(sv, value);\
  901. \n SvREADONLY_on(sv);\
  902. \n}\n";
  903. static const char *setpv = "#ifndef PERL_OBJECT\
  904. \n#define swig_setpv(a,b) _swig_setpv(a,b)\
  905. \nstatic void _swig_setpv(char *name, char *value) { \
  906. \n#else\
  907. \n#define swig_setpv(a,b) _swig_setpv(pPerl,a,b)\
  908. \nstatic void _swig_setpv(CPerlObj *pPerl, char *name, char *value) { \
  909. \n#endif\
  910. \n SV *sv; \
  911. \n sv = perl_get_sv(name,TRUE | 0x2);\
  912. \n sv_setpv(sv, value);\
  913. \n SvREADONLY_on(sv);\
  914. \n}\n";
  915. static const char *setrv = "#ifndef PERL_OBJECT\
  916. \n#define swig_setrv(a,b,c) _swig_setrv(a,b,c)\
  917. \nstatic void _swig_setrv(char *name, void *value, char *type) { \
  918. \n#else\
  919. \n#define swig_setrv(a,b,c) _swig_setrv(pPerl,a,b,c)\
  920. \nstatic void _swig_setrv(CPerlObj *pPerl, char *name, void *value, char *type) { \
  921. \n#endif\
  922. \n SV *sv; \
  923. \n sv = perl_get_sv(name,TRUE | 0x2);\
  924. \n sv_setref_pv(sv, type, value);\
  925. \n SvREADONLY_on(sv);\
  926. \n}\n";
  927. void
  928. PERL5::constant(DOH *node)
  929. {
  930. char *name;
  931. SwigType *type;
  932. char *value;
  933. char *tm;
  934. static int have_int_func = 0;
  935. static int have_double_func = 0;
  936. static int have_char_func = 0;
  937. static int have_ref_func = 0;
  938. name = GetChar(node,"name");
  939. type = Getattr(node,"type");
  940. value = GetChar(node,"value");
  941. if ((tm = Swig_typemap_lookup((char*)"const",type,name,value,name,0))) {
  942. Printf(f_init,"%s\n",tm);
  943. } else {
  944. switch(SwigType_type(type)) {
  945. case T_INT: case T_UINT: case T_BOOL:
  946. case T_SHORT: case T_USHORT:
  947. case T_LONG: case T_ULONG:
  948. case T_SCHAR: case T_UCHAR:
  949. if (!have_int_func) {
  950. Printf(f_header,"%s\n",setiv);
  951. have_int_func = 1;
  952. }
  953. Printv(vinit, tab4, "swig_setiv(\"", package, "::", name, "\", (long) ", value, ");\n",0);
  954. break;
  955. case T_DOUBLE:
  956. case T_FLOAT:
  957. if (!have_double_func) {
  958. Printf(f_header,"%s\n",setnv);
  959. have_double_func = 1;
  960. }
  961. Printv(vinit, tab4, "swig_setnv(\"", package, "::", name, "\", (double) (", value, "));\n",0);
  962. break;
  963. case T_CHAR :
  964. if (!have_char_func) {
  965. Printf(f_header,"%s\n",setpv);
  966. have_char_func = 1;
  967. }
  968. Printf(vinit," swig_setpv(\"%s::%s\",\"%s\");\n", package, name, value);
  969. break;
  970. case T_STRING:
  971. if (!have_char_func) {
  972. Printf(f_header,"%s\n",setpv);
  973. have_char_func = 1;
  974. }
  975. Printf(vinit," swig_setpv(\"%s::%s\",\"%s\");\n", package, name, value);
  976. break;
  977. case T_POINTER: case T_ARRAY: case T_REFERENCE:
  978. if (!have_ref_func) {
  979. Printf(f_header,"%s\n",setrv);
  980. have_ref_func = 1;
  981. }
  982. Printv(vinit, tab4, "swig_setrv(\"", package, "::", name, "\", (void *) ", value, ", \"",
  983. SwigType_manglestr(type), "\");\n", 0);
  984. break;
  985. default:
  986. Printf(stderr,"%s:%d. Unsupported constant value.\n", Getfile(node), Getline(node));
  987. break;
  988. }
  989. }
  990. if (blessed) {
  991. if (is_shadow(type)) {
  992. Printv(var_stubs,
  993. "\nmy %__", name, "_hash;\n",
  994. "tie %__", name, "_hash,\"", is_shadow(type), "\", $",
  995. package, "::", name, ";\n",
  996. "$", name, "= \\%__", name, "_hash;\n",
  997. "bless $", name, ", ", is_shadow(type), ";\n",
  998. 0);
  999. } else {
  1000. Printv(var_stubs, "*",name," = *", package, "::", name, ";\n", 0);
  1001. }
  1002. }
  1003. if (export_all)
  1004. Printf(exported,"$%s ",name);
  1005. }
  1006. /* -----------------------------------------------------------------------------
  1007. * PERL5::usage_func()
  1008. * ----------------------------------------------------------------------------- */
  1009. char *
  1010. PERL5::usage_func(char *iname, SwigType *, ParmList *l) {
  1011. static String *temp = 0;
  1012. Parm *p;
  1013. int i;
  1014. if (!temp) temp = NewString("");
  1015. Clear(temp);
  1016. Printf(temp,"%s(",iname);
  1017. /* Now go through and print parameters */
  1018. p = l;
  1019. i = 0;
  1020. while (p != 0) {
  1021. SwigType *pt = Gettype(p);
  1022. String *pn = Getname(p);
  1023. if (!Getignore(p)) {
  1024. /* If parameter has been named, use that. Otherwise, just print a type */
  1025. if (SwigType_type(pt) != T_VOID) {
  1026. if (Len(pn) > 0) {
  1027. Printf(temp,"%s",pn);
  1028. } else {
  1029. Printf(temp,"%s",SwigType_str(pt,0));
  1030. }
  1031. }
  1032. i++;
  1033. p = Getnext(p);
  1034. if (p)
  1035. if (!Getignore(p))
  1036. Putc(',',temp);
  1037. } else {
  1038. p = Getnext(p);
  1039. if (p)
  1040. if ((i>0) && (!Getignore(p)))
  1041. Putc(',',temp);
  1042. }
  1043. }
  1044. Printf(temp,");");
  1045. return Char(temp);
  1046. }
  1047. /* -----------------------------------------------------------------------------
  1048. * PERL5::nativefunction()
  1049. * ----------------------------------------------------------------------------- */
  1050. void
  1051. PERL5::nativefunction(DOH *node) {
  1052. char *name, *funcname;
  1053. name = GetChar(node,"scriptname");
  1054. funcname = GetChar(node,"name");
  1055. Printf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package,name, funcname);
  1056. if (export_all)
  1057. Printf(exported,"%s ",name);
  1058. if (blessed) {
  1059. Printv(func_stubs,"*", name, " = *", package, "::", name, ";\n", 0);
  1060. }
  1061. }
  1062. /****************************************************************************
  1063. *** OBJECT-ORIENTED FEATURES
  1064. ****************************************************************************
  1065. *** These extensions provide a more object-oriented interface to C++
  1066. *** classes and structures. The code here is based on extensions
  1067. *** provided by David Fletcher and Gary Holt.
  1068. ***
  1069. *** I have generalized these extensions to make them more general purpose
  1070. *** and to resolve object-ownership problems.
  1071. ***
  1072. *** The approach here is very similar to the Python module :
  1073. *** 1. All of the original methods are placed into a single
  1074. *** package like before except that a 'c' is appended to the
  1075. *** package name.
  1076. ***
  1077. *** 2. All methods and function calls are wrapped with a new
  1078. *** perl function. While possibly inefficient this allows
  1079. *** us to catch complex function arguments (which are hard to
  1080. *** track otherwise).
  1081. ***
  1082. *** 3. Classes are represented as tied-hashes in a manner similar
  1083. *** to Gary Holt's extension. This allows us to access
  1084. *** member data.
  1085. ***
  1086. *** 4. Stand-alone (global) C functions are modified to take
  1087. *** tied hashes as arguments for complex datatypes (if
  1088. *** appropriate).
  1089. ***
  1090. *** 5. Global variables involving a class/struct is encapsulated
  1091. *** in a tied hash.
  1092. ***
  1093. *** 6. Object ownership is maintained by having a hash table
  1094. *** within in each package called "this". It is unlikely
  1095. *** that C++ program will use this so it's a somewhat
  1096. *** safe variable name.
  1097. ***
  1098. ****************************************************************************/
  1099. /* -----------------------------------------------------------------------------
  1100. * PERL5::cpp_open_class()
  1101. * ----------------------------------------------------------------------------- */
  1102. void
  1103. PERL5::cpp_open_class(DOH *node) {
  1104. this->Language::cpp_open_class(node);
  1105. char *classname = GetChar(node,"name");
  1106. char *rname = GetChar(node,"scriptname");
  1107. char *ctype = GetChar(node,"classtype");
  1108. if (blessed) {
  1109. have_constructor = 0;
  1110. have_destructor = 0;
  1111. have_data_members = 0;
  1112. Delete(class_name); class_name = 0;
  1113. Delete(class_type); class_type =0;
  1114. Delete(real_classname); real_classname = 0;
  1115. Delete(base_class); base_class = 0;
  1116. Delete(fullclassname); fullclassname = 0;
  1117. /* If the class is being renamed to something else, use the renaming */
  1118. if (rname) {
  1119. class_name = NewString(rname);
  1120. class_renamed = 1;
  1121. } else {
  1122. class_name = NewString(classname);
  1123. class_renamed = 0;
  1124. }
  1125. /* Use the fully qualified name of the Perl class */
  1126. if (!compat) {
  1127. fullclassname = NewStringf("%s::%s",realpackage,class_name);
  1128. } else {
  1129. fullclassname = NewString(class_name);
  1130. }
  1131. real_classname = NewString(classname);
  1132. if (base_class) Delete(base_class);
  1133. base_class = 0;
  1134. class_type = NewString(ctype);
  1135. pcode = NewString("");
  1136. blessedmembers = NewString("");
  1137. member_keys = NewString("");
  1138. /* Add some symbols to the hash tables */
  1139. Hash *nnode = NewHash();
  1140. Setattr(nnode,"name", classname);
  1141. Setattr(nnode,"scriptname", fullclassname);
  1142. Setattr(nnode,"classtype", ctype);
  1143. cpp_class_decl(nnode);
  1144. }
  1145. }
  1146. /* -----------------------------------------------------------------------------
  1147. * PERL5::cpp_close_class()
  1148. * ----------------------------------------------------------------------------- */
  1149. void
  1150. PERL5::cpp_close_class() {
  1151. if (blessed) {
  1152. Printv(pm,
  1153. "\n############# Class : ", fullclassname, " ##############\n",
  1154. "\npackage ", fullclassname, ";\n",
  1155. 0);
  1156. /* If we are inheriting from a base class, set that up */
  1157. if (Cmp(class_name,realpackage))
  1158. Printv(pm, "@ISA = qw( ",realpackage, 0);
  1159. else
  1160. Printv(pm, "@ISA = qw( ", 0);
  1161. if (base_class) {
  1162. Printv(pm, " ", base_class, 0);
  1163. }
  1164. Printf(pm, " );\n");
  1165. /* Dump out a hash table containing the pointers that we own */
  1166. Printf(pm, "%%OWNER = ();\n");
  1167. if (have_data_members) {
  1168. Printv(pm,
  1169. "%BLESSEDMEMBERS = (\n", blessedmembers, ");\n\n",
  1170. 0);
  1171. }
  1172. if (have_data_members || have_destructor)
  1173. Printf(pm, "%%ITERATORS = ();\n");
  1174. /* Dump out the package methods */
  1175. Printv(pm,pcode,0);
  1176. Delete(pcode);
  1177. /* Output methods for managing ownership */
  1178. Printv(pm,
  1179. "sub DISOWN {\n",
  1180. tab4, "my $self = shift;\n",
  1181. tab4, "my $ptr = tied(%$self);\n",
  1182. tab4, "delete $OWNER{$ptr};\n",
  1183. tab4, "};\n\n",
  1184. "sub ACQUIRE {\n",
  1185. tab4, "my $self = shift;\n",
  1186. tab4, "my $ptr = tied(%$self);\n",
  1187. tab4, "$OWNER{$ptr} = 1;\n",
  1188. tab4, "};\n\n",
  1189. 0);
  1190. /* Only output the following methods if a class has member data */
  1191. if (have_data_members) {
  1192. /* Output a FETCH method. This is actually common to all classes */
  1193. Printv(pm,
  1194. "sub FETCH {\n",
  1195. tab4, "my ($self,$field) = @_;\n",
  1196. tab4, "my $member_func = \"", package, "::", Swig_name_get(Swig_name_member(class_name,(char*)"${field}")), "\";\n",
  1197. tab4, "my $val = &$member_func($self);\n",
  1198. tab4, "if (exists $BLESSEDMEMBERS{$field}) {\n",
  1199. tab8, "return undef if (!defined($val));\n",
  1200. tab8, "my %retval;\n",
  1201. tab8, "tie %retval,$BLESSEDMEMBERS{$field},$val;\n",
  1202. tab8, "return bless \\%retval, $BLESSEDMEMBERS{$field};\n",
  1203. tab4, "}\n",
  1204. tab4, "return $val;\n",
  1205. "}\n\n",
  1206. 0);
  1207. /* Output a STORE method. This is also common to all classes (might move to base class) */
  1208. Printv(pm,
  1209. "sub STORE {\n",
  1210. tab4, "my ($self,$field,$newval) = @_;\n",
  1211. tab4, "my $member_func = \"", package, "::", Swig_name_set(Swig_name_member(class_name,(char*)"${field}")), "\";\n",
  1212. tab4, "if (exists $BLESSEDMEMBERS{$field}) {\n",
  1213. tab8, "&$member_func($self,tied(%{$newval}));\n",
  1214. tab4, "} else {\n",
  1215. tab8, "&$member_func($self,$newval);\n",
  1216. tab4, "}\n",
  1217. "}\n\n",
  1218. 0);
  1219. /* Output a FIRSTKEY method. This is to allow iteration over a structure's keys. */
  1220. Printv(pm,
  1221. "sub FIRSTKEY {\n",
  1222. tab4, "my $self = shift;\n",
  1223. tab4, "$ITERATORS{$self} = [", member_keys, "];\n",
  1224. tab4, "my $first = shift @{$ITERATORS{$self}};\n",
  1225. tab4, "return $first;\n",
  1226. "}\n\n",
  1227. 0);
  1228. /* Output a NEXTKEY method. This is the iterator so that each and keys works */
  1229. Printv(pm,
  1230. "sub NEXTKEY {\n",
  1231. tab4, "my $self = shift;\n",
  1232. tab4, "$nelem = scalar @{$ITERATORS{$self}};\n",
  1233. tab4, "if ($nelem > 0) {\n",
  1234. tab8, "my $member = shift @{$ITERATORS{$self}};\n",
  1235. tab8, "return $member;\n",
  1236. tab4, "} else {\n",
  1237. tab8, "$ITERATORS{$self} = [", member_keys, "];\n",
  1238. tab8, "return ();\n",
  1239. tab4, "}\n",
  1240. "}\n\n",
  1241. 0);
  1242. }
  1243. }
  1244. }
  1245. /* -----------------------------------------------------------------------------
  1246. * PERL5::cpp_member_func()
  1247. * ----------------------------------------------------------------------------- */
  1248. void
  1249. PERL5::cpp_memberfunction(DOH *node) {
  1250. char *name, *iname;
  1251. SwigType *t;
  1252. ParmList *l;
  1253. String *func;
  1254. char *realname;
  1255. Parm *p;
  1256. int i;
  1257. String *cname;
  1258. int pcount, numopt;
  1259. char *tm;
  1260. int need_wrapper = 0;
  1261. member_func = 1;
  1262. this->Language::cpp_memberfunction(node);
  1263. member_func = 0;
  1264. if (!blessed) return;
  1265. name = GetChar(node,"name");
  1266. iname = GetChar(node,"scriptname");
  1267. t = Getattr(node,"type");
  1268. l = Getattr(node,"parms");
  1269. func = NewString("");
  1270. cname = NewString("perl5:");
  1271. /* Now emit a Perl wrapper function around our member function, we might need
  1272. to patch up some arguments along the way */
  1273. if (!iname)
  1274. realname = name;
  1275. else
  1276. realname = iname;
  1277. Printf(cname,"%s::%s",class_name,realname);
  1278. if (Getattr(symbols,cname)) {
  1279. return; /* Forget it, we saw this already */
  1280. }
  1281. Setattr(symbols,cname,cname);
  1282. Printv(func,
  1283. "sub ", realname, " {\n",
  1284. tab4, "my @args = @_;\n",
  1285. 0);
  1286. /* Now we have to go through and patch up the argument list. If any
  1287. arguments to our function correspond to other Perl objects, we
  1288. need to extract them from a tied-hash table object. */
  1289. p = l;
  1290. pcount = ParmList_len(l);
  1291. numopt = check_numopt(l);
  1292. i = 1;
  1293. while(p) {
  1294. SwigType *pt = Gettype(p);
  1295. if (!Getignore(p)) {
  1296. char sourceNtarget[512];
  1297. sprintf(sourceNtarget, "$args[%d]", i);
  1298. if ((tm = Swig_typemap_lookup((char*)"perl5in",pt,(char*)"",sourceNtarget,sourceNtarget,0))) {
  1299. Printf(func,"%s\n",tm);
  1300. need_wrapper = 1;
  1301. }
  1302. i++;
  1303. }
  1304. p = Getnext(p);
  1305. }
  1306. /* Okay. We've made argument adjustments, now call into the package */
  1307. Printv(func,
  1308. tab4, "my $result = ", package, "::", Swig_name_member(class_name,realname),
  1309. "(@args);\n",
  1310. 0);
  1311. /* Now check to see what kind of return result was found.
  1312. * If this function is returning a result by 'value', SWIG did an
  1313. * implicit malloc/new. We'll mark the object like it was created
  1314. * in Perl so we can garbage collect it. */
  1315. if ((tm = Swig_typemap_lookup((char*)"perl5out",t,(char*)"",name,(char*)"sv",0))) {
  1316. Printv(func,
  1317. tm, "\n",
  1318. tab4,"return $result;\n",
  1319. "}\n",
  1320. 0);
  1321. need_wrapper = 1;
  1322. } else if (is_shadow(t)) {
  1323. Printv(func,tab4, "return undef if (!defined($result));\n", 0);
  1324. /* If we're returning an object by value, put it's reference
  1325. into our local hash table */
  1326. if (!SwigType_ispointer(t) || NewObject) {
  1327. Printv(func, tab4, "$", is_shadow(t), "::OWNER{$result} = 1; \n", 0);
  1328. }
  1329. /* We're returning a Perl "object" of some kind. Turn it into
  1330. a tied hash */
  1331. Printv(func,
  1332. tab4, "my %resulthash;\n",
  1333. tab4, "tie %resulthash, ref($result), $result;\n",
  1334. tab4, "return bless \\%resulthash, ref($result);\n",
  1335. "}\n",
  1336. 0);
  1337. need_wrapper = 1;
  1338. } else {
  1339. /* Hmmm. This doesn't appear to be anything I know about so just
  1340. return it unmodified */
  1341. Printv(func, tab4,"return $result;\n", "}\n", 0);
  1342. }
  1343. if (need_wrapper) {
  1344. Printv(pcode,func,0);
  1345. } else {
  1346. Printv(pcode,"*",realname," = *", package, "::", Swig_name_member(class_name,realname), ";\n", 0);
  1347. }
  1348. Delete(func);
  1349. Delete(cname);
  1350. }
  1351. /* -----------------------------------------------------------------------------
  1352. * PERL5::cpp_variable()
  1353. *
  1354. * Adds an instance member. This is a little hairy because data members are
  1355. * really added with a tied-hash table that is attached to the object.
  1356. *
  1357. * On the low level, we will emit a pair of get/set functions to retrieve
  1358. * values just like before. These will then be encapsulated in a FETCH/STORE
  1359. * method associated with the tied-hash.
  1360. *
  1361. * In the event that a member is an object that we have already wrapped, then
  1362. * we need to retrieve the data a tied-hash as opposed to what SWIG normally
  1363. * returns. To determine this, we build an internal hash called 'BLESSEDMEMBERS'
  1364. * that contains the names and types of tied data members. If a member name
  1365. * is in the list, we tie it, otherwise, we just return the normal SWIG value.
  1366. * ----------------------------------------------------------------------------- */
  1367. void PERL5::cpp_variable(DOH *node) {
  1368. char *name, *iname;
  1369. SwigType *t;
  1370. char *realname;
  1371. String *cname;
  1372. cname = NewString("perl5:");
  1373. /* Emit a pair of get/set functions for the variable */
  1374. member_func = 1;
  1375. this->Language::cpp_variable(node);
  1376. member_func = 0;
  1377. if (blessed) {
  1378. name = GetChar(node,"name");
  1379. iname = GetChar(node,"scriptname");
  1380. t = Getattr(node,"type");
  1381. if (iname) realname = iname;
  1382. else realname = name;
  1383. Printf(cname,"%s::%s", class_name, realname);
  1384. if (Getattr(symbols,cname)) {
  1385. Delete(cname);
  1386. return;
  1387. }
  1388. Setattr(symbols,cname,cname);
  1389. /* Store name of key for future reference */
  1390. Printf(member_keys,"'%s', ", realname);
  1391. /* Now we need to generate a little Perl code for this */
  1392. if (is_shadow(t)) {
  1393. /* This is a Perl object that we have already seen. Add an
  1394. entry to the members list*/
  1395. Printv(blessedmembers,
  1396. tab4, realname, " => '", is_shadow(t), "',\n",
  1397. 0);
  1398. }
  1399. }
  1400. have_data_members++;
  1401. Delete(cname);
  1402. }
  1403. /* -----------------------------------------------------------------------------
  1404. * PERL5::cpp_constructor()
  1405. *
  1406. * Emits a blessed constructor for our class. In addition to our construct
  1407. * we manage a Perl hash table containing all of the pointers created by
  1408. * the constructor. This prevents us from accidentally trying to free
  1409. * something that wasn't necessarily allocated by malloc or new
  1410. * ----------------------------------------------------------------------------- */
  1411. void
  1412. PERL5::cpp_constructor(DOH *node) {
  1413. char *name, *iname;
  1414. ParmList *l;
  1415. Parm *p;
  1416. int i;
  1417. String *realname;
  1418. String *cname;
  1419. cname = NewString("perl5:constructor:");
  1420. /* Emit an old-style constructor for this class */
  1421. member_func = 1;
  1422. this->Language::cpp_constructor(node);
  1423. if (blessed) {
  1424. name = GetChar(node,"name");
  1425. iname = GetChar(node,"scriptname")

Large files files are truncated, but you can click here to view the full file