PageRenderTime 56ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 1ms

/branches/gsoc2008-cherylfoil/Source/Modules/guile.cxx

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

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