/tags/rel-1-3-24/SWIG/Source/Modules/mzscheme.cxx

# · C++ · 816 lines · 555 code · 146 blank · 115 comment · 164 complexity · bde5ec2f0574dae91adbbf73ef0cb321 MD5 · raw file

  1. /******************************************************************************
  2. * Simplified Wrapper and Interface Generator (SWIG)
  3. *
  4. * Author : David Beazley
  5. *
  6. * Department of Computer Science
  7. * University of Chicago
  8. * 1100 E 58th Street
  9. * Chicago, IL 60637
  10. * beazley@cs.uchicago.edu
  11. *
  12. * Please read the file LICENSE for the copyright and terms by which SWIG
  13. * can be used and distributed.
  14. *****************************************************************************/
  15. char cvsroot_mzscheme_cxx[] = "$Header$";
  16. /***********************************************************************
  17. * $Header$
  18. *
  19. * mzscheme.cxx
  20. *
  21. * Definitions for adding functions to Mzscheme 101
  22. ***********************************************************************/
  23. #include "swigmod.h"
  24. #include <ctype.h>
  25. static const char *usage = (char*)"\
  26. Mzscheme Options (available with -mzscheme)\n\
  27. -prefix <name> - Set a prefix <name> to be prepended to all names\n\
  28. -declaremodule - Create extension that declares a module\n\
  29. -noinit - Do not emit scheme_initialize, scheme_reload,\n\
  30. scheme_module_name functions\n";
  31. static String *fieldnames_tab = 0;
  32. static String *convert_tab = 0;
  33. static String *convert_proto_tab = 0;
  34. static String *struct_name = 0;
  35. static String *mangled_struct_name = 0;
  36. static char *prefix=0;
  37. static bool declaremodule = false;
  38. static bool noinit = false;
  39. static String *module=0;
  40. static char *mzscheme_path=(char*)"mzscheme";
  41. static String *init_func_def = 0;
  42. static File *f_runtime = 0;
  43. static File *f_header = 0;
  44. static File *f_wrappers = 0;
  45. static File *f_init = 0;
  46. // Used for garbage collection
  47. static int exporting_destructor = 0;
  48. static String *swigtype_ptr = 0;
  49. static String *cls_swigtype = 0;
  50. class MZSCHEME : public Language {
  51. public:
  52. /* ------------------------------------------------------------
  53. * main()
  54. * ------------------------------------------------------------ */
  55. virtual void main (int argc, char *argv[]) {
  56. int i;
  57. SWIG_library_directory(mzscheme_path);
  58. // Look for certain command line options
  59. for (i = 1; i < argc; i++) {
  60. if (argv[i]) {
  61. if (strcmp (argv[i], "-help") == 0) {
  62. fputs (usage, stderr);
  63. SWIG_exit (0);
  64. } else if (strcmp (argv[i], "-prefix") == 0) {
  65. if (argv[i + 1]) {
  66. prefix = new char[strlen(argv[i + 1]) + 2];
  67. strcpy(prefix, argv[i + 1]);
  68. Swig_mark_arg (i);
  69. Swig_mark_arg (i + 1);
  70. i++;
  71. } else {
  72. Swig_arg_error();
  73. }
  74. } else if (strcmp (argv[i], "-declaremodule") == 0) {
  75. declaremodule = true;
  76. Swig_mark_arg (i);
  77. } else if (strcmp (argv[i], "-noinit") == 0) {
  78. noinit = true;
  79. Swig_mark_arg (i);
  80. }
  81. }
  82. }
  83. // If a prefix has been specified make sure it ends in a '_'
  84. if (prefix) {
  85. if (prefix[strlen (prefix)] != '_') {
  86. prefix[strlen (prefix) + 1] = 0;
  87. prefix[strlen (prefix)] = '_';
  88. }
  89. } else
  90. prefix = (char*)"swig_";
  91. // Add a symbol for this module
  92. Preprocessor_define ("SWIGMZSCHEME 1",0);
  93. // Set name of typemaps
  94. SWIG_typemap_lang("mzscheme");
  95. // Read in default typemaps */
  96. SWIG_config_file("mzscheme.swg");
  97. allow_overloading();
  98. }
  99. /* ------------------------------------------------------------
  100. * top()
  101. * ------------------------------------------------------------ */
  102. virtual int top(Node *n) {
  103. /* Initialize all of the output files */
  104. String *outfile = Getattr(n,"outfile");
  105. f_runtime = NewFile(outfile,"w");
  106. if (!f_runtime) {
  107. Printf(stderr,"*** Can't open '%s'\n", outfile);
  108. SWIG_exit(EXIT_FAILURE);
  109. }
  110. f_init = NewString("");
  111. f_header = NewString("");
  112. f_wrappers = NewString("");
  113. /* Register file targets with the SWIG file handler */
  114. Swig_register_filebyname("header",f_header);
  115. Swig_register_filebyname("wrapper",f_wrappers);
  116. Swig_register_filebyname("runtime",f_runtime);
  117. init_func_def = NewString("");
  118. Swig_register_filebyname("init",init_func_def);
  119. Printf(f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n");
  120. Swig_banner (f_runtime);
  121. module = Getattr(n,"name");
  122. Language::top(n);
  123. SwigType_emit_type_table (f_runtime, f_wrappers);
  124. if (!noinit) {
  125. Printf(f_init, "Scheme_Object *scheme_reload(Scheme_Env *env) {\n");
  126. if (declaremodule) {
  127. Printf(f_init, "\tScheme_Env *menv = scheme_primitive_module(scheme_intern_symbol(\"%s\"), env);\n", module);
  128. }
  129. else {
  130. Printf(f_init, "\tScheme_Env *menv = env;\n");
  131. }
  132. Printf(f_init, "%s\n", Char(init_func_def));
  133. if (declaremodule) {
  134. Printf(f_init, "\tscheme_finish_primitive_module(menv);\n");
  135. }
  136. Printf (f_init, "\treturn scheme_void;\n}\n");
  137. Printf(f_init, "Scheme_Object *scheme_initialize(Scheme_Env *env) {\n");
  138. Printf(f_init, "\treturn scheme_reload(env);\n");
  139. Printf (f_init, "}\n");
  140. Printf(f_init,"Scheme_Object *scheme_module_name(void) {\n");
  141. if (declaremodule) {
  142. Printf(f_init, " return scheme_intern_symbol((char*)\"%s\");\n", module);
  143. }
  144. else {
  145. Printf(f_init," return scheme_make_symbol((char*)\"%s\");\n", module);
  146. }
  147. Printf(f_init,"}\n");
  148. }
  149. /* Close all of the files */
  150. Dump(f_header,f_runtime);
  151. Dump(f_wrappers,f_runtime);
  152. Wrapper_pretty_print(f_init,f_runtime);
  153. Delete(f_header);
  154. Delete(f_wrappers);
  155. Delete(f_init);
  156. Close(f_runtime);
  157. Delete(f_runtime);
  158. return SWIG_OK;
  159. }
  160. /* ------------------------------------------------------------
  161. * functionWrapper()
  162. * Create a function declaration and register it with the interpreter.
  163. * ------------------------------------------------------------ */
  164. void throw_unhandled_mzscheme_type_error (SwigType *d)
  165. {
  166. Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number,
  167. "Unable to handle type %s.\n", SwigType_str(d,0));
  168. }
  169. /* Return true iff T is a pointer type */
  170. int
  171. is_a_pointer (SwigType *t)
  172. {
  173. return SwigType_ispointer(SwigType_typedef_resolve_all(t));
  174. }
  175. virtual int functionWrapper(Node *n) {
  176. char *iname = GetChar(n,"sym:name");
  177. SwigType *d = Getattr(n,"type");
  178. ParmList *l = Getattr(n,"parms");
  179. Parm *p;
  180. Wrapper *f = NewWrapper();
  181. String *proc_name = NewString("");
  182. String *source = NewString("");
  183. String *target = NewString("");
  184. String *arg = NewString("");
  185. String *cleanup = NewString("");
  186. String *outarg = NewString("");
  187. String *build = NewString("");
  188. String *tm;
  189. int argout_set = 0;
  190. int i = 0;
  191. int numargs;
  192. int numreq;
  193. String *overname = 0;
  194. // Make a wrapper name for this
  195. String *wname = Swig_name_wrapper(iname);
  196. if (Getattr(n,"sym:overloaded")) {
  197. overname = Getattr(n,"sym:overname");
  198. } else {
  199. if (!addSymbol(iname,n)) return SWIG_ERROR;
  200. }
  201. if (overname) {
  202. Append(wname, overname);
  203. }
  204. Setattr(n,"wrap:name",wname);
  205. // Build the name for Scheme.
  206. Printv(proc_name, iname,NIL);
  207. Replaceall(proc_name, "_", "-");
  208. // writing the function wrapper function
  209. Printv(f->def, "static Scheme_Object *", wname, " (", NIL);
  210. Printv(f->def, "int argc, Scheme_Object **argv", NIL);
  211. Printv(f->def, ")\n{", NIL);
  212. /* Define the scheme name in C. This define is used by several
  213. macros. */
  214. Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
  215. // Declare return variable and arguments
  216. // number of parameters
  217. // they are called arg0, arg1, ...
  218. // the return value is called result
  219. emit_args(d, l, f);
  220. /* Attach the standard typemaps */
  221. emit_attach_parmmaps(l,f);
  222. Setattr(n,"wrap:parms",l);
  223. numargs = emit_num_arguments(l);
  224. numreq = emit_num_required(l);
  225. // adds local variables
  226. Wrapper_add_local(f, "lenv", "int lenv = 1");
  227. Wrapper_add_local(f, "values", "Scheme_Object *values[MAXVALUES]");
  228. // Now write code to extract the parameters (this is super ugly)
  229. for (i = 0, p = l; i < numargs; i++) {
  230. /* Skip ignored arguments */
  231. while (checkAttribute(p,"tmap:in:numinputs","0")) {
  232. p = Getattr(p,"tmap:in:next");
  233. }
  234. SwigType *pt = Getattr(p,"type");
  235. String *ln = Getattr(p,"lname");
  236. // Produce names of source and target
  237. Clear(source);
  238. Clear(target);
  239. Clear(arg);
  240. Printf(source, "argv[%d]", i);
  241. Printf(target, "%s",ln);
  242. Printv(arg, Getattr(p,"name"),NIL);
  243. if (i >= numreq) {
  244. Printf(f->code,"if (argc > %d) {\n",i);
  245. }
  246. // Handle parameter types.
  247. if ((tm = Getattr(p,"tmap:in"))) {
  248. Replaceall(tm,"$source",source);
  249. Replaceall(tm,"$target",target);
  250. Replaceall(tm,"$input",source);
  251. Setattr(p,"emit:input",source);
  252. Printv(f->code, tm, "\n", NIL);
  253. p = Getattr(p,"tmap:in:next");
  254. } else {
  255. // no typemap found
  256. // check if typedef and resolve
  257. throw_unhandled_mzscheme_type_error (pt);
  258. p = nextSibling(p);
  259. }
  260. if (i >= numreq) {
  261. Printf(f->code,"}\n");
  262. }
  263. }
  264. /* Insert constraint checking code */
  265. for (p = l; p;) {
  266. if ((tm = Getattr(p,"tmap:check"))) {
  267. Replaceall(tm,"$target",Getattr(p,"lname"));
  268. Printv(f->code,tm,"\n",NIL);
  269. p = Getattr(p,"tmap:check:next");
  270. } else {
  271. p = nextSibling(p);
  272. }
  273. }
  274. // Pass output arguments back to the caller.
  275. for (p = l; p;) {
  276. if ((tm = Getattr(p,"tmap:argout"))) {
  277. Replaceall(tm,"$source",Getattr(p,"emit:input")); /* Deprecated */
  278. Replaceall(tm,"$target",Getattr(p,"lname")); /* Deprecated */
  279. Replaceall(tm,"$arg",Getattr(p,"emit:input"));
  280. Replaceall(tm,"$input",Getattr(p,"emit:input"));
  281. Printv(outarg,tm,"\n",NIL);
  282. p = Getattr(p,"tmap:argout:next");
  283. argout_set = 1;
  284. } else {
  285. p = nextSibling(p);
  286. }
  287. }
  288. // Free up any memory allocated for the arguments.
  289. /* Insert cleanup code */
  290. for (p = l; p;) {
  291. if ((tm = Getattr(p,"tmap:freearg"))) {
  292. Replaceall(tm,"$target",Getattr(p,"lname"));
  293. Printv(cleanup,tm,"\n",NIL);
  294. p = Getattr(p,"tmap:freearg:next");
  295. } else {
  296. p = nextSibling(p);
  297. }
  298. }
  299. // Now write code to make the function call
  300. emit_action(n,f);
  301. // Now have return value, figure out what to do with it.
  302. if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) {
  303. Replaceall(tm,"$source","result");
  304. Replaceall(tm,"$target","values[0]");
  305. Replaceall(tm,"$result","values[0]");
  306. if (Getattr(n, "feature:new"))
  307. Replaceall(tm, "$owner", "1");
  308. else
  309. Replaceall(tm, "$owner", "0");
  310. Printv(f->code, tm, "\n",NIL);
  311. } else {
  312. throw_unhandled_mzscheme_type_error (d);
  313. }
  314. // Dump the argument output code
  315. Printv(f->code, Char(outarg),NIL);
  316. // Dump the argument cleanup code
  317. Printv(f->code, Char(cleanup),NIL);
  318. // Look for any remaining cleanup
  319. if (Getattr(n,"feature:new")) {
  320. if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) {
  321. Replaceall(tm,"$source","result");
  322. Printv(f->code, tm, "\n",NIL);
  323. }
  324. }
  325. // Free any memory allocated by the function being wrapped..
  326. if ((tm = Swig_typemap_lookup_new("ret",n,"result",0))) {
  327. Replaceall(tm,"$source","result");
  328. Printv(f->code, tm, "\n",NIL);
  329. }
  330. // Wrap things up (in a manner of speaking)
  331. Printv(f->code, tab4, "return SWIG_MzScheme_PackageValues(lenv, values);\n", NIL);
  332. Printf(f->code, "#undef FUNC_NAME\n");
  333. Printv(f->code, "}\n",NIL);
  334. Wrapper_print(f, f_wrappers);
  335. if (!Getattr(n,"sym:overloaded")) {
  336. // Now register the function
  337. char temp[256];
  338. sprintf(temp, "%d", numargs);
  339. if (exporting_destructor) {
  340. Printf(init_func_def, "SWIG_TypeClientData(SWIGTYPE%s, (void *) %s);\n", swigtype_ptr, wname);
  341. } else {
  342. Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n",
  343. proc_name, wname, proc_name, numreq, numargs);
  344. }
  345. } else {
  346. if (!Getattr(n,"sym:nextSibling")) {
  347. /* Emit overloading dispatch function */
  348. int maxargs;
  349. String *dispatch = Swig_overload_dispatch(n,"return %s(argc,argv);",&maxargs);
  350. /* Generate a dispatch wrapper for all overloaded functions */
  351. Wrapper *df = NewWrapper();
  352. String *dname = Swig_name_wrapper(iname);
  353. Printv(df->def,
  354. "static Scheme_Object *\n", dname,
  355. "(int argc, Scheme_Object **argv) {",
  356. NIL);
  357. Printv(df->code,dispatch,"\n",NIL);
  358. Printf(df->code,"scheme_signal_error(\"No matching function for overloaded '%s'\");\n", iname);
  359. Printv(df->code,"}\n",NIL);
  360. Wrapper_print(df,f_wrappers);
  361. Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n",
  362. proc_name, dname, proc_name, 0, maxargs);
  363. DelWrapper(df);
  364. Delete(dispatch);
  365. Delete(dname);
  366. }
  367. }
  368. Delete(proc_name);
  369. Delete(source);
  370. Delete(target);
  371. Delete(arg);
  372. Delete(outarg);
  373. Delete(cleanup);
  374. Delete(build);
  375. DelWrapper(f);
  376. return SWIG_OK;
  377. }
  378. /* ------------------------------------------------------------
  379. * variableWrapper()
  380. *
  381. * Create a link to a C variable.
  382. * This creates a single function _wrap_swig_var_varname().
  383. * This function takes a single optional argument. If supplied, it means
  384. * we are setting this variable to some value. If omitted, it means we are
  385. * simply evaluating this variable. Either way, we return the variables
  386. * value.
  387. * ------------------------------------------------------------ */
  388. virtual int variableWrapper(Node *n) {
  389. char *name = GetChar(n,"name");
  390. char *iname = GetChar(n,"sym:name");
  391. SwigType *t = Getattr(n,"type");
  392. String *proc_name = NewString("");
  393. char var_name[256];
  394. String *tm;
  395. String *tm2 = NewString("");;
  396. String *argnum = NewString("0");
  397. String *arg = NewString("argv[0]");
  398. Wrapper *f;
  399. if (!addSymbol(iname,n)) return SWIG_ERROR;
  400. f = NewWrapper();
  401. // evaluation function names
  402. strcpy(var_name, Char(Swig_name_wrapper(iname)));
  403. // Build the name for scheme.
  404. Printv(proc_name, iname,NIL);
  405. Replaceall(proc_name, "_", "-");
  406. if ((SwigType_type(t) != T_USER) || (is_a_pointer(t))) {
  407. Printf (f->def, "static Scheme_Object *%s(int argc, Scheme_Object** argv) {\n", var_name);
  408. Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
  409. Wrapper_add_local (f, "swig_result", "Scheme_Object *swig_result");
  410. if (!Getattr(n,"feature:immutable")) {
  411. /* Check for a setting of the variable value */
  412. Printf (f->code, "if (argc) {\n");
  413. if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) {
  414. Replaceall(tm,"$source","argv[0]");
  415. Replaceall(tm,"$target",name);
  416. Replaceall(tm,"$input","argv[0]");
  417. Printv(f->code, tm, "\n",NIL);
  418. }
  419. else {
  420. throw_unhandled_mzscheme_type_error (t);
  421. }
  422. Printf (f->code, "}\n");
  423. }
  424. // Now return the value of the variable (regardless
  425. // of evaluating or setting)
  426. if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) {
  427. Replaceall(tm,"$source",name);
  428. Replaceall(tm,"$target","swig_result");
  429. Replaceall(tm,"$result","swig_result");
  430. Printf (f->code, "%s\n", tm);
  431. }
  432. else {
  433. throw_unhandled_mzscheme_type_error (t);
  434. }
  435. Printf (f->code, "\nreturn swig_result;\n");
  436. Printf (f->code, "#undef FUNC_NAME\n");
  437. Printf (f->code, "}\n");
  438. Wrapper_print (f, f_wrappers);
  439. // Now add symbol to the MzScheme interpreter
  440. Printv(init_func_def,
  441. "scheme_add_global(\"",
  442. proc_name,
  443. "\", scheme_make_prim_w_arity(",
  444. var_name,
  445. ", \"",
  446. proc_name,
  447. "\", ",
  448. "0",
  449. ", ",
  450. "1",
  451. "), menv);\n",NIL);
  452. } else {
  453. Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number,
  454. "Unsupported variable type %s (ignored).\n", SwigType_str(t,0));
  455. }
  456. Delete(proc_name);
  457. Delete(argnum);
  458. Delete(arg);
  459. Delete(tm2);
  460. DelWrapper(f);
  461. return SWIG_OK;
  462. }
  463. /* ------------------------------------------------------------
  464. * constantWrapper()
  465. * ------------------------------------------------------------ */
  466. virtual int constantWrapper(Node *n) {
  467. char *name = GetChar(n,"name");
  468. char *iname = GetChar(n,"sym:name");
  469. SwigType *type = Getattr(n,"type");
  470. String *value = Getattr(n,"value");
  471. String *var_name = NewString("");
  472. String *proc_name = NewString("");
  473. String *rvalue = NewString("");
  474. String *temp = NewString("");
  475. String *tm;
  476. // Make a static variable;
  477. Printf (var_name, "_wrap_const_%s", Swig_name_mangle(Getattr(n,"sym:name")));
  478. // Build the name for scheme.
  479. Printv(proc_name, iname,NIL);
  480. Replaceall(proc_name, "_", "-");
  481. if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) {
  482. Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number,
  483. "Unsupported constant value.\n");
  484. return SWIG_NOWRAP;
  485. }
  486. // See if there's a typemap
  487. Printv(rvalue, value,NIL);
  488. if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) {
  489. temp = Copy(rvalue);
  490. Clear(rvalue);
  491. Printv(rvalue, "\"", temp, "\"",NIL);
  492. }
  493. if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) {
  494. Delete(temp);
  495. temp = Copy(rvalue);
  496. Clear(rvalue);
  497. Printv(rvalue, "'", temp, "'",NIL);
  498. }
  499. if ((tm = Swig_typemap_lookup_new("constant",n,name,0))) {
  500. Replaceall(tm,"$source",rvalue);
  501. Replaceall(tm,"$value",rvalue);
  502. Replaceall(tm,"$target",name);
  503. Printf (f_init, "%s\n", tm);
  504. } else {
  505. // Create variable and assign it a value
  506. Printf (f_header, "static %s = ", SwigType_lstr(type,var_name));
  507. if ((SwigType_type(type) == T_STRING)) {
  508. Printf (f_header, "\"%s\";\n", value);
  509. } else if (SwigType_type(type) == T_CHAR) {
  510. Printf (f_header, "\'%s\';\n", value);
  511. } else {
  512. Printf (f_header, "%s;\n", value);
  513. }
  514. // Now create a variable declaration
  515. {
  516. /* Hack alert: will cleanup later -- Dave */
  517. Node *n = NewHash();
  518. Setattr(n,"name",var_name);
  519. Setattr(n,"sym:name",iname);
  520. Setattr(n,"type", type);
  521. variableWrapper(n);
  522. Delete(n);
  523. }
  524. }
  525. Delete(proc_name);
  526. Delete(rvalue);
  527. Delete(temp);
  528. return SWIG_OK;
  529. }
  530. virtual int destructorHandler(Node *n) {
  531. exporting_destructor = true;
  532. Language::destructorHandler(n);
  533. exporting_destructor = false;
  534. return SWIG_OK;
  535. }
  536. /* ------------------------------------------------------------
  537. * classHandler()
  538. * ------------------------------------------------------------ */
  539. virtual int classHandler(Node *n) {
  540. String *mangled_classname = 0;
  541. String *real_classname = 0;
  542. String *scm_structname = NewString("");
  543. SwigType *ctype_ptr = NewStringf("p.%s", Getattr(n, "classtype"));
  544. SwigType *t = NewStringf("p.%s", Getattr(n, "name"));
  545. swigtype_ptr = SwigType_manglestr(t);
  546. Delete(t);
  547. cls_swigtype = SwigType_manglestr(Getattr(n, "name"));
  548. fieldnames_tab = NewString("");
  549. convert_tab = NewString("");
  550. convert_proto_tab = NewString("");
  551. struct_name = Getattr(n,"sym:name");
  552. mangled_struct_name = Swig_name_mangle(Getattr(n,"sym:name"));
  553. Printv(scm_structname, struct_name, NIL);
  554. Replaceall(scm_structname, "_", "-");
  555. real_classname = Getattr(n,"name");
  556. mangled_classname = Swig_name_mangle(real_classname);
  557. Printv(fieldnames_tab, "static const char *_swig_struct_",
  558. cls_swigtype, "_field_names[] = { \n", NIL);
  559. Printv(convert_proto_tab, "static Scheme_Object *_swig_convert_struct_",
  560. cls_swigtype, "(", SwigType_str(ctype_ptr, "ptr"), ");\n", NIL);
  561. Printv(convert_tab, "static Scheme_Object *_swig_convert_struct_",
  562. cls_swigtype, "(", SwigType_str(ctype_ptr, "ptr"), ")\n {\n",
  563. NIL);
  564. Printv(convert_tab,
  565. tab4, "Scheme_Object *obj;\n",
  566. tab4, "Scheme_Object *fields[_swig_struct_", cls_swigtype,
  567. "_field_names_cnt];\n",
  568. tab4, "int i = 0;\n\n", NIL);
  569. /* Generate normal wrappers */
  570. Language::classHandler(n);
  571. Printv(convert_tab, tab4, "obj = scheme_make_struct_instance(",
  572. "_swig_struct_type_", cls_swigtype, ", i, fields);\n", NIL);
  573. Printv(convert_tab, tab4, "return obj;\n}\n\n", NIL);
  574. Printv(fieldnames_tab, "};\n", NIL);
  575. Printv(f_header, "static Scheme_Object *_swig_struct_type_",
  576. cls_swigtype, ";\n", NIL);
  577. Printv(f_header, fieldnames_tab, NIL);
  578. Printv(f_header, "#define _swig_struct_", cls_swigtype,
  579. "_field_names_cnt (sizeof(_swig_struct_", cls_swigtype,
  580. "_field_names)/sizeof(char*))\n", NIL);
  581. Printv(f_header, convert_proto_tab, NIL);
  582. Printv(f_wrappers, convert_tab, NIL);
  583. Printv(init_func_def, "_swig_struct_type_", cls_swigtype,
  584. " = SWIG_MzScheme_new_scheme_struct(menv, \"", scm_structname, "\", ",
  585. "_swig_struct_", cls_swigtype, "_field_names_cnt,",
  586. "(char**) _swig_struct_", cls_swigtype, "_field_names);\n",
  587. NIL);
  588. Delete(mangled_classname);
  589. Delete(swigtype_ptr);
  590. swigtype_ptr = 0;
  591. Delete(fieldnames_tab);
  592. Delete(convert_tab);
  593. Delete(ctype_ptr);
  594. Delete(convert_proto_tab);
  595. struct_name = 0;
  596. mangled_struct_name = 0;
  597. Delete(cls_swigtype);
  598. cls_swigtype = 0;
  599. return SWIG_OK;
  600. }
  601. /* ------------------------------------------------------------
  602. * membervariableHandler()
  603. * ------------------------------------------------------------ */
  604. virtual int membervariableHandler(Node *n) {
  605. Language::membervariableHandler(n);
  606. if (!is_smart_pointer()) {
  607. String *symname = Getattr(n, "sym:name");
  608. String *name = Getattr(n, "name");
  609. SwigType *type = Getattr(n, "type");
  610. String *swigtype = SwigType_manglestr(Getattr(n, "type"));
  611. String *tm = 0;
  612. String *access_mem = NewString("");
  613. SwigType *ctype_ptr = NewStringf("p.%s", Getattr(n, "type"));
  614. Printv(fieldnames_tab, tab4, "\"", symname, "\",\n", NIL);
  615. Printv(access_mem, "(ptr)->", name, NIL);
  616. if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) {
  617. Printv(convert_tab, tab4, "fields[i++] = ", NIL);
  618. Printv(convert_tab, "_swig_convert_struct_", swigtype,
  619. "((", SwigType_str(ctype_ptr, ""), ")&((ptr)->",
  620. name, "));\n", NIL);
  621. } else if ((tm = Swig_typemap_lookup_new("varout",n,access_mem,0))) {
  622. Replaceall(tm,"$result","fields[i++]");
  623. Printv(convert_tab, tm, "\n", NIL);
  624. } else
  625. Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number,
  626. "Unsupported member variable type %s (ignored).\n",
  627. SwigType_str(type,0));
  628. Delete(access_mem);
  629. }
  630. return SWIG_OK;
  631. }
  632. /* ------------------------------------------------------------
  633. * validIdentifer()
  634. * ------------------------------------------------------------ */
  635. virtual int validIdentifier(String *s) {
  636. char *c = Char(s);
  637. /* Check whether we have an R5RS identifier.*/
  638. /* <identifier> --> <initial> <subsequent>* | <peculiar identifier> */
  639. /* <initial> --> <letter> | <special initial> */
  640. if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%')
  641. || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
  642. || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
  643. || (*c == '^') || (*c == '_') || (*c == '~'))) {
  644. /* <peculiar identifier> --> + | - | ... */
  645. if ((strcmp(c, "+") == 0)
  646. || strcmp(c, "-") == 0
  647. || strcmp(c, "...") == 0) return 1;
  648. else return 0;
  649. }
  650. /* <subsequent> --> <initial> | <digit> | <special subsequent> */
  651. while (*c) {
  652. if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%')
  653. || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
  654. || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
  655. || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+')
  656. || (*c == '-') || (*c == '.') || (*c == '@'))) return 0;
  657. c++;
  658. }
  659. return 1;
  660. }
  661. };
  662. /* -----------------------------------------------------------------------------
  663. * swig_mzscheme() - Instantiate module
  664. * ----------------------------------------------------------------------------- */
  665. static Language * new_swig_mzscheme() {
  666. return new MZSCHEME();
  667. }
  668. extern "C" Language * swig_mzscheme(void) {
  669. return new_swig_mzscheme();
  670. }