PageRenderTime 83ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

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

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

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