PageRenderTime 90ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 1ms

/tags/rel-1.3.36/Source/Modules/guile.cxx

#
C++ | 1752 lines | 1354 code | 205 blank | 193 comment | 435 complexity | 5cfc4308004d8e44ad92292a481d1188 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1. /* -----------------------------------------------------------------------------
  2. * See the LICENSE file for information on copyright, usage and redistribution
  3. * of SWIG, and the README file for authors - http://www.swig.org/release.html.
  4. *
  5. * guile.cxx
  6. *
  7. * Guile language module for SWIG.
  8. * ----------------------------------------------------------------------------- */
  9. char cvsroot_guile_cxx[] = "$Id: guile.cxx 10562 2008-06-23 21:14:53Z wsfulton $";
  10. #include "swigmod.h"
  11. #include <ctype.h>
  12. // Note string broken in half for compilers that can't handle long strings
  13. static const char *guile_usage = (char *) "\
  14. Guile Options (available with -guile)\n\
  15. -prefix <name> - Use <name> as prefix [default \"gswig_\"]\n\
  16. -package <name> - Set the path of the module to <name>\n\
  17. (default NULL)\n\
  18. -emitsetters - Emit procedures-with-setters for variables\n\
  19. and structure slots.\n\
  20. -onlysetters - Don't emit traditional getter and setter\n\
  21. procedures for structure slots,\n\
  22. only emit procedures-with-setters.\n\
  23. -procdoc <file> - Output procedure documentation to <file>\n\
  24. -procdocformat <format> - Output procedure documentation in <format>;\n\
  25. one of `guile-1.4', `plain', `texinfo'\n\
  26. -linkage <lstyle> - Use linkage protocol <lstyle> (default `simple')\n\
  27. Use `module' for native Guile module linking\n\
  28. (requires Guile >= 1.5.0). Use `passive' for\n\
  29. passive linking (no C-level module-handling code),\n\
  30. `ltdlmod' for Guile's old dynamic module\n\
  31. convention (Guile <= 1.4), or `hobbit' for hobbit\n\
  32. modules.\n\
  33. -scmstub - Output Scheme file with module declaration and\n\
  34. exports; only with `passive' and `simple' linkage\n\
  35. -gh - Use the gh_ Guile API. (Guile <= 1.8) \n\
  36. -scm - Use the scm Guile API. (Guile >= 1.6, default) \n\
  37. -proxy - Export GOOPS class definitions\n\
  38. -emitslotaccessors - Emit accessor methods for all GOOPS slots\n" "\
  39. -primsuffix <suffix> - Name appended to primitive module when exporting\n\
  40. GOOPS classes. (default = \"primitive\")\n\
  41. -goopsprefix <prefix> - Prepend <prefix> to all goops identifiers\n\
  42. -useclassprefix - Prepend the class name to all goops identifiers\n\
  43. -exportprimitive - Add the (export ...) code from scmstub into the\n\
  44. GOOPS file.\n";
  45. static File *f_runtime = 0;
  46. static File *f_header = 0;
  47. static File *f_wrappers = 0;
  48. static File *f_init = 0;
  49. static char *prefix = (char *) "gswig_";
  50. static char *module = 0;
  51. static char *package = 0;
  52. static enum {
  53. GUILE_LSTYLE_SIMPLE, // call `SWIG_init()'
  54. GUILE_LSTYLE_PASSIVE, // passive linking (no module code)
  55. GUILE_LSTYLE_MODULE, // native guile module linking (Guile >= 1.4.1)
  56. GUILE_LSTYLE_LTDLMOD_1_4, // old (Guile <= 1.4) dynamic module convention
  57. GUILE_LSTYLE_HOBBIT // use (hobbit4d link)
  58. } linkage = GUILE_LSTYLE_SIMPLE;
  59. static File *procdoc = 0;
  60. static bool scmstub = false;
  61. static String *scmtext;
  62. static bool goops = false;
  63. static String *goopstext;
  64. static String *goopscode;
  65. static String *goopsexport;
  66. static enum {
  67. GUILE_1_4,
  68. PLAIN,
  69. TEXINFO
  70. } docformat = GUILE_1_4;
  71. static int emit_setters = 0;
  72. static int only_setters = 0;
  73. static int emit_slot_accessors = 0;
  74. static int struct_member = 0;
  75. static String *beforereturn = 0;
  76. static String *return_nothing_doc = 0;
  77. static String *return_one_doc = 0;
  78. static String *return_multi_doc = 0;
  79. static String *exported_symbols = 0;
  80. static int use_scm_interface = 1;
  81. static int exporting_destructor = 0;
  82. static String *swigtype_ptr = 0;
  83. /* GOOPS stuff */
  84. static String *primsuffix = 0;
  85. static String *class_name = 0;
  86. static String *short_class_name = 0;
  87. static String *goops_class_methods;
  88. static int in_class = 0;
  89. static int have_constructor = 0;
  90. static int useclassprefix = 0; // -useclassprefix argument
  91. static String *goopsprefix = 0; // -goopsprefix argument
  92. static int primRenamer = 0; // if (use-modules ((...) :renamer ...) is exported to GOOPS file
  93. static int exportprimitive = 0; // -exportprimitive argument
  94. static String *memberfunction_name = 0;
  95. extern "C" {
  96. static int has_classname(Node *class_node) {
  97. return Getattr(class_node, "guile:goopsclassname") != NULL;
  98. }
  99. }
  100. class GUILE:public Language {
  101. public:
  102. /* ------------------------------------------------------------
  103. * main()
  104. * ------------------------------------------------------------ */
  105. virtual void main(int argc, char *argv[]) {
  106. int i, orig_len;
  107. SWIG_library_directory("guile");
  108. SWIG_typemap_lang("guile");
  109. // Look for certain command line options
  110. for (i = 1; i < argc; i++) {
  111. if (argv[i]) {
  112. if (strcmp(argv[i], "-help") == 0) {
  113. fputs(guile_usage, stdout);
  114. SWIG_exit(EXIT_SUCCESS);
  115. } else if (strcmp(argv[i], "-prefix") == 0) {
  116. if (argv[i + 1]) {
  117. prefix = new char[strlen(argv[i + 1]) + 2];
  118. strcpy(prefix, argv[i + 1]);
  119. Swig_mark_arg(i);
  120. Swig_mark_arg(i + 1);
  121. i++;
  122. } else {
  123. Swig_arg_error();
  124. }
  125. } else if (strcmp(argv[i], "-package") == 0) {
  126. if (argv[i + 1]) {
  127. package = new char[strlen(argv[i + 1]) + 2];
  128. strcpy(package, argv[i + 1]);
  129. Swig_mark_arg(i);
  130. Swig_mark_arg(i + 1);
  131. i++;
  132. } else {
  133. Swig_arg_error();
  134. }
  135. } else if (strcmp(argv[i], "-Linkage") == 0 || strcmp(argv[i], "-linkage") == 0) {
  136. if (argv[i + 1]) {
  137. if (0 == strcmp(argv[i + 1], "ltdlmod"))
  138. linkage = GUILE_LSTYLE_LTDLMOD_1_4;
  139. else if (0 == strcmp(argv[i + 1], "hobbit"))
  140. linkage = GUILE_LSTYLE_HOBBIT;
  141. else if (0 == strcmp(argv[i + 1], "simple"))
  142. linkage = GUILE_LSTYLE_SIMPLE;
  143. else if (0 == strcmp(argv[i + 1], "passive"))
  144. linkage = GUILE_LSTYLE_PASSIVE;
  145. else if (0 == strcmp(argv[i + 1], "module"))
  146. linkage = GUILE_LSTYLE_MODULE;
  147. else
  148. Swig_arg_error();
  149. Swig_mark_arg(i);
  150. Swig_mark_arg(i + 1);
  151. i++;
  152. } else {
  153. Swig_arg_error();
  154. }
  155. } else if (strcmp(argv[i], "-procdoc") == 0) {
  156. if (argv[i + 1]) {
  157. procdoc = NewFile(argv[i + 1], (char *) "w");
  158. if (!procdoc) {
  159. FileErrorDisplay(argv[i + 1]);
  160. SWIG_exit(EXIT_FAILURE);
  161. }
  162. Swig_mark_arg(i);
  163. Swig_mark_arg(i + 1);
  164. i++;
  165. } else {
  166. Swig_arg_error();
  167. }
  168. } else if (strcmp(argv[i], "-procdocformat") == 0) {
  169. if (strcmp(argv[i + 1], "guile-1.4") == 0)
  170. docformat = GUILE_1_4;
  171. else if (strcmp(argv[i + 1], "plain") == 0)
  172. docformat = PLAIN;
  173. else if (strcmp(argv[i + 1], "texinfo") == 0)
  174. docformat = TEXINFO;
  175. else
  176. Swig_arg_error();
  177. Swig_mark_arg(i);
  178. Swig_mark_arg(i + 1);
  179. i++;
  180. } else if (strcmp(argv[i], "-emit-setters") == 0 || strcmp(argv[i], "-emitsetters") == 0) {
  181. emit_setters = 1;
  182. Swig_mark_arg(i);
  183. } else if (strcmp(argv[i], "-only-setters") == 0 || strcmp(argv[i], "-onlysetters") == 0) {
  184. emit_setters = 1;
  185. only_setters = 1;
  186. Swig_mark_arg(i);
  187. } else if (strcmp(argv[i], "-emit-slot-accessors") == 0 || strcmp(argv[i], "-emitslotaccessors") == 0) {
  188. emit_slot_accessors = 1;
  189. Swig_mark_arg(i);
  190. } else if (strcmp(argv[i], "-scmstub") == 0) {
  191. scmstub = true;
  192. Swig_mark_arg(i);
  193. } else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
  194. goops = true;
  195. Swig_mark_arg(i);
  196. } else if (strcmp(argv[i], "-gh") == 0) {
  197. use_scm_interface = 0;
  198. Swig_mark_arg(i);
  199. } else if (strcmp(argv[i], "-scm") == 0) {
  200. use_scm_interface = 1;
  201. Swig_mark_arg(i);
  202. } else if (strcmp(argv[i], "-primsuffix") == 0) {
  203. if (argv[i + 1]) {
  204. primsuffix = NewString(argv[i + 1]);
  205. Swig_mark_arg(i);
  206. Swig_mark_arg(i + 1);
  207. i++;
  208. } else {
  209. Swig_arg_error();
  210. }
  211. } else if (strcmp(argv[i], "-goopsprefix") == 0) {
  212. if (argv[i + 1]) {
  213. goopsprefix = NewString(argv[i + 1]);
  214. Swig_mark_arg(i);
  215. Swig_mark_arg(i + 1);
  216. i++;
  217. } else {
  218. Swig_arg_error();
  219. }
  220. } else if (strcmp(argv[i], "-useclassprefix") == 0) {
  221. useclassprefix = 1;
  222. Swig_mark_arg(i);
  223. } else if (strcmp(argv[i], "-exportprimitive") == 0) {
  224. exportprimitive = 1;
  225. // should use Swig_warning() here?
  226. Swig_mark_arg(i);
  227. }
  228. }
  229. }
  230. // set default value for primsuffix
  231. if (primsuffix == NULL)
  232. primsuffix = NewString("primitive");
  233. //goops support can only be enabled if passive or module linkage is used
  234. if (goops) {
  235. if (linkage != GUILE_LSTYLE_PASSIVE && linkage != GUILE_LSTYLE_MODULE) {
  236. Printf(stderr, "guile: GOOPS support requires passive or module linkage\n");
  237. exit(1);
  238. }
  239. }
  240. if (goops) {
  241. // -proxy implies -emit-setters
  242. emit_setters = 1;
  243. }
  244. if ((linkage == GUILE_LSTYLE_PASSIVE && scmstub) || linkage == GUILE_LSTYLE_MODULE)
  245. primRenamer = 1;
  246. if (exportprimitive && primRenamer) {
  247. // should use Swig_warning() ?
  248. Printf(stderr, "guile: Warning: -exportprimitive only makes sense with passive linkage without a scmstub.\n");
  249. }
  250. // Make sure `prefix' ends in an underscore
  251. orig_len = strlen(prefix);
  252. if (prefix[orig_len - 1] != '_') {
  253. prefix[1 + orig_len] = 0;
  254. prefix[orig_len] = '_';
  255. }
  256. /* Add a symbol for this module */
  257. Preprocessor_define("SWIGGUILE 1", 0);
  258. /* Read in default typemaps */
  259. if (use_scm_interface)
  260. SWIG_config_file("guile_scm.swg");
  261. else
  262. SWIG_config_file("guile_gh.swg");
  263. allow_overloading();
  264. }
  265. /* ------------------------------------------------------------
  266. * top()
  267. * ------------------------------------------------------------ */
  268. virtual int top(Node *n) {
  269. /* Initialize all of the output files */
  270. String *outfile = Getattr(n, "outfile");
  271. f_runtime = NewFile(outfile, "w");
  272. if (!f_runtime) {
  273. FileErrorDisplay(outfile);
  274. SWIG_exit(EXIT_FAILURE);
  275. }
  276. f_init = NewString("");
  277. f_header = NewString("");
  278. f_wrappers = NewString("");
  279. /* Register file targets with the SWIG file handler */
  280. Swig_register_filebyname("header", f_header);
  281. Swig_register_filebyname("wrapper", f_wrappers);
  282. Swig_register_filebyname("runtime", f_runtime);
  283. Swig_register_filebyname("init", f_init);
  284. scmtext = NewString("");
  285. Swig_register_filebyname("scheme", scmtext);
  286. exported_symbols = NewString("");
  287. goopstext = NewString("");
  288. Swig_register_filebyname("goops", goopstext);
  289. goopscode = NewString("");
  290. goopsexport = NewString("");
  291. Printf(f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n");
  292. Swig_banner(f_runtime);
  293. Printf(f_runtime, "/* Implementation : GUILE */\n\n");
  294. if (!use_scm_interface) {
  295. if (SwigRuntime == 1)
  296. Printf(f_runtime, "#define SWIG_GLOBAL\n");
  297. if (SwigRuntime == 2)
  298. Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
  299. }
  300. /* Write out directives and declarations */
  301. module = Swig_copy_string(Char(Getattr(n, "name")));
  302. switch (linkage) {
  303. case GUILE_LSTYLE_SIMPLE:
  304. /* Simple linkage; we have to export the SWIG_init function. The user can
  305. rename the function by a #define. */
  306. Printf(f_runtime, "#define SWIG_GUILE_INIT_STATIC extern\n");
  307. break;
  308. default:
  309. /* Other linkage; we make the SWIG_init function static */
  310. Printf(f_runtime, "#define SWIG_GUILE_INIT_STATIC static\n");
  311. break;
  312. }
  313. if (CPlusPlus) {
  314. Printf(f_runtime, "extern \"C\" {\n\n");
  315. }
  316. Printf(f_runtime, "SWIG_GUILE_INIT_STATIC void\nSWIG_init (void);\n");
  317. if (CPlusPlus) {
  318. Printf(f_runtime, "\n}\n");
  319. }
  320. Language::top(n);
  321. /* Close module */
  322. Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
  323. SwigType_emit_type_table(f_runtime, f_wrappers);
  324. Printf(f_init, "}\n\n");
  325. Printf(f_init, "#ifdef __cplusplus\n}\n#endif\n");
  326. String *module_name = NewString("");
  327. if (!module)
  328. Printv(module_name, "swig", NIL);
  329. else {
  330. if (package)
  331. Printf(module_name, "%s/%s", package, module);
  332. else
  333. Printv(module_name, module, NIL);
  334. }
  335. emit_linkage(module_name);
  336. Delete(module_name);
  337. if (procdoc) {
  338. Delete(procdoc);
  339. procdoc = NULL;
  340. }
  341. Delete(goopscode);
  342. Delete(goopsexport);
  343. Delete(goopstext);
  344. /* Close all of the files */
  345. Dump(f_header, f_runtime);
  346. Dump(f_wrappers, f_runtime);
  347. Wrapper_pretty_print(f_init, f_runtime);
  348. Delete(f_header);
  349. Delete(f_wrappers);
  350. Delete(f_init);
  351. Close(f_runtime);
  352. Delete(f_runtime);
  353. return SWIG_OK;
  354. }
  355. void emit_linkage(String *module_name) {
  356. String *module_func = NewString("");
  357. if (CPlusPlus) {
  358. Printf(f_init, "extern \"C\" {\n\n");
  359. }
  360. Printv(module_func, module_name, NIL);
  361. Replaceall(module_func, "-", "_");
  362. switch (linkage) {
  363. case GUILE_LSTYLE_SIMPLE:
  364. Printf(f_init, "\n/* Linkage: simple */\n");
  365. break;
  366. case GUILE_LSTYLE_PASSIVE:
  367. Printf(f_init, "\n/* Linkage: passive */\n");
  368. Replaceall(module_func, "/", "_");
  369. Insert(module_func, 0, "scm_init_");
  370. Append(module_func, "_module");
  371. Printf(f_init, "SCM\n%s (void)\n{\n", module_func);
  372. Printf(f_init, " SWIG_init();\n");
  373. Printf(f_init, " return SCM_UNSPECIFIED;\n");
  374. Printf(f_init, "}\n");
  375. break;
  376. case GUILE_LSTYLE_LTDLMOD_1_4:
  377. Printf(f_init, "\n/* Linkage: ltdlmod */\n");
  378. Replaceall(module_func, "/", "_");
  379. Insert(module_func, 0, "scm_init_");
  380. Append(module_func, "_module");
  381. Printf(f_init, "SCM\n%s (void)\n{\n", module_func);
  382. {
  383. String *mod = NewString(module_name);
  384. Replaceall(mod, "/", " ");
  385. Printf(f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", mod);
  386. Printf(f_init, " return SCM_UNSPECIFIED;\n");
  387. Delete(mod);
  388. }
  389. Printf(f_init, "}\n");
  390. break;
  391. case GUILE_LSTYLE_MODULE:
  392. Printf(f_init, "\n/* Linkage: module */\n");
  393. Replaceall(module_func, "/", "_");
  394. Insert(module_func, 0, "scm_init_");
  395. Append(module_func, "_module");
  396. Printf(f_init, "static void SWIG_init_helper(void *data)\n");
  397. Printf(f_init, "{\n SWIG_init();\n");
  398. if (Len(exported_symbols) > 0)
  399. Printf(f_init, " scm_c_export(%sNULL);", exported_symbols);
  400. Printf(f_init, "\n}\n\n");
  401. Printf(f_init, "SCM\n%s (void)\n{\n", module_func);
  402. {
  403. String *mod = NewString(module_name);
  404. if (goops)
  405. Printv(mod, "-", primsuffix, NIL);
  406. Replaceall(mod, "/", " ");
  407. Printf(f_init, " scm_c_define_module(\"%s\",\n", mod);
  408. Printf(f_init, " SWIG_init_helper, NULL);\n");
  409. Printf(f_init, " return SCM_UNSPECIFIED;\n");
  410. Delete(mod);
  411. }
  412. Printf(f_init, "}\n");
  413. break;
  414. case GUILE_LSTYLE_HOBBIT:
  415. Printf(f_init, "\n/* Linkage: hobbit */\n");
  416. Replaceall(module_func, "/", "_slash_");
  417. Insert(module_func, 0, "scm_init_");
  418. Printf(f_init, "SCM\n%s (void)\n{\n", module_func);
  419. {
  420. String *mod = NewString(module_name);
  421. Replaceall(mod, "/", " ");
  422. Printf(f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", mod);
  423. Printf(f_init, " return SCM_UNSPECIFIED;\n");
  424. Delete(mod);
  425. }
  426. Printf(f_init, "}\n");
  427. break;
  428. default:
  429. abort(); // for now
  430. }
  431. if (scmstub) {
  432. /* Emit Scheme stub if requested */
  433. String *primitive_name = NewString(module_name);
  434. if (goops)
  435. Printv(primitive_name, "-", primsuffix, NIL);
  436. String *mod = NewString(primitive_name);
  437. Replaceall(mod, "/", " ");
  438. String *fname = NewStringf("%s%s.scm",
  439. SWIG_output_directory(),
  440. primitive_name);
  441. Delete(primitive_name);
  442. File *scmstubfile = NewFile(fname, (char *) "w");
  443. if (!scmstubfile) {
  444. FileErrorDisplay(fname);
  445. SWIG_exit(EXIT_FAILURE);
  446. }
  447. Delete(fname);
  448. Printf(scmstubfile, ";;; -*- buffer-read-only: t -*- vi: set ro: */\n");
  449. Printf(scmstubfile, ";;; Automatically generated by SWIG; do not edit.\n\n");
  450. if (linkage == GUILE_LSTYLE_SIMPLE || linkage == GUILE_LSTYLE_PASSIVE)
  451. Printf(scmstubfile, "(define-module (%s))\n\n", mod);
  452. Delete(mod);
  453. Printf(scmstubfile, "%s", scmtext);
  454. if ((linkage == GUILE_LSTYLE_SIMPLE || linkage == GUILE_LSTYLE_PASSIVE)
  455. && Len(exported_symbols) > 0) {
  456. String *ex = NewString(exported_symbols);
  457. Replaceall(ex, ", ", "\n ");
  458. Replaceall(ex, "\"", "");
  459. Chop(ex);
  460. Printf(scmstubfile, "\n(export %s)\n", ex);
  461. Delete(ex);
  462. }
  463. Delete(scmstubfile);
  464. }
  465. if (goops) {
  466. String *mod = NewString(module_name);
  467. Replaceall(mod, "/", " ");
  468. String *fname = NewStringf("%s%s.scm", SWIG_output_directory(),
  469. module_name);
  470. File *goopsfile = NewFile(fname, (char *) "w");
  471. if (!goopsfile) {
  472. FileErrorDisplay(fname);
  473. SWIG_exit(EXIT_FAILURE);
  474. }
  475. Delete(fname);
  476. Printf(goopsfile, ";;; -*- buffer-read-only: t -*- vi: set ro: */\n");
  477. Printf(goopsfile, ";;; Automatically generated by SWIG; do not edit.\n\n");
  478. Printf(goopsfile, "(define-module (%s))\n", mod);
  479. Printf(goopsfile, "%s\n", goopstext);
  480. Printf(goopsfile, "(use-modules (oop goops) (Swig common))\n");
  481. if (primRenamer) {
  482. Printf(goopsfile, "(use-modules ((%s-%s) :renamer (symbol-prefix-proc 'primitive:)))\n", mod, primsuffix);
  483. }
  484. Printf(goopsfile, "%s\n(export %s)", goopscode, goopsexport);
  485. if (exportprimitive) {
  486. String *ex = NewString(exported_symbols);
  487. Replaceall(ex, ", ", "\n ");
  488. Replaceall(ex, "\"", "");
  489. Chop(ex);
  490. Printf(goopsfile, "\n(export %s)", ex);
  491. Delete(ex);
  492. }
  493. Delete(mod);
  494. Delete(goopsfile);
  495. }
  496. Delete(module_func);
  497. if (CPlusPlus) {
  498. Printf(f_init, "\n}\n");
  499. }
  500. }
  501. /* Return true iff T is a pointer type */
  502. int is_a_pointer(SwigType *t) {
  503. return SwigType_ispointer(SwigType_typedef_resolve_all(t));
  504. }
  505. /* Report an error handling the given type. */
  506. void throw_unhandled_guile_type_error(SwigType *d) {
  507. Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s.\n", SwigType_str(d, 0));
  508. }
  509. /* Write out procedure documentation */
  510. void write_doc(const String *proc_name, const String *signature, const String *doc, const String *signature2 = NULL) {
  511. switch (docformat) {
  512. case GUILE_1_4:
  513. Printv(procdoc, "\f\n", NIL);
  514. Printv(procdoc, "(", signature, ")\n", NIL);
  515. if (signature2)
  516. Printv(procdoc, "(", signature2, ")\n", NIL);
  517. Printv(procdoc, doc, "\n", NIL);
  518. break;
  519. case PLAIN:
  520. Printv(procdoc, "\f", proc_name, "\n\n", NIL);
  521. Printv(procdoc, "(", signature, ")\n", NIL);
  522. if (signature2)
  523. Printv(procdoc, "(", signature2, ")\n", NIL);
  524. Printv(procdoc, doc, "\n\n", NIL);
  525. break;
  526. case TEXINFO:
  527. Printv(procdoc, "\f", proc_name, "\n", NIL);
  528. Printv(procdoc, "@deffn primitive ", signature, "\n", NIL);
  529. if (signature2)
  530. Printv(procdoc, "@deffnx primitive ", signature2, "\n", NIL);
  531. Printv(procdoc, doc, "\n", NIL);
  532. Printv(procdoc, "@end deffn\n\n", NIL);
  533. break;
  534. }
  535. }
  536. /* returns false if the typemap is an empty string */
  537. bool handle_documentation_typemap(String *output,
  538. const String *maybe_delimiter, Parm *p, const String *typemap, const String *default_doc, const String *name = NULL) {
  539. String *tmp = NewString("");
  540. String *tm;
  541. if (!(tm = Getattr(p, typemap))) {
  542. Printf(tmp, "%s", default_doc);
  543. tm = tmp;
  544. }
  545. bool result = (Len(tm) > 0);
  546. if (maybe_delimiter && Len(output) > 0 && Len(tm) > 0) {
  547. Printv(output, maybe_delimiter, NIL);
  548. }
  549. const String *pn = (name == NULL) ? (const String *) Getattr(p, "name") : name;
  550. String *pt = Getattr(p, "type");
  551. Replaceall(tm, "$name", pn); // legacy for $parmname
  552. Replaceall(tm, "$type", SwigType_str(pt, 0));
  553. /* $NAME is like $name, but marked-up as a variable. */
  554. String *ARGNAME = NewString("");
  555. if (docformat == TEXINFO)
  556. Printf(ARGNAME, "@var{%s}", pn);
  557. else
  558. Printf(ARGNAME, "%(upper)s", pn);
  559. Replaceall(tm, "$NAME", ARGNAME);
  560. Replaceall(tm, "$PARMNAME", ARGNAME);
  561. Printv(output, tm, NIL);
  562. Delete(tmp);
  563. return result;
  564. }
  565. /* ------------------------------------------------------------
  566. * functionWrapper()
  567. * Create a function declaration and register it with the interpreter.
  568. * ------------------------------------------------------------ */
  569. virtual int functionWrapper(Node *n) {
  570. String *iname = Getattr(n, "sym:name");
  571. SwigType *d = Getattr(n, "type");
  572. ParmList *l = Getattr(n, "parms");
  573. Parm *p;
  574. String *proc_name = 0;
  575. char source[256];
  576. Wrapper *f = NewWrapper();;
  577. String *cleanup = NewString("");
  578. String *outarg = NewString("");
  579. String *signature = NewString("");
  580. String *doc_body = NewString("");
  581. String *returns = NewString("");
  582. String *method_signature = NewString("");
  583. String *primitive_args = NewString("");
  584. Hash *scheme_arg_names = NewHash();
  585. int num_results = 1;
  586. String *tmp = NewString("");
  587. String *tm;
  588. int i;
  589. int numargs = 0;
  590. int numreq = 0;
  591. String *overname = 0;
  592. int args_passed_as_array = 0;
  593. int scheme_argnum = 0;
  594. bool any_specialized_arg = false;
  595. // Make a wrapper name for this
  596. String *wname = Swig_name_wrapper(iname);
  597. if (Getattr(n, "sym:overloaded")) {
  598. overname = Getattr(n, "sym:overname");
  599. args_passed_as_array = 1;
  600. } else {
  601. if (!addSymbol(iname, n)) {
  602. DelWrapper(f);
  603. return SWIG_ERROR;
  604. }
  605. }
  606. if (overname) {
  607. Append(wname, overname);
  608. }
  609. Setattr(n, "wrap:name", wname);
  610. // Build the name for scheme.
  611. proc_name = NewString(iname);
  612. Replaceall(proc_name, "_", "-");
  613. /* Emit locals etc. into f->code; figure out which args to ignore */
  614. emit_parameter_variables(l, f);
  615. /* Attach the standard typemaps */
  616. emit_attach_parmmaps(l, f);
  617. Setattr(n, "wrap:parms", l);
  618. /* Get number of required and total arguments */
  619. numargs = emit_num_arguments(l);
  620. numreq = emit_num_required(l);
  621. /* Declare return variable */
  622. Wrapper_add_local(f, "gswig_result", "SCM gswig_result");
  623. Wrapper_add_local(f, "gswig_list_p", "SWIGUNUSED int gswig_list_p = 0");
  624. /* Open prototype and signature */
  625. Printv(f->def, "static SCM\n", wname, " (", NIL);
  626. if (args_passed_as_array) {
  627. Printv(f->def, "int argc, SCM *argv", NIL);
  628. }
  629. Printv(signature, proc_name, NIL);
  630. /* Now write code to extract the parameters */
  631. for (i = 0, p = l; i < numargs; i++) {
  632. while (checkAttribute(p, "tmap:in:numinputs", "0")) {
  633. p = Getattr(p, "tmap:in:next");
  634. }
  635. SwigType *pt = Getattr(p, "type");
  636. int opt_p = (i >= numreq);
  637. // Produce names of source and target
  638. if (args_passed_as_array)
  639. sprintf(source, "argv[%d]", i);
  640. else
  641. sprintf(source, "s_%d", i);
  642. String *target = Getattr(p, "lname");
  643. if (!args_passed_as_array) {
  644. if (i != 0)
  645. Printf(f->def, ", ");
  646. Printf(f->def, "SCM s_%d", i);
  647. }
  648. if (opt_p) {
  649. Printf(f->code, " if (%s != SCM_UNDEFINED) {\n", source);
  650. }
  651. if ((tm = Getattr(p, "tmap:in"))) {
  652. Replaceall(tm, "$source", source);
  653. Replaceall(tm, "$target", target);
  654. Replaceall(tm, "$input", source);
  655. Setattr(p, "emit:input", source);
  656. Printv(f->code, tm, "\n", NIL);
  657. SwigType *pb = SwigType_typedef_resolve_all(SwigType_base(pt));
  658. SwigType *pn = Getattr(p, "name");
  659. String *argname;
  660. scheme_argnum++;
  661. if (pn && !Getattr(scheme_arg_names, pn))
  662. argname = pn;
  663. else {
  664. /* Anonymous arg or re-used argument name -- choose a name that cannot clash */
  665. argname = NewStringf("%%arg%d", scheme_argnum);
  666. }
  667. if (procdoc) {
  668. if (i == numreq) {
  669. /* First optional argument */
  670. Printf(signature, " #:optional");
  671. }
  672. /* Add to signature (arglist) */
  673. handle_documentation_typemap(signature, " ", p, "tmap:in:arglist", "$name", argname);
  674. /* Document the type of the arg in the documentation body */
  675. handle_documentation_typemap(doc_body, ", ", p, "tmap:in:doc", "$NAME is of type <$type>", argname);
  676. }
  677. if (goops) {
  678. if (i < numreq) {
  679. if (strcmp("void", Char(pt)) != 0) {
  680. Node *class_node = Swig_symbol_clookup_check(pb, Getattr(n, "sym:symtab"),
  681. has_classname);
  682. String *goopsclassname = (class_node == NULL) ? NULL : Getattr(class_node, "guile:goopsclassname");
  683. /* do input conversion */
  684. if (goopsclassname) {
  685. Printv(method_signature, " (", argname, " ", goopsclassname, ")", NIL);
  686. any_specialized_arg = true;
  687. } else {
  688. Printv(method_signature, " ", argname, NIL);
  689. }
  690. Printv(primitive_args, " ", argname, NIL);
  691. Setattr(scheme_arg_names, argname, p);
  692. }
  693. }
  694. }
  695. if (!pn) {
  696. Delete(argname);
  697. }
  698. p = Getattr(p, "tmap:in:next");
  699. } else {
  700. throw_unhandled_guile_type_error(pt);
  701. p = nextSibling(p);
  702. }
  703. if (opt_p)
  704. Printf(f->code, " }\n");
  705. }
  706. if (Len(doc_body) > 0)
  707. Printf(doc_body, ".\n");
  708. /* Insert constraint checking code */
  709. for (p = l; p;) {
  710. if ((tm = Getattr(p, "tmap:check"))) {
  711. Replaceall(tm, "$target", Getattr(p, "lname"));
  712. Printv(f->code, tm, "\n", NIL);
  713. p = Getattr(p, "tmap:check:next");
  714. } else {
  715. p = nextSibling(p);
  716. }
  717. }
  718. /* Pass output arguments back to the caller. */
  719. /* Insert argument output code */
  720. String *returns_argout = NewString("");
  721. for (p = l; p;) {
  722. if ((tm = Getattr(p, "tmap:argout"))) {
  723. Replaceall(tm, "$source", Getattr(p, "lname"));
  724. Replaceall(tm, "$target", Getattr(p, "lname"));
  725. Replaceall(tm, "$arg", Getattr(p, "emit:input"));
  726. Replaceall(tm, "$input", Getattr(p, "emit:input"));
  727. Printv(outarg, tm, "\n", NIL);
  728. if (procdoc) {
  729. if (handle_documentation_typemap(returns_argout, ", ", p, "tmap:argout:doc", "$NAME (of type $type)")) {
  730. /* A documentation typemap that is not the empty string
  731. indicates that a value is returned to Scheme. */
  732. num_results++;
  733. }
  734. }
  735. p = Getattr(p, "tmap:argout:next");
  736. } else {
  737. p = nextSibling(p);
  738. }
  739. }
  740. /* Insert cleanup code */
  741. for (p = l; p;) {
  742. if ((tm = Getattr(p, "tmap:freearg"))) {
  743. Replaceall(tm, "$target", Getattr(p, "lname"));
  744. Replaceall(tm, "$input", Getattr(p, "emit:input"));
  745. Printv(cleanup, tm, "\n", NIL);
  746. p = Getattr(p, "tmap:freearg:next");
  747. } else {
  748. p = nextSibling(p);
  749. }
  750. }
  751. if (use_scm_interface && exporting_destructor) {
  752. /* Mark the destructor's argument as destroyed. */
  753. String *tm = NewString("SWIG_Guile_MarkPointerDestroyed($input);");
  754. Replaceall(tm, "$input", Getattr(l, "emit:input"));
  755. Printv(cleanup, tm, "\n", NIL);
  756. Delete(tm);
  757. }
  758. /* Close prototype */
  759. Printf(f->def, ")\n{\n");
  760. /* Define the scheme name in C. This define is used by several Guile
  761. macros. */
  762. Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
  763. // Now write code to make the function call
  764. if (!use_scm_interface)
  765. Printv(f->code, tab4, "gh_defer_ints();\n", NIL);
  766. String *actioncode = emit_action(n);
  767. if (!use_scm_interface)
  768. Printv(actioncode, tab4, "gh_allow_ints();\n", NIL);
  769. // Now have return value, figure out what to do with it.
  770. if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
  771. Replaceall(tm, "$result", "gswig_result");
  772. Replaceall(tm, "$target", "gswig_result");
  773. Replaceall(tm, "$source", "result");
  774. if (GetFlag(n, "feature:new"))
  775. Replaceall(tm, "$owner", "1");
  776. else
  777. Replaceall(tm, "$owner", "0");
  778. Printv(f->code, tm, "\n", NIL);
  779. } else {
  780. throw_unhandled_guile_type_error(d);
  781. }
  782. emit_return_variable(n, d, f);
  783. // Documentation
  784. if ((tm = Getattr(n, "tmap:out:doc"))) {
  785. Printv(returns, tm, NIL);
  786. if (Len(tm) > 0)
  787. num_results = 1;
  788. else
  789. num_results = 0;
  790. } else {
  791. String *s = SwigType_str(d, 0);
  792. Chop(s);
  793. Printf(returns, "<%s>", s);
  794. Delete(s);
  795. num_results = 1;
  796. }
  797. Append(returns, returns_argout);
  798. // Dump the argument output code
  799. Printv(f->code, outarg, NIL);
  800. // Dump the argument cleanup code
  801. Printv(f->code, cleanup, NIL);
  802. // Look for any remaining cleanup
  803. if (GetFlag(n, "feature:new")) {
  804. if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
  805. Replaceall(tm, "$source", "result");
  806. Printv(f->code, tm, "\n", NIL);
  807. }
  808. }
  809. // Free any memory allocated by the function being wrapped..
  810. if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
  811. Replaceall(tm, "$source", "result");
  812. Printv(f->code, tm, "\n", NIL);
  813. }
  814. // Wrap things up (in a manner of speaking)
  815. if (beforereturn)
  816. Printv(f->code, beforereturn, "\n", NIL);
  817. Printv(f->code, "return gswig_result;\n", NIL);
  818. /* Substitute the function name */
  819. Replaceall(f->code, "$symname", iname);
  820. // Undefine the scheme name
  821. Printf(f->code, "#undef FUNC_NAME\n");
  822. Printf(f->code, "}\n");
  823. Wrapper_print(f, f_wrappers);
  824. if (!Getattr(n, "sym:overloaded")) {
  825. if (numargs > 10) {
  826. int i;
  827. /* gh_new_procedure would complain: too many args */
  828. /* Build a wrapper wrapper */
  829. Printv(f_wrappers, "static SCM\n", wname, "_rest (SCM rest)\n", NIL);
  830. Printv(f_wrappers, "{\n", NIL);
  831. Printf(f_wrappers, "SCM arg[%d];\n", numargs);
  832. Printf(f_wrappers, "SWIG_Guile_GetArgs (arg, rest, %d, %d, \"%s\");\n", numreq, numargs - numreq, proc_name);
  833. Printv(f_wrappers, "return ", wname, "(", NIL);
  834. Printv(f_wrappers, "arg[0]", NIL);
  835. for (i = 1; i < numargs; i++)
  836. Printf(f_wrappers, ", arg[%d]", i);
  837. Printv(f_wrappers, ");\n", NIL);
  838. Printv(f_wrappers, "}\n", NIL);
  839. /* Register it */
  840. if (use_scm_interface) {
  841. Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, 0, 1, (swig_guile_proc) %s_rest);\n", proc_name, wname);
  842. } else {
  843. Printf(f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s_rest, 0, 0, 1);\n", proc_name, wname);
  844. }
  845. } else if (emit_setters && struct_member && strlen(Char(proc_name)) > 3) {
  846. int len = Len(proc_name);
  847. const char *pc = Char(proc_name);
  848. /* MEMBER-set and MEMBER-get functions. */
  849. int is_setter = (pc[len - 3] == 's');
  850. if (is_setter) {
  851. Printf(f_init, "SCM setter = ");
  852. struct_member = 2; /* have a setter */
  853. } else
  854. Printf(f_init, "SCM getter = ");
  855. if (use_scm_interface) {
  856. /* GOOPS support uses the MEMBER-set and MEMBER-get functions,
  857. so ignore only_setters in this case. */
  858. if (only_setters && !goops)
  859. Printf(f_init, "scm_c_make_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname);
  860. else
  861. Printf(f_init, "scm_c_define_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname);
  862. } else {
  863. if (only_setters && !goops)
  864. Printf(f_init, "scm_make_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname);
  865. else
  866. Printf(f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, %d, %d, 0);\n", proc_name, wname, numreq, numargs - numreq);
  867. }
  868. if (!is_setter) {
  869. /* Strip off "-get" */
  870. char *pws_name = (char *) malloc(sizeof(char) * (len - 3));
  871. strncpy(pws_name, pc, len - 3);
  872. pws_name[len - 4] = 0;
  873. if (struct_member == 2) {
  874. /* There was a setter, so create a procedure with setter */
  875. if (use_scm_interface) {
  876. Printf(f_init, "scm_c_define");
  877. } else {
  878. Printf(f_init, "gh_define");
  879. }
  880. Printf(f_init, "(\"%s\", " "scm_make_procedure_with_setter(getter, setter));\n", pws_name);
  881. } else {
  882. /* There was no setter, so make an alias to the getter */
  883. if (use_scm_interface) {
  884. Printf(f_init, "scm_c_define");
  885. } else {
  886. Printf(f_init, "gh_define");
  887. }
  888. Printf(f_init, "(\"%s\", getter);\n", pws_name);
  889. }
  890. Printf(exported_symbols, "\"%s\", ", pws_name);
  891. free(pws_name);
  892. }
  893. } else {
  894. /* Register the function */
  895. if (use_scm_interface) {
  896. if (exporting_destructor) {
  897. Printf(f_init, "((swig_guile_clientdata *)(SWIGTYPE%s->clientdata))->destroy = (guile_destructor) %s;\n", swigtype_ptr, wname);
  898. //Printf(f_init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) %s);\n", swigtype_ptr, wname);
  899. }
  900. Printf(f_init, "scm_c_define_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname);
  901. } else {
  902. Printf(f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, %d, %d, 0);\n", proc_name, wname, numreq, numargs - numreq);
  903. }
  904. }
  905. } else { /* overloaded function; don't export the single methods */
  906. if (!Getattr(n, "sym:nextSibling")) {
  907. /* Emit overloading dispatch function */
  908. int maxargs;
  909. String *dispatch = Swig_overload_dispatch(n, "return %s(argc,argv);", &maxargs);
  910. /* Generate a dispatch wrapper for all overloaded functions */
  911. Wrapper *df = NewWrapper();
  912. String *dname = Swig_name_wrapper(iname);
  913. Printv(df->def, "static SCM\n", dname, "(SCM rest)\n{\n", NIL);
  914. Printf(df->code, "#define FUNC_NAME \"%s\"\n", proc_name);
  915. Printf(df->code, "SCM argv[%d];\n", maxargs);
  916. Printf(df->code, "int argc = SWIG_Guile_GetArgs (argv, rest, %d, %d, \"%s\");\n", 0, maxargs, proc_name);
  917. Printv(df->code, dispatch, "\n", NIL);
  918. Printf(df->code, "scm_misc_error(\"%s\", \"No matching method for generic function `%s'\", SCM_EOL);\n", proc_name, iname);
  919. Printf(df->code, "#undef FUNC_NAME\n");
  920. Printv(df->code, "}\n", NIL);
  921. Wrapper_print(df, f_wrappers);
  922. if (use_scm_interface) {
  923. Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, 0, 1, (swig_guile_proc) %s);\n", proc_name, dname);
  924. } else {
  925. Printf(f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, 0, 1);\n", proc_name, dname);
  926. }
  927. DelWrapper(df);
  928. Delete(dispatch);
  929. Delete(dname);
  930. }
  931. }
  932. Printf(exported_symbols, "\"%s\", ", proc_name);
  933. if (!in_class || memberfunction_name) {
  934. // export wrapper into goops file
  935. String *method_def = NewString("");
  936. String *goops_name;
  937. if (in_class)
  938. goops_name = NewString(memberfunction_name);
  939. else
  940. goops_name = goopsNameMapping(proc_name, (char *) "");
  941. String *primitive_name = NewString("");
  942. if (primRenamer)
  943. Printv(primitive_name, "primitive:", proc_name, NIL);
  944. else
  945. Printv(primitive_name, proc_name, NIL);
  946. Replaceall(method_signature, "_", "-");
  947. Replaceall(primitive_args, "_", "-");
  948. if (!any_specialized_arg) {
  949. /* If there would not be any specialized argument in
  950. the method declaration, we simply re-export the
  951. function. This is a performance optimization. */
  952. Printv(method_def, "(define ", goops_name, " ", primitive_name, ")\n", NIL);
  953. } else if (numreq == numargs) {
  954. Printv(method_def, "(define-method (", goops_name, method_signature, ")\n", NIL);
  955. Printv(method_def, " (", primitive_name, primitive_args, "))\n", NIL);
  956. } else {
  957. /* Handle optional args. For the rest argument, use a name
  958. that cannot clash. */
  959. Printv(method_def, "(define-method (", goops_name, method_signature, " . %args)\n", NIL);
  960. Printv(method_def, " (apply ", primitive_name, primitive_args, " %args))\n", NIL);
  961. }
  962. if (in_class) {
  963. /* Defer method definition till end of class definition. */
  964. Printv(goops_class_methods, method_def, NIL);
  965. } else {
  966. Printv(goopscode, method_def, NIL);
  967. }
  968. Printf(goopsexport, "%s ", goops_name);
  969. Delete(primitive_name);
  970. Delete(goops_name);
  971. Delete(method_def);
  972. }
  973. if (procdoc) {
  974. String *returns_text = NewString("");
  975. if (num_results == 0)
  976. Printv(returns_text, return_nothing_doc, NIL);
  977. else if (num_results == 1)
  978. Printv(returns_text, return_one_doc, NIL);
  979. else
  980. Printv(returns_text, return_multi_doc, NIL);
  981. /* Substitute documentation variables */
  982. static const char *numbers[] = { "zero", "one", "two", "three",
  983. "four", "five", "six", "seven",
  984. "eight", "nine", "ten", "eleven",
  985. "twelve"
  986. };
  987. if (num_results <= 12)
  988. Replaceall(returns_text, "$num_values", numbers[num_results]);
  989. else {
  990. String *num_results_str = NewStringf("%d", num_results);
  991. Replaceall(returns_text, "$num_values", num_results_str);
  992. Delete(num_results_str);
  993. }
  994. Replaceall(returns_text, "$values", returns);
  995. Printf(doc_body, "\n%s", returns_text);
  996. write_doc(proc_name, signature, doc_body);
  997. Delete(returns_text);
  998. }
  999. Delete(proc_name);
  1000. Delete(outarg);
  1001. Delete(cleanup);
  1002. Delete(signature);
  1003. Delete(method_signature);
  1004. Delete(primitive_args);
  1005. Delete(doc_body);
  1006. Delete(returns_argout);
  1007. Delete(returns);
  1008. Delete(tmp);
  1009. Delete(scheme_arg_names);
  1010. DelWrapper(f);
  1011. return SWIG_OK;
  1012. }
  1013. /* ------------------------------------------------------------
  1014. * variableWrapper()
  1015. *
  1016. * Create a link to a C variable.
  1017. * This creates a single function PREFIX_var_VARNAME().
  1018. * This function takes a single optional argument. If supplied, it means
  1019. * we are setting this variable to some value. If omitted, it means we are
  1020. * simply evaluating this variable. Either way, we return the variables
  1021. * value.
  1022. * ------------------------------------------------------------ */
  1023. virtual int variableWrapper(Node *n) {
  1024. char *name = GetChar(n, "name");
  1025. char *iname = GetChar(n, "sym:name");
  1026. SwigType *t = Getattr(n, "type");
  1027. String *proc_name;
  1028. Wrapper *f;
  1029. String *tm;
  1030. if (!addSymbol(iname, n))
  1031. return SWIG_ERROR;
  1032. f = NewWrapper();
  1033. // evaluation function names
  1034. String *var_name = Swig_name_wrapper(iname);
  1035. // Build the name for scheme.
  1036. proc_name = NewString(iname);
  1037. Replaceall(proc_name, "_", "-");
  1038. Setattr(n, "wrap:name", proc_name);
  1039. if (1 || (SwigType_type(t) != T_USER) || (is_a_pointer(t))) {
  1040. Printf(f->def, "static SCM\n%s(SCM s_0)\n{\n", var_name);
  1041. /* Define the scheme name in C. This define is used by several Guile
  1042. macros. */
  1043. Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
  1044. Wrapper_add_local(f, "gswig_result", "SCM gswig_result");
  1045. if (!GetFlag(n, "feature:immutable")) {
  1046. /* Check for a setting of the variable value */
  1047. Printf(f->code, "if (s_0 != SCM_UNDEFINED) {\n");
  1048. if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
  1049. Replaceall(tm, "$source", "s_0");
  1050. Replaceall(tm, "$input", "s_0");
  1051. Replaceall(tm, "$target", name);
  1052. /* Printv(f->code,tm,"\n",NIL); */
  1053. emit_action_code(n, f->code, tm);
  1054. } else {
  1055. throw_unhandled_guile_type_error(t);
  1056. }
  1057. Printf(f->code, "}\n");
  1058. }
  1059. // Now return the value of the variable (regardless
  1060. // of evaluating or setting)
  1061. if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
  1062. Replaceall(tm, "$source", name);
  1063. Replaceall(tm, "$target", "gswig_result");
  1064. Replaceall(tm, "$result", "gswig_result");
  1065. /* Printv(f->code,tm,"\n",NIL); */
  1066. emit_action_code(n, f->code, tm);
  1067. } else {
  1068. throw_unhandled_guile_type_error(t);
  1069. }
  1070. Printf(f->code, "\nreturn gswig_result;\n");
  1071. Printf(f->code, "#undef FUNC_NAME\n");
  1072. Printf(f->code, "}\n");
  1073. Wrapper_print(f, f_wrappers);
  1074. // Now add symbol to the Guile interpreter
  1075. if (!emit_setters || GetFlag(n, "feature:immutable")) {
  1076. /* Read-only variables become a simple procedure returning the
  1077. value; read-write variables become a simple procedure with
  1078. an optional argument. */
  1079. if (use_scm_interface) {
  1080. if (!goops && GetFlag(n, "feature:constasvar")) {
  1081. /* need to export this function as a variable instead of a procedure */
  1082. if (scmstub) {
  1083. /* export the function in the wrapper, and (set!) it in scmstub */
  1084. Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, %d, 0, (swig_guile_proc) %s);\n", proc_name, !GetFlag(n, "feature:immutable"), var_name);
  1085. Printf(scmtext, "(set! %s (%s))\n", proc_name, proc_name);
  1086. } else {
  1087. /* export the variable directly */
  1088. Printf(f_init, "scm_c_define(\"%s\", %s(SCM_UNDEFINED));\n", proc_name, var_name);
  1089. }
  1090. } else {
  1091. /* Export the function as normal */
  1092. Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, %d, 0, (swig_guile_proc) %s);\n", proc_name, !GetFlag(n, "feature:immutable"), var_name);
  1093. }
  1094. } else {
  1095. Printf(f_init, "\t gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, %d, 0);\n", proc_name, var_name, !GetFlag(n, "feature:immutable"));
  1096. }
  1097. } else {
  1098. /* Read/write variables become a procedure with setter. */
  1099. if (use_scm_interface) {
  1100. Printf(f_init, "{ SCM p = scm_c_define_gsubr(\"%s\", 0, 1, 0, (swig_guile_proc) %s);\n", proc_name, var_name);
  1101. Printf(f_init, "scm_c_define");
  1102. } else {
  1103. Printf(f_init, "\t{ SCM p = gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, 1, 0);\n", proc_name, var_name);
  1104. Printf(f_init, "gh_define");
  1105. }
  1106. Printf(f_init, "(\"%s\", " "scm_make_procedure_with_setter(p, p)); }\n", proc_name);
  1107. }
  1108. Printf(exported_symbols, "\"%s\", ", proc_name);
  1109. // export wrapper into goops file
  1110. if (!in_class) { // only if the variable is not part of a class
  1111. String *class_name = SwigType_typedef_resolve_all(SwigType_base(t));
  1112. String *goops_name = goopsNameMapping(proc_name, (char *) "");
  1113. String *primitive_name = NewString("");
  1114. if (primRenamer)
  1115. Printv(primitive_name, "primitive:", NIL);
  1116. Printv(primitive_name, proc_name, NIL);
  1117. /* Simply re-export the procedure */
  1118. if ((!emit_setters || GetFlag(n, "feature:immutable"))
  1119. && GetFlag(n, "feature:constasvar")) {
  1120. Printv(goopscode, "(define ", goops_name, " (", primitive_name, "))\n", NIL);
  1121. } else {
  1122. Printv(goopscode, "(define ", goops_name, " ", primitive_name, ")\n", NIL);
  1123. }
  1124. Printf(goopsexport, "%s ", goops_name);
  1125. Delete(primitive_name);
  1126. Delete(class_name);
  1127. Delete(goops_name);
  1128. }
  1129. if (procdoc) {
  1130. /* Compute documentation */
  1131. String *signature = NewString("");
  1132. String *signature2 = NULL;
  1133. String *doc = NewString("");
  1134. if (GetFlag(n, "feature:immutable")) {
  1135. Printv(signature, proc_name, NIL);
  1136. if (GetFlag(n, "feature:constasvar")) {
  1137. Printv(doc, "Is constant ", NIL);
  1138. } else {
  1139. Printv(doc, "Returns constant ", NIL);
  1140. }
  1141. if ((tm = Getattr(n, "tmap:varout:doc"))) {
  1142. Printv(doc, tm, NIL);
  1143. } else {
  1144. String *s = SwigType_str(t, 0);
  1145. Chop(s);
  1146. Printf(doc, "<%s>", s);
  1147. Delete(s);
  1148. }
  1149. } else if (emit_setters) {
  1150. Printv(signature, proc_name, NIL);
  1151. signature2 = NewString("");
  1152. Printv(signature2, "set! (", proc_name, ") ", NIL);
  1153. handle_documentation_typemap(signature2, NIL, n, "tmap:varin:arglist", "new-value");
  1154. Printv(doc, "Get or set the value of the C variable, \n", NIL);
  1155. Printv(doc, "which is of type ", NIL);
  1156. handle_documentation_typemap(doc, NIL, n, "tmap:varout:doc", "$1_type");
  1157. Printv(doc, ".");
  1158. } else {
  1159. Printv(signature, proc_name, " #:optional ", NIL);
  1160. if ((tm = Getattr(n, "tmap:varin:doc"))) {
  1161. Printv(signature, tm, NIL);
  1162. } else {
  1163. String *s = SwigType_str(t, 0);
  1164. Chop(s);
  1165. Printf(signature, "new-value <%s>", s);
  1166. Delete(s);
  1167. }
  1168. Printv(doc, "If NEW-VALUE is provided, " "set C variable to this value.\n", NIL);
  1169. Printv(doc, "Returns variable value ", NIL);
  1170. if ((tm = Getattr(n, "tmap:varout:doc"))) {
  1171. Printv(doc, tm, NIL);
  1172. } else {
  1173. String *s = SwigType_str(t, 0);
  1174. Chop(s);
  1175. Printf(doc, "<%s>", s);
  1176. Delete(s);
  1177. }
  1178. }
  1179. write_doc(proc_name, signature, doc, signature2);
  1180. Delete(signature);
  1181. if (signature2)
  1182. Delete(signature2);
  1183. Delete(doc);
  1184. }
  1185. } else {
  1186. Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t, 0));
  1187. }
  1188. Delete(var_name);
  1189. Delete(proc_name);
  1190. DelWrapper(f);
  1191. return SWIG_OK;
  1192. }
  1193. /* ------------------------------------------------------------
  1194. * constantWrapper()
  1195. *
  1196. * We create a read-only variable.
  1197. * ------------------------------------------------------------ */
  1198. virtual int constantWrapper(Node *n) {
  1199. char *name = GetChar(n, "name");
  1200. char *iname = GetChar(n, "sym:name");
  1201. SwigType *type = Getattr(n, "type");
  1202. String *value = Getattr(n, "value");
  1203. int constasvar = GetFlag(n, "feature:constasvar");
  1204. String *proc_name;
  1205. String *var_name;
  1206. String *rvalue;
  1207. Wrapper *f;
  1208. SwigType *nctype;
  1209. String *tm;
  1210. f = NewWrapper();
  1211. // Make a static variable;
  1212. var_name = NewStringf("%sconst_%s", prefix, iname);
  1213. // Strip const qualifier from type if present
  1214. nctype = NewString(type);
  1215. if (SwigType_isconst(nctype)) {
  1216. Delete(SwigType_pop(nctype));
  1217. }
  1218. // Build the name for scheme.
  1219. proc_name = NewString(iname);
  1220. Replaceall(proc_name, "_", "-");
  1221. if ((SwigType_type(nctype) == T_USER) && (!is_a_pointer(nctype))) {
  1222. Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
  1223. Delete(var_name);
  1224. DelWrapper(f);
  1225. return SWIG_NOWRAP;
  1226. }
  1227. // See if there's a typemap
  1228. if (SwigType_type(nctype) == T_STRING) {
  1229. rvalue = NewStringf("\"%s\"", value);
  1230. } else if (SwigType_type(nctype) == T_CHAR) {
  1231. rvalue = NewStringf("\'%s\'", value);
  1232. } else {
  1233. rvalue = NewString(value);
  1234. }
  1235. if ((tm = Swig_typemap_lookup("constant", n, name, 0))) {
  1236. Replaceall(tm, "$source", rvalue);
  1237. Replaceall(tm, "$value", rvalue);
  1238. Replaceall(tm, "$target", name);
  1239. Printv(f_header, tm, "\n", NIL);
  1240. } else {
  1241. // Create variable and assign it a value
  1242. Printf(f_header, "static %s = %s;\n", SwigType_lstr(nctype, var_name), rvalue);
  1243. }
  1244. {
  1245. /* Hack alert: will cleanup later -- Dave */
  1246. Node *n = NewHash();
  1247. Setattr(n, "name", var_name);
  1248. Setattr(n, "sym:name", iname);
  1249. Setattr(n, "type", nctype);
  1250. SetFlag(n, "feature:immutable");
  1251. if (constasvar) {
  1252. SetFlag(n, "feature:constasvar");
  1253. }
  1254. variableWrapper(n);
  1255. Delete(n);
  1256. }
  1257. Delete(var_name);
  1258. Delete(nctype);
  1259. Delete(proc_name);
  1260. Delete(rvalue);
  1261. DelWrapper(f);
  1262. return SWIG_OK;
  1263. }
  1264. /* ------------------------------------------------------------
  1265. * classDeclaration()
  1266. * ------------------------------------------------------------ */
  1267. virtual int classDeclaration(Node *n) {
  1268. String *class_name = NewStringf("<%s>", Getattr(n, "sym:name"));
  1269. Setattr(n, "guile:goopsclassname", class_name);
  1270. return Language::classDeclaration(n);
  1271. }
  1272. /* ------------------------------------------------------------
  1273. * classHandler()
  1274. * ------------------------------------------------------------ */
  1275. virtual int classHandler(Node *n) {
  1276. /* Create new strings for building up a wrapper function */
  1277. have_constructor = 0;
  1278. class_name = NewString("");
  1279. short_class_name = NewString("");
  1280. Printv(class_name, "<", Getattr(n, "sym:name"), ">", NIL);
  1281. Printv(short_class_name, Getattr(n, "sym:name"), NIL);
  1282. Replaceall(class_name, "_", "-");
  1283. Replaceall(short_class_name, "_", "-");
  1284. if (!addSymbol(class_name, n))
  1285. return SWIG_ERROR;
  1286. /* Handle inheritance */
  1287. String *base_class = NewString("<");
  1288. List *baselist = Getattr(n, "bases");
  1289. if (baselist && Len(baselist)) {
  1290. Iterator i = First(baselist);
  1291. while (i.item) {
  1292. Printv(base_class, Getattr(i.item, "sym:name"), NIL);
  1293. i = Next(i);
  1294. if (i.item) {
  1295. Printf(base_class, "> <");
  1296. }
  1297. }
  1298. }
  1299. Printf(base_class, ">");
  1300. Replaceall(base_class, "_", "-");
  1301. Printv(goopscode, "(define-class ", class_name, " ", NIL);
  1302. Printf(goopsexport, "%s ", class_name);
  1303. if (Len(base_class) > 2) {
  1304. Printv(goopscode, "(", base_class, ")\n", NIL);
  1305. } else {
  1306. Printv(goopscode, "(<swig>)\n", NIL);
  1307. }
  1308. SwigType *ct = NewStringf("p.%s", Getattr(n, "name"));
  1309. swigtype_ptr = SwigType_manglestr(ct);
  1310. String *mangled_classname = Swig_name_mangle(Getattr(n, "sym:name"));
  1311. /* Export clientdata structure */
  1312. if (use_scm_interface) {
  1313. Printf(f_runtime, "static swig_guile_clientdata _swig_guile_clientdata%s = { NULL, SCM_EOL };\n", mangled_classname);
  1314. Printv(f_init, "SWIG_TypeClientData(SWIGTYPE", swigtype_ptr, ", (void *) &_swig_guile_clientdata", mangled_classname, ");\n", NIL);
  1315. SwigType_remember(ct);
  1316. }
  1317. Delete(ct);
  1318. /* Emit all of the members */
  1319. goops_class_methods = NewString("");
  1320. in_class = 1;
  1321. Language::classHandler(n);
  1322. in_class = 0;
  1323. Printv(goopscode, " #:metaclass <swig-metaclass>\n", NIL);
  1324. if (have_constructor)
  1325. Printv(goopscode, " #:new-function ", primRenamer ? "primitive:" : "", "new-", short_class_name, "\n", NIL);
  1326. Printf(goopscode, ")\n%s\n", goops_class_methods);
  1327. Delete(goops_class_methods);
  1328. goops_class_methods = 0;
  1329. /* export class initialization function */
  1330. if (goops) {
  1331. /* export the wrapper function */
  1332. String *funcName = NewString(mangled_classname);
  1333. Printf(funcName, "_swig_guile_setgoopsclass");
  1334. String *guileFuncName = NewString(funcName);
  1335. Replaceall(guileFuncName, "_", "-");
  1336. Printv(f_wrappers, "static SCM ", funcName, "(SCM cl) \n", NIL);
  1337. Printf(f_wrappers, "#define FUNC_NAME %s\n{\n", guileFuncName);
  1338. Printv(f_wrappers, " ((swig_guile_clientdata *)(SWIGTYPE", swigtype_ptr, "->clientdata))->goops_class = cl;\n", NIL);
  1339. Printf(f_wrappers, " return SCM_UNSPECIFIED;\n");
  1340. Printf(f_wrappers, "}\n#undef FUNC_NAME\n\n");
  1341. Printf(f_init, "scm_c_define_gsubr(\"%s\", 1, 0, 0, (swig_guile_proc) %s);\n", guileFuncName, funcName);
  1342. Printf(exported_symbols, "\"%s\", ", guileFuncName);
  1343. /* export the call to the wrapper function */
  1344. Printf(goopscode, "(%s%s %s)\n\n", primRenamer ? "primitive:" : "", guileFuncName, class_name);
  1345. Delete(guileFuncName);
  1346. Delete(funcName);
  1347. }
  1348. Delete(mangled_classname);
  1349. Delete(swigtype_ptr);
  1350. swigtype_ptr = 0;
  1351. Delete(class_name);
  1352. Delete(short_class_name);
  1353. class_name = 0;
  1354. short_class_name = 0;
  1355. return SWIG_OK;
  1356. }
  1357. /* ------------------------------------------------------------
  1358. * memberfunctionHandler()
  1359. * ------------------------------------------------------------ */
  1360. int memberfunctionHandler(Node *n) {
  1361. String *iname = Getattr(n, "sym:name");
  1362. String *proc = NewString(iname);
  1363. Replaceall(proc, "_", "-");
  1364. memberfunction_name = goopsNameMapping(proc, short_class_name);
  1365. Language::memberfunctionHandler(n);
  1366. Delete(memberfunction_name);
  1367. memberfunction_name = NULL;
  1368. Delete(proc);
  1369. return SWIG_OK;
  1370. }
  1371. /* ------------------------------------------------------------
  1372. * membervariableHandler()
  1373. * ------------------------------------------------------------ */
  1374. int membervariableHandler(Node *n) {
  1375. String *iname = Getattr(n, "sym:name");
  1376. if (emit_setters) {
  1377. struct_member = 1;
  1378. Printf(f_init, "{\n");
  1379. }
  1380. Language::membervariableHandler(n);
  1381. if (emit_setters) {
  1382. Printf(f_init, "}\n");
  1383. struct_member = 0;
  1384. }
  1385. String *proc = NewString(iname);
  1386. Replaceall(proc, "_", "-");
  1387. String *goops_name = goopsNameMapping(proc, short_class_name);
  1388. /* The slot name is never qualified with the class,
  1389. even if useclassprefix is true. */
  1390. Printv(goopscode, " (", proc, " #:allocation #:virtual", NIL);
  1391. /* GOOPS (at least in Guile 1.6.3) only accepts closures, not
  1392. primitive procedures for slot-ref and slot-set. */
  1393. Printv(goopscode, "\n #:slot-ref (lambda (obj) (", primRenamer ? "primitive:" : "", short_class_name, "-", proc, "-get", " obj))", NIL);
  1394. if (!GetFlag(n, "feature:immutable")) {
  1395. Printv(goopscode, "\n #:slot-set! (lambda (obj value) (", primRenamer ? "primitive:" : "", short_class_name, "-", proc, "-set", " obj value))", NIL);
  1396. } else {
  1397. Printf(goopscode, "\n #:slot-set! (lambda (obj value) (error \"Immutable slot\"))");
  1398. }
  1399. if (emit_slot_accessors) {
  1400. if (GetFlag(n, "feature:immutable")) {
  1401. Printv(goopscode, "\n #:getter ", goops_name, NIL);
  1402. } else {
  1403. Printv(goopscode, "\n #:accessor ", goops_name, NIL);
  1404. }
  1405. Printf(goopsexport, "%s ", goops_name);
  1406. }
  1407. Printv(goopscode, ")\n", NIL);
  1408. Delete(proc);
  1409. Delete(goops_name);
  1410. return SWIG_OK;
  1411. }
  1412. /* ------------------------------------------------------------
  1413. * constructorHandler()
  1414. * ------------------------------------------------------------ */
  1415. int constructorHandler(Node *n) {
  1416. Language::constructorHandler(n);
  1417. have_constructor = 1;
  1418. return SWIG_OK;
  1419. }
  1420. /* ------------------------------------------------------------
  1421. * destructorHandler()
  1422. * ------------------------------------------------------------ */
  1423. virtual int destructorHandler(Node *n) {
  1424. exporting_destructor = true;
  1425. Language::destructorHandler(n);
  1426. exporting_destructor = false;
  1427. return SWIG_OK;
  1428. }
  1429. /* ------------------------------------------------------------
  1430. * pragmaDirective()
  1431. * ------------------------------------------------------------ */
  1432. virtual int pragmaDirective(Node *n) {
  1433. if (!ImportMode) {
  1434. String *lang = Getattr(n, "lang");
  1435. String *cmd = Getattr(n, "name");
  1436. String *value = Getattr(n, "value");
  1437. # define store_pragma(PRAGMANAME) \
  1438. if (Strcmp(cmd, #PRAGMANAME) == 0) { \
  1439. if (PRAGMANAME) Delete(PRAGMANAME); \
  1440. PRAGMANAME = value ? NewString(value) : NULL; \
  1441. }
  1442. if (Strcmp(lang, "guile") == 0) {
  1443. store_pragma(beforereturn)
  1444. store_pragma(return_nothing_doc)
  1445. store_pragma(return_one_doc)
  1446. store_pragma(return_multi_doc);
  1447. # undef store_pragma
  1448. }
  1449. }
  1450. return Language::pragmaDirective(n);
  1451. }
  1452. /* ------------------------------------------------------------
  1453. * goopsNameMapping()
  1454. * Maps the identifier from C++ to the GOOPS based * on command
  1455. * line parameters and such.
  1456. * If class_name = "" that means the mapping is for a function or
  1457. * variable not attached to any class.
  1458. * ------------------------------------------------------------ */
  1459. String *goopsNameMapping(String *name, String_or_char *class_name) {
  1460. String *n = NewString("");
  1461. if (Strcmp(class_name, "") == 0) {
  1462. // not part of a class, so no class name to prefix
  1463. if (goopsprefix) {
  1464. Printf(n, "%s%s", goopsprefix, name);
  1465. } else {
  1466. Printf(n, "%s", name);
  1467. }
  1468. } else {
  1469. if (useclassprefix) {
  1470. Printf(n, "%s-%s", class_name, name);
  1471. } else {
  1472. if (goopsprefix) {
  1473. Printf(n, "%s%s", goopsprefix, name);
  1474. } else {
  1475. Printf(n, "%s", name);
  1476. }
  1477. }
  1478. }
  1479. return n;
  1480. }
  1481. /* ------------------------------------------------------------
  1482. * validIdentifier()
  1483. * ------------------------------------------------------------ */
  1484. virtual int validIdentifier(String *s) {
  1485. char *c = Char(s);
  1486. /* Check whether we have an R5RS identifier. Guile supports a
  1487. superset of R5RS identifiers, but it's probably a bad idea to use
  1488. those. */
  1489. /* <identifier> --> <initial> <subsequent>* | <peculiar identifier> */
  1490. /* <initial> --> <letter> | <special initial> */
  1491. if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%')
  1492. || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
  1493. || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
  1494. || (*c == '^') || (*c == '_') || (*c == '~'))) {
  1495. /* <peculiar identifier> --> + | - | ... */
  1496. if ((strcmp(c, "+") == 0)
  1497. || strcmp(c, "-") == 0 || strcmp(c, "...") == 0)
  1498. return 1;
  1499. else
  1500. return 0;
  1501. }
  1502. /* <subsequent> --> <initial> | <digit> | <special subsequent> */
  1503. while (*c) {
  1504. if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%')
  1505. || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
  1506. || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
  1507. || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+')
  1508. || (*c == '-') || (*c == '.') || (*c == '@')))
  1509. return 0;
  1510. c++;
  1511. }
  1512. return 1;
  1513. }
  1514. String *runtimeCode() {
  1515. String *s;
  1516. if (use_scm_interface) {
  1517. s = Swig_include_sys("guile_scm_run.swg");
  1518. if (!s) {
  1519. Printf(stderr, "*** Unable to open 'guile_scm_run.swg");
  1520. s = NewString("");
  1521. }
  1522. } else {
  1523. s = Swig_include_sys("guile_gh_run.swg");
  1524. if (!s) {
  1525. Printf(stderr, "*** Unable to open 'guile_gh_run.swg");
  1526. s = NewString("");
  1527. }
  1528. }
  1529. return s;
  1530. }
  1531. String *defaultExternalRuntimeFilename() {
  1532. if (use_scm_interface) {
  1533. return NewString("swigguilerun.h");
  1534. } else {
  1535. return NewString("swigguileghrun.h");
  1536. }
  1537. }
  1538. };
  1539. /* -----------------------------------------------------------------------------
  1540. * swig_guile() - Instantiate module
  1541. * ----------------------------------------------------------------------------- */
  1542. static Language *new_swig_guile() {
  1543. return new GUILE();
  1544. }
  1545. extern "C" Language *swig_guile(void) {
  1546. return new_swig_guile();
  1547. }