PageRenderTime 66ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/tags/mkoeppe-1-3-mzscheme/SWIG/Source/Modules1.1/perl5.cxx

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

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