PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/ttn-pre-libtool-1-4-3-upgrade/SWIG/Source/Modules1.1/guile.cxx

#
C++ | 1209 lines | 916 code | 149 blank | 144 comment | 282 complexity | 917b6d47dd211e8f26386e674643e174 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1. /******************************************************************************
  2. * Simplified Wrapper and Interface Generator (SWIG)
  3. *
  4. * Author : David Beazley
  5. *
  6. * Department of Computer Science
  7. * University of Chicago
  8. * 1100 E 58th Street
  9. * Chicago, IL 60637
  10. * beazley@cs.uchicago.edu
  11. *
  12. * Please read the file LICENSE for the copyright and terms by which SWIG
  13. * can be used and distributed.
  14. *****************************************************************************/
  15. static char cvsroot[] = "$Header$";
  16. /***********************************************************************
  17. * $Header$
  18. *
  19. * guile.cxx
  20. *
  21. * Definitions for adding functions to Guile
  22. ***********************************************************************/
  23. #include "swigmod.h"
  24. #ifndef MACSWIG
  25. #include "swigconfig.h"
  26. #endif
  27. #include <ctype.h>
  28. static char *guile_usage = (char*)"\
  29. Guile Options (available with -guile)\n\
  30. -ldflags - Print runtime libraries to link with\n\
  31. -prefix name - Use NAME as prefix [default \"gswig_\"]\n\
  32. -package name - Set the path of the module [default NULL]\n\
  33. -emit-setters - Emit procedures-with-setters for variables\n\
  34. and structure slots.\n\
  35. -linkage lstyle - Use linkage protocol LSTYLE [default `module']\n\
  36. -procdoc file - Output procedure documentation to FILE\n\
  37. -procdocformat format - Output procedure documentation in FORMAT;\n\
  38. one of `guile-1.4', `plain', `texinfo'\n\
  39. -scmstub file - Output Scheme FILE with module declaration and\n\
  40. exports; only with `passive' and `simple' linkage\n\
  41. \n\
  42. When unspecified, the default LSTYLE is `simple'. For native Guile\n\
  43. module linking (for Guile versions >=1.5.0), use `module'. Other\n\
  44. LSTYLE values are: `passive' for passive linking (no C-level\n\
  45. module-handling code), `ltdlmod' for Guile's old dynamic module\n\
  46. convention (versions <= 1.4), or `hobbit' for hobbit modules.\n\
  47. \n";
  48. static File *f_runtime = 0;
  49. static File *f_header = 0;
  50. static File *f_wrappers = 0;
  51. static File *f_init = 0;
  52. static char *prefix = (char *) "gswig_";
  53. static char *module = 0;
  54. static char *package = 0;
  55. static enum {
  56. GUILE_LSTYLE_SIMPLE, // call `SWIG_init()'
  57. GUILE_LSTYLE_PASSIVE, // passive linking (no module code)
  58. GUILE_LSTYLE_MODULE, // native guile module linking (Guile >= 1.4.1)
  59. GUILE_LSTYLE_LTDLMOD_1_4, // old (Guile <= 1.4) dynamic module convention
  60. GUILE_LSTYLE_HOBBIT // use (hobbit4d link)
  61. } linkage = GUILE_LSTYLE_SIMPLE;
  62. static File *procdoc = 0;
  63. static File *scmstub = 0;
  64. static String *scmtext;
  65. static enum {
  66. GUILE_1_4,
  67. PLAIN,
  68. TEXINFO
  69. } docformat = GUILE_1_4;
  70. static int emit_setters = 0;
  71. static int struct_member = 0;
  72. static String *beforereturn = 0;
  73. static String *return_nothing_doc = 0;
  74. static String *return_one_doc = 0;
  75. static String *return_multi_doc = 0;
  76. static String *exported_symbols = 0;
  77. class GUILE : public Language {
  78. public:
  79. /* ------------------------------------------------------------
  80. * main()
  81. * ------------------------------------------------------------ */
  82. virtual void main (int argc, char *argv[]) {
  83. int i, orig_len;
  84. SWIG_library_directory("guile");
  85. SWIG_typemap_lang("guile");
  86. // Look for certain command line options
  87. for (i = 1; i < argc; i++) {
  88. if (argv[i]) {
  89. if (strcmp (argv[i], "-help") == 0) {
  90. fputs (guile_usage, stderr);
  91. SWIG_exit (EXIT_SUCCESS);
  92. }
  93. else if (strcmp (argv[i], "-prefix") == 0) {
  94. if (argv[i + 1]) {
  95. prefix = new char[strlen (argv[i + 1]) + 2];
  96. strcpy (prefix, argv[i + 1]);
  97. Swig_mark_arg (i);
  98. Swig_mark_arg (i + 1);
  99. i++;
  100. } else {
  101. Swig_arg_error();
  102. }
  103. }
  104. else if (strcmp (argv[i], "-package") == 0) {
  105. if (argv[i + 1]) {
  106. package = new char[strlen (argv[i + 1]) + 2];
  107. strcpy (package, argv [i + 1]);
  108. Swig_mark_arg (i);
  109. Swig_mark_arg (i + 1);
  110. i++;
  111. } else {
  112. Swig_arg_error();
  113. }
  114. }
  115. else if (strcmp (argv[i], "-ldflags") == 0) {
  116. printf("%s\n", SWIG_GUILE_RUNTIME);
  117. SWIG_exit (EXIT_SUCCESS);
  118. }
  119. else if (strcmp (argv[i], "-Linkage") == 0
  120. || strcmp (argv[i], "-linkage") == 0) {
  121. if (argv[i + 1]) {
  122. if (0 == strcmp (argv[i + 1], "ltdlmod"))
  123. linkage = GUILE_LSTYLE_LTDLMOD_1_4;
  124. else if (0 == strcmp (argv[i + 1], "hobbit"))
  125. linkage = GUILE_LSTYLE_HOBBIT;
  126. else if (0 == strcmp (argv[i + 1], "simple"))
  127. linkage = GUILE_LSTYLE_SIMPLE;
  128. else if (0 == strcmp (argv[i + 1], "passive"))
  129. linkage = GUILE_LSTYLE_PASSIVE;
  130. else if (0 == strcmp (argv[i + 1], "module"))
  131. linkage = GUILE_LSTYLE_MODULE;
  132. else
  133. Swig_arg_error ();
  134. Swig_mark_arg (i);
  135. Swig_mark_arg (i + 1);
  136. i++;
  137. } else {
  138. Swig_arg_error();
  139. }
  140. }
  141. else if (strcmp (argv[i], "-procdoc") == 0) {
  142. if (argv[i + 1]) {
  143. procdoc = NewFile(argv[i + 1], (char *) "w");
  144. Swig_mark_arg (i);
  145. Swig_mark_arg (i + 1);
  146. i++;
  147. } else {
  148. Swig_arg_error();
  149. }
  150. }
  151. else if (strcmp (argv[i], "-procdocformat") == 0) {
  152. if (strcmp(argv[i+1], "guile-1.4") == 0)
  153. docformat = GUILE_1_4;
  154. else if (strcmp(argv[i+1], "plain") == 0)
  155. docformat = PLAIN;
  156. else if (strcmp(argv[i+1], "texinfo") == 0)
  157. docformat = TEXINFO;
  158. else Swig_arg_error();
  159. Swig_mark_arg(i);
  160. Swig_mark_arg(i+1);
  161. i++;
  162. }
  163. else if (strcmp (argv[i], "-emit-setters") == 0) {
  164. emit_setters = 1;
  165. Swig_mark_arg (i);
  166. }
  167. else if (strcmp (argv[i], "-scmstub") == 0) {
  168. if (argv[i + 1]) {
  169. scmstub = NewFile(argv[i + 1], (char *) "w");
  170. Swig_mark_arg (i);
  171. Swig_mark_arg (i + 1);
  172. i++;
  173. } else {
  174. Swig_arg_error();
  175. }
  176. }
  177. }
  178. }
  179. // Make sure `prefix' ends in an underscore
  180. orig_len = strlen (prefix);
  181. if (prefix[orig_len - 1] != '_') {
  182. prefix[1 + orig_len] = 0;
  183. prefix[orig_len] = '_';
  184. }
  185. /* Add a symbol for this module */
  186. Preprocessor_define ("SWIGGUILE 1",0);
  187. /* Read in default typemaps */
  188. SWIG_config_file("guile.i");
  189. allow_overloading();
  190. }
  191. /* ------------------------------------------------------------
  192. * top()
  193. * ------------------------------------------------------------ */
  194. virtual int top(Node *n) {
  195. /* Initialize all of the output files */
  196. String *outfile = Getattr(n,"outfile");
  197. f_runtime = NewFile(outfile,"w");
  198. if (!f_runtime) {
  199. Printf(stderr,"*** Can't open '%s'\n", outfile);
  200. SWIG_exit(EXIT_FAILURE);
  201. }
  202. f_init = NewString("");
  203. f_header = NewString("");
  204. f_wrappers = NewString("");
  205. /* Register file targets with the SWIG file handler */
  206. Swig_register_filebyname("header",f_header);
  207. Swig_register_filebyname("wrapper",f_wrappers);
  208. Swig_register_filebyname("runtime",f_runtime);
  209. Swig_register_filebyname("init",f_init);
  210. scmtext = NewString("");
  211. Swig_register_filebyname("scheme", scmtext);
  212. exported_symbols = NewString("");
  213. Printf(f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n");
  214. Swig_banner (f_runtime);
  215. Printf (f_runtime, "/* Implementation : GUILE */\n\n");
  216. /* Write out directives and declarations */
  217. if (NoInclude) {
  218. Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
  219. }
  220. module = Swig_copy_string(Char(Getattr(n,"name")));
  221. if (CPlusPlus) {
  222. Printf(f_runtime, "extern \"C\" {\n\n");
  223. }
  224. switch (linkage) {
  225. case GUILE_LSTYLE_SIMPLE:
  226. /* Simple linkage; we have to export the SWIG_init function. The user can
  227. rename the function by a #define. */
  228. Printf (f_runtime, "extern void\nSWIG_init (void)\n;\n");
  229. Printf (f_init, "extern void\nSWIG_init (void)\n{\n");
  230. break;
  231. default:
  232. /* Other linkage; we make the SWIG_init function static */
  233. Printf (f_runtime, "static void\nSWIG_init (void)\n;\n");
  234. Printf (f_init, "static void\nSWIG_init (void)\n{\n");
  235. break;
  236. }
  237. Printf (f_init, "\tSWIG_Guile_Init();\n");
  238. if (CPlusPlus) {
  239. Printf(f_runtime, "\n}\n");
  240. }
  241. Language::top(n);
  242. /* Close module */
  243. Printf(f_wrappers,"#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
  244. SwigType_emit_type_table (f_runtime, f_wrappers);
  245. Printf(f_wrappers,"#ifdef __cplusplus\n}\n#endif\n");
  246. Printf (f_init, "SWIG_Guile_RegisterTypes(swig_types, swig_types_initial);\n");
  247. Printf (f_init, "}\n\n");
  248. char module_name[256];
  249. if (!module)
  250. sprintf(module_name, "swig");
  251. else {
  252. if (package)
  253. sprintf(module_name,"%s/%s", package,module);
  254. else
  255. strcpy(module_name,module);
  256. }
  257. emit_linkage (module_name);
  258. if (procdoc) {
  259. Delete(procdoc);
  260. procdoc = NULL;
  261. }
  262. if (scmstub) {
  263. Delete(scmstub);
  264. scmstub = NULL;
  265. }
  266. /* Close all of the files */
  267. Dump(f_header,f_runtime);
  268. Dump(f_wrappers,f_runtime);
  269. Wrapper_pretty_print(f_init,f_runtime);
  270. Delete(f_header);
  271. Delete(f_wrappers);
  272. Delete(f_init);
  273. Close(f_runtime);
  274. Delete(f_runtime);
  275. return SWIG_OK;
  276. }
  277. void emit_linkage (char *module_name) {
  278. String *module_func = NewString("");
  279. if (CPlusPlus) {
  280. Printf(f_init, "extern \"C\" {\n\n");
  281. }
  282. Printv(module_func,module_name,NIL);
  283. Replaceall(module_func,"-", "_");
  284. switch (linkage) {
  285. case GUILE_LSTYLE_SIMPLE:
  286. Printf (f_init, "\n/* Linkage: simple */\n");
  287. break;
  288. case GUILE_LSTYLE_PASSIVE:
  289. Printf (f_init, "\n/* Linkage: passive */\n");
  290. Replaceall(module_func,"/", "_");
  291. Insert(module_func,0, "scm_init_");
  292. Append(module_func,"_module");
  293. Printf (f_init, "SCM\n%s (void)\n{\n", module_func);
  294. Printf (f_init, " SWIG_init();\n");
  295. Printf (f_init, " return SCM_UNSPECIFIED;\n");
  296. Printf (f_init, "}\n");
  297. break;
  298. case GUILE_LSTYLE_LTDLMOD_1_4:
  299. Printf (f_init, "\n/* Linkage: ltdlmod */\n");
  300. Replaceall(module_func,"/", "_");
  301. Insert(module_func,0, "scm_init_");
  302. Append(module_func,"_module");
  303. Printf (f_init, "SCM\n%s (void)\n{\n", module_func);
  304. {
  305. String *mod = NewString(module_name);
  306. Replaceall(mod,"/", " ");
  307. Printf (f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n",
  308. mod);
  309. Printf (f_init, " return SCM_UNSPECIFIED;\n");
  310. Delete(mod);
  311. }
  312. Printf (f_init, "}\n");
  313. break;
  314. case GUILE_LSTYLE_MODULE:
  315. Printf (f_init, "\n/* Linkage: module */\n");
  316. Replaceall(module_func,"/", "_");
  317. Insert(module_func,0, "scm_init_");
  318. Append(module_func,"_module");
  319. Printf (f_init, "static void SWIG_init_helper(void *data)\n");
  320. Printf (f_init, "{\n SWIG_init();\n");
  321. if (Len(exported_symbols) > 0)
  322. Printf (f_init, " scm_c_export(%sNULL);",
  323. exported_symbols);
  324. Printf (f_init, "\n}\n\n");
  325. Printf (f_init, "SCM\n%s (void)\n{\n", module_func);
  326. {
  327. String *mod = NewString(module_name);
  328. Replaceall(mod,"/", " ");
  329. Printf(f_init, " SCM module = scm_c_define_module(\"%s\",\n", mod);
  330. Printf(f_init, " SWIG_init_helper, NULL);\n");
  331. Printf(f_init, " return SCM_UNSPECIFIED;\n");
  332. Delete(mod);
  333. }
  334. Printf (f_init, "}\n");
  335. break;
  336. case GUILE_LSTYLE_HOBBIT:
  337. Printf (f_init, "\n/* Linkage: hobbit */\n");
  338. Replaceall(module_func,"/", "_slash_");
  339. Insert(module_func,0, "scm_init_");
  340. Printf (f_init, "SCM\n%s (void)\n{\n", module_func);
  341. {
  342. String *mod = NewString(module_name);
  343. Replaceall(mod,"/", " ");
  344. Printf (f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n",
  345. mod);
  346. Printf (f_init, " return SCM_UNSPECIFIED;\n");
  347. Delete(mod);
  348. }
  349. Printf (f_init, "}\n");
  350. break;
  351. default:
  352. abort(); // for now
  353. }
  354. if (scmstub) {
  355. /* Emit Scheme stub if requested */
  356. String *mod = NewString(module_name);
  357. Replaceall(mod, "/", " ");
  358. Printf (scmstub, ";;; -*- buffer-read-only: t -*- vi: set ro: */\n");
  359. Printf (scmstub, ";;; Automatically generated by SWIG; do not edit.\n\n");
  360. if (linkage == GUILE_LSTYLE_SIMPLE
  361. || linkage == GUILE_LSTYLE_PASSIVE)
  362. Printf (scmstub, "(define-module (%s))\n\n", mod);
  363. Delete(mod);
  364. Printf (scmstub, "%s", scmtext);
  365. if ((linkage == GUILE_LSTYLE_SIMPLE
  366. || linkage == GUILE_LSTYLE_PASSIVE)
  367. && Len(exported_symbols) > 0) {
  368. String *ex = NewString(exported_symbols);
  369. Replaceall(ex, ", ", "\n ");
  370. Replaceall(ex, "\"", "");
  371. Chop(ex);
  372. Printf(scmstub, "\n(export %s)\n", ex);
  373. Delete(ex);
  374. }
  375. }
  376. Delete(module_func);
  377. if (CPlusPlus) {
  378. Printf(f_init, "\n}\n");
  379. }
  380. }
  381. /* Return true iff T is a pointer type */
  382. int is_a_pointer (SwigType *t) {
  383. return SwigType_ispointer(SwigType_typedef_resolve_all(t));
  384. }
  385. /* Report an error handling the given type. */
  386. void throw_unhandled_guile_type_error (SwigType *d) {
  387. Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number,
  388. "Unable to handle type %s.\n", SwigType_str(d,0));
  389. }
  390. /* Write out procedure documentation */
  391. void write_doc(const String *proc_name,
  392. const String *signature,
  393. const String *doc,
  394. const String *signature2 = NULL) {
  395. switch (docformat) {
  396. case GUILE_1_4:
  397. Printv(procdoc, "\f\n", NIL);
  398. Printv(procdoc, "(", signature, ")\n", NIL);
  399. if (signature2)
  400. Printv(procdoc, "(", signature2, ")\n", NIL);
  401. Printv(procdoc, doc, "\n", NIL);
  402. break;
  403. case PLAIN:
  404. Printv(procdoc, "\f", proc_name, "\n\n", NIL);
  405. Printv(procdoc, "(", signature, ")\n", NIL);
  406. if (signature2)
  407. Printv(procdoc, "(", signature2, ")\n", NIL);
  408. Printv(procdoc, doc, "\n\n", NIL);
  409. break;
  410. case TEXINFO:
  411. Printv(procdoc, "\f", proc_name, "\n", NIL);
  412. Printv(procdoc, "@deffn primitive ", signature, "\n", NIL);
  413. if (signature2)
  414. Printv(procdoc, "@deffnx primitive ", signature2, "\n", NIL);
  415. Printv(procdoc, doc, "\n", NIL);
  416. Printv(procdoc, "@end deffn\n\n", NIL);
  417. break;
  418. }
  419. }
  420. /* returns false if the typemap is an empty string */
  421. bool handle_documentation_typemap(String *output,
  422. const String *maybe_delimiter,
  423. Parm *p,
  424. const String *typemap,
  425. const String *default_doc)
  426. {
  427. String *tmp = NewString("");
  428. String *tm;
  429. if (!(tm = Getattr(p, typemap))) {
  430. Printf(tmp, "%s", default_doc);
  431. tm = tmp;
  432. }
  433. bool result = (Len(tm) > 0);
  434. if (maybe_delimiter && Len(output) > 0 && Len(tm) > 0) {
  435. Printv(output, maybe_delimiter, NIL);
  436. }
  437. String *pn = Getattr(p,"name");
  438. String *pt = Getattr(p,"type");
  439. Replaceall(tm, "$name", pn); // legacy for $parmname
  440. Replaceall(tm, "$type", SwigType_str(pt,0));
  441. /* $NAME is like $name, but marked-up as a variable. */
  442. String *ARGNAME = NewString("");
  443. if (docformat == TEXINFO)
  444. Printf(ARGNAME, "@var{%s}", pn);
  445. else Printf(ARGNAME, "%(upper)s", pn);
  446. Replaceall(tm, "$NAME", ARGNAME);
  447. Replaceall(tm, "$PARMNAME", ARGNAME);
  448. Printv(output,tm,NIL);
  449. Delete(tmp);
  450. return result;
  451. }
  452. /* ------------------------------------------------------------
  453. * functionWrapper()
  454. * Create a function declaration and register it with the interpreter.
  455. * ------------------------------------------------------------ */
  456. virtual int functionWrapper(Node *n) {
  457. String *iname = Getattr(n,"sym:name");
  458. SwigType *d = Getattr(n,"type");
  459. ParmList *l = Getattr(n,"parms");
  460. Parm *p;
  461. String *proc_name = 0;
  462. char source[256], target[256];
  463. Wrapper *f = NewWrapper();;
  464. String *cleanup = NewString("");
  465. String *outarg = NewString("");
  466. String *signature = NewString("");
  467. String *doc_body = NewString("");
  468. String *returns = NewString("");
  469. int num_results = 1;
  470. String *tmp = NewString("");
  471. String *tm;
  472. int i;
  473. int numargs = 0;
  474. int numreq = 0;
  475. String *overname = 0;
  476. int args_passed_as_array = 0;
  477. // Make a wrapper name for this
  478. String *wname = Swig_name_wrapper(iname);
  479. if (Getattr(n,"sym:overloaded")) {
  480. overname = Getattr(n,"sym:overname");
  481. args_passed_as_array = 1;
  482. } else {
  483. if (!addSymbol(iname,n)) return SWIG_ERROR;
  484. }
  485. if (overname) {
  486. Append(wname, overname);
  487. }
  488. Setattr(n,"wrap:name",wname);
  489. // Build the name for scheme.
  490. proc_name = NewString(iname);
  491. Replaceall(proc_name,"_", "-");
  492. /* Emit locals etc. into f->code; figure out which args to ignore */
  493. emit_args (d, l, f);
  494. /* Attach the standard typemaps */
  495. emit_attach_parmmaps(l,f);
  496. Setattr(n,"wrap:parms",l);
  497. /* Get number of required and total arguments */
  498. numargs = emit_num_arguments(l);
  499. numreq = emit_num_required(l);
  500. /* Declare return variable */
  501. Wrapper_add_local (f,"gswig_result", "SCM gswig_result");
  502. Wrapper_add_local (f,"gswig_list_p", "int gswig_list_p = 0");
  503. /* Get the output typemap so we can start generating documentation. Don't
  504. worry, the returned string is saved as 'tmap:out' */
  505. Swig_typemap_lookup_new("out",n,"result",0);
  506. if ((tm = Getattr(n,"tmap:out:doc"))) {
  507. Printv(returns,tm,NIL);
  508. if (Len(tm) > 0) num_results = 1;
  509. else num_results = 0;
  510. } else {
  511. String *s = SwigType_str(d,0);
  512. Chop(s);
  513. Printf(returns,"<%s>",s);
  514. Delete(s);
  515. num_results = 1;
  516. }
  517. /* Open prototype and signature */
  518. Printv(f->def, "static SCM\n", wname," (", NIL);
  519. if (args_passed_as_array) {
  520. Printv(f->def, "int argc, SCM *argv", NIL);
  521. }
  522. Printv(signature, proc_name, NIL);
  523. /* Now write code to extract the parameters */
  524. for (i = 0, p = l; i < numargs; i++) {
  525. while (checkAttribute(p,"tmap:in:numinputs","0")) {
  526. p = Getattr(p,"tmap:in:next");
  527. }
  528. SwigType *pt = Getattr(p,"type");
  529. String *pn = Getattr(p,"name");
  530. String *ln = Getattr(p,"lname");
  531. int opt_p = (i >= numreq);
  532. // Produce names of source and target
  533. if (args_passed_as_array)
  534. sprintf(source, "argv[%d]", i);
  535. else
  536. sprintf(source,"s_%d",i);
  537. sprintf(target,"%s", Char(ln));
  538. if (!args_passed_as_array) {
  539. if (i!=0) Printf(f->def,", ");
  540. Printf(f->def,"SCM s_%d", i);
  541. }
  542. if (opt_p) {
  543. Printf(f->code," if (%s != GH_NOT_PASSED) {\n", source);
  544. }
  545. if ((tm = Getattr(p,"tmap:in"))) {
  546. Replaceall(tm,"$source",source);
  547. Replaceall(tm,"$target",target);
  548. Replaceall(tm,"$input",source);
  549. Setattr(p,"emit:input", source);
  550. Printv(f->code,tm,"\n",NIL);
  551. if (procdoc) {
  552. /* Add to signature (arglist) */
  553. handle_documentation_typemap(signature, " ", p, "tmap:in:arglist",
  554. "$name");
  555. /* Document the type of the arg in the documentation body */
  556. handle_documentation_typemap(doc_body, ", ", p, "tmap:in:doc",
  557. "$NAME is of type <$type>");
  558. }
  559. p = Getattr(p,"tmap:in:next");
  560. } else {
  561. throw_unhandled_guile_type_error (pt);
  562. p = nextSibling(p);
  563. }
  564. if (opt_p)
  565. Printf(f->code," }\n");
  566. }
  567. if (Len(doc_body) > 0)
  568. Printf(doc_body, ".\n");
  569. /* Insert constraint checking code */
  570. for (p = l; p;) {
  571. if ((tm = Getattr(p,"tmap:check"))) {
  572. Replaceall(tm,"$target",Getattr(p,"lname"));
  573. Printv(f->code,tm,"\n",NIL);
  574. p = Getattr(p,"tmap:check:next");
  575. } else {
  576. p = nextSibling(p);
  577. }
  578. }
  579. /* Pass output arguments back to the caller. */
  580. /* Insert argument output code */
  581. for (p = l; p;) {
  582. if ((tm = Getattr(p,"tmap:argout"))) {
  583. Replaceall(tm,"$source",Getattr(p,"lname"));
  584. Replaceall(tm,"$target",Getattr(p,"lname"));
  585. Replaceall(tm,"$arg",Getattr(p,"emit:input"));
  586. Replaceall(tm,"$input",Getattr(p,"emit:input"));
  587. Printv(outarg,tm,"\n",NIL);
  588. if (procdoc) {
  589. if (handle_documentation_typemap(returns, ", ",
  590. p, "tmap:argout:doc",
  591. "$NAME (of type $type)")) {
  592. /* A documentation typemap that is not the empty string
  593. indicates that a value is returned to Scheme. */
  594. num_results++;
  595. }
  596. }
  597. p = Getattr(p,"tmap:argout:next");
  598. } else {
  599. p = nextSibling(p);
  600. }
  601. }
  602. /* Insert cleanup code */
  603. for (p = l; p;) {
  604. if ((tm = Getattr(p,"tmap:freearg"))) {
  605. Replaceall(tm,"$target",Getattr(p,"lname"));
  606. Printv(cleanup,tm,"\n",NIL);
  607. p = Getattr(p,"tmap:freearg:next");
  608. } else {
  609. p = nextSibling(p);
  610. }
  611. }
  612. /* Close prototype */
  613. Printf(f->def, ")\n{\n");
  614. /* Define the scheme name in C. This define is used by several Guile
  615. macros. */
  616. Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
  617. // Now write code to make the function call
  618. Printv(f->code, tab4, "gh_defer_ints();\n", NIL);
  619. emit_action(n,f);
  620. Printv(f->code, tab4, "gh_allow_ints();\n", NIL);
  621. // Now have return value, figure out what to do with it.
  622. if ((tm = Getattr(n,"tmap:out"))) {
  623. Replaceall(tm,"$result","gswig_result");
  624. Replaceall(tm,"$target","gswig_result");
  625. Replaceall(tm,"$source","result");
  626. Printv(f->code,tm,"\n",NIL);
  627. }
  628. else {
  629. throw_unhandled_guile_type_error (d);
  630. }
  631. // Dump the argument output code
  632. Printv(f->code,outarg,NIL);
  633. // Dump the argument cleanup code
  634. Printv(f->code,cleanup,NIL);
  635. // Look for any remaining cleanup
  636. if (Getattr(n,"feature:new")) {
  637. if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) {
  638. Replaceall(tm,"$source","result");
  639. Printv(f->code,tm,"\n",NIL);
  640. }
  641. }
  642. // Free any memory allocated by the function being wrapped..
  643. if ((tm = Swig_typemap_lookup_new("ret",n,"result",0))) {
  644. Replaceall(tm,"$source","result");
  645. Printv(f->code,tm,"\n",NIL);
  646. }
  647. // Wrap things up (in a manner of speaking)
  648. if (beforereturn)
  649. Printv(f->code, beforereturn, "\n", NIL);
  650. Printv(f->code, "return gswig_result;\n", NIL);
  651. // Undefine the scheme name
  652. Printf(f->code, "#undef FUNC_NAME\n");
  653. Printf(f->code, "}\n");
  654. Wrapper_print (f, f_wrappers);
  655. if (!Getattr(n, "sym:overloaded")) {
  656. if (numargs > 10) {
  657. int i;
  658. /* gh_new_procedure would complain: too many args */
  659. /* Build a wrapper wrapper */
  660. Printv(f_wrappers, "static SCM\n", wname,"_rest (SCM rest)\n", NIL);
  661. Printv(f_wrappers, "{\n", NIL);
  662. Printf(f_wrappers, "SCM arg[%d];\n", numargs);
  663. Printf(f_wrappers, "SWIG_Guile_GetArgs (arg, rest, %d, %d, \"%s\");\n",
  664. numreq, numargs-numreq, proc_name);
  665. Printv(f_wrappers, "return ", wname, "(", NIL);
  666. Printv(f_wrappers, "arg[0]", NIL);
  667. for (i = 1; i<numargs; i++)
  668. Printf(f_wrappers, ", arg[%d]", i);
  669. Printv(f_wrappers, ");\n", NIL);
  670. Printv(f_wrappers, "}\n", NIL);
  671. /* Register it */
  672. Printf (f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s_rest, 0, 0, 1);\n",
  673. proc_name, wname, numreq, numargs-numreq);
  674. }
  675. else if (emit_setters && struct_member && strlen(Char(proc_name))>3) {
  676. int len = Len(proc_name);
  677. const char *pc = Char(proc_name);
  678. /* MEMBER-set and MEMBER-get functions. */
  679. int is_setter = (pc[len - 3] == 's');
  680. if (is_setter) {
  681. Printf(f_init, "SCM setter = ");
  682. struct_member = 2; /* have a setter */
  683. }
  684. else Printf(f_init, "SCM getter = ");
  685. Printf (f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, %d, %d, 0);\n",
  686. proc_name, wname, numreq, numargs-numreq);
  687. if (!is_setter) {
  688. /* Strip off "-get" */
  689. char *pws_name = (char*) malloc(sizeof(char) * (len - 3));
  690. strncpy(pws_name, pc, len - 3);
  691. pws_name[len - 4] = 0;
  692. if (struct_member==2) {
  693. /* There was a setter, so create a procedure with setter */
  694. Printf (f_init, "gh_define(\"%s\", "
  695. "scm_make_procedure_with_setter(getter, setter));\n",
  696. pws_name);
  697. }
  698. else {
  699. /* There was no setter, so make an alias to the getter */
  700. Printf (f_init, "gh_define(\"%s\", getter);\n",
  701. pws_name);
  702. }
  703. Printf (exported_symbols, "\"%s\", ", pws_name);
  704. free(pws_name);
  705. }
  706. }
  707. else {
  708. /* Register the function */
  709. Printf (f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, %d, %d, 0);\n",
  710. proc_name, wname, numreq, numargs-numreq);
  711. }
  712. }
  713. else { /* overloaded function; don't export the single methods */
  714. if (!Getattr(n,"sym:nextSibling")) {
  715. /* Emit overloading dispatch function */
  716. int maxargs;
  717. String *dispatch = Swig_overload_dispatch(n,"return %s(argc,argv);",&maxargs);
  718. /* Generate a dispatch wrapper for all overloaded functions */
  719. Wrapper *df = NewWrapper();
  720. String *dname = Swig_name_wrapper(iname);
  721. Printv(df->def,
  722. "static SCM\n", dname,
  723. "(SCM rest)\n{\n",
  724. NIL);
  725. Printf(df->code, "SCM argv[%d];\n", maxargs);
  726. Printf(df->code, "int argc = SWIG_Guile_GetArgs (argv, rest, %d, %d, \"%s\");\n",
  727. 0, maxargs, proc_name);
  728. Printv(df->code,dispatch,"\n",NIL);
  729. Printf(df->code,"scm_misc_error(\"%s\", \"No matching method for generic function `%s'\", SCM_EOL);\n", proc_name, iname);
  730. Printv(df->code,"}\n",NIL);
  731. Wrapper_print(df,f_wrappers);
  732. Printf(f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, 0, 1);\n",
  733. proc_name, dname);
  734. DelWrapper(df);
  735. Delete(dispatch);
  736. Delete(dname);
  737. }
  738. }
  739. Printf (exported_symbols, "\"%s\", ", proc_name);
  740. if (procdoc) {
  741. String *returns_text = NewString("");
  742. if (num_results == 0) Printv(returns_text, return_nothing_doc, NIL);
  743. else if (num_results == 1) Printv(returns_text, return_one_doc, NIL);
  744. else Printv(returns_text, return_multi_doc, NIL);
  745. /* Substitute documentation variables */
  746. static const char *numbers[] = {"zero", "one", "two", "three",
  747. "four", "five", "six", "seven",
  748. "eight", "nine", "ten", "eleven",
  749. "twelve"};
  750. if (num_results <= 12)
  751. Replaceall(returns_text, "$num_values", numbers[num_results]);
  752. else {
  753. String *num_results_str = NewStringf("%d", num_results);
  754. Replaceall(returns_text, "$num_values", num_results_str);
  755. Delete(num_results_str);
  756. }
  757. Replaceall(returns_text, "$values", returns);
  758. Printf(doc_body, "\n%s", returns_text);
  759. write_doc(proc_name, signature, doc_body);
  760. Delete(returns_text);
  761. }
  762. Delete(proc_name);
  763. Delete(outarg);
  764. Delete(cleanup);
  765. Delete(signature);
  766. Delete(doc_body);
  767. Delete(returns);
  768. Delete(tmp);
  769. DelWrapper(f);
  770. return SWIG_OK;
  771. }
  772. /* ------------------------------------------------------------
  773. * variableWrapper()
  774. *
  775. * Create a link to a C variable.
  776. * This creates a single function PREFIX_var_VARNAME().
  777. * This function takes a single optional argument. If supplied, it means
  778. * we are setting this variable to some value. If omitted, it means we are
  779. * simply evaluating this variable. Either way, we return the variables
  780. * value.
  781. * ------------------------------------------------------------ */
  782. virtual int variableWrapper(Node *n) {
  783. char *name = GetChar(n,"name");
  784. char *iname = GetChar(n,"sym:name");
  785. SwigType *t = Getattr(n,"type");
  786. String *proc_name;
  787. char var_name[256];
  788. Wrapper *f;
  789. String *tm;
  790. if (!addSymbol(iname,n)) return SWIG_ERROR;
  791. f = NewWrapper();
  792. // evaluation function names
  793. strcpy(var_name, Char(Swig_name_wrapper(iname)));
  794. // Build the name for scheme.
  795. proc_name = NewString(iname);
  796. Replaceall(proc_name,"_", "-");
  797. if (1 || (SwigType_type(t) != T_USER) || (is_a_pointer(t))) {
  798. Printf (f->def, "static SCM\n%s(SCM s_0)\n{\n", var_name);
  799. /* Define the scheme name in C. This define is used by several Guile
  800. macros. */
  801. Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
  802. Wrapper_add_local (f, "gswig_result", "SCM gswig_result");
  803. if (!Getattr(n,"feature:immutable")) {
  804. /* Check for a setting of the variable value */
  805. Printf (f->code, "if (s_0 != GH_NOT_PASSED) {\n");
  806. if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) {
  807. Replaceall(tm,"$source","s_0");
  808. Replaceall(tm,"$input","s_0");
  809. Replaceall(tm,"$target",name);
  810. Printv(f->code,tm,"\n",NIL);
  811. }
  812. else {
  813. throw_unhandled_guile_type_error (t);
  814. }
  815. Printf (f->code, "}\n");
  816. }
  817. // Now return the value of the variable (regardless
  818. // of evaluating or setting)
  819. if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) {
  820. Replaceall(tm,"$source",name);
  821. Replaceall(tm,"$target","gswig_result");
  822. Replaceall(tm,"$result", "gswig_result");
  823. Printv(f->code,tm,"\n",NIL);
  824. }
  825. else {
  826. throw_unhandled_guile_type_error (t);
  827. }
  828. Printf (f->code, "\nreturn gswig_result;\n");
  829. Printf (f->code, "#undef FUNC_NAME\n");
  830. Printf (f->code, "}\n");
  831. Wrapper_print (f, f_wrappers);
  832. // Now add symbol to the Guile interpreter
  833. if (!emit_setters
  834. || Getattr(n,"feature:immutable")) {
  835. /* Read-only variables become a simple procedure returning the
  836. value; read-write variables become a simple procedure with
  837. an optional argument. */
  838. Printf (f_init, "\t gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, %d, 0);\n",
  839. proc_name, var_name, Getattr(n,"feature:immutable") ? 0 : 1);
  840. }
  841. else {
  842. /* Read/write variables become a procedure with setter. */
  843. Printf (f_init, "\t{ SCM p = gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, 1, 0);\n",
  844. proc_name, var_name);
  845. Printf (f_init, "\t gh_define(\"%s\", "
  846. "scm_make_procedure_with_setter(p, p)); }\n",
  847. proc_name);
  848. }
  849. Printf (exported_symbols, "\"%s\", ", proc_name);
  850. if (procdoc) {
  851. /* Compute documentation */
  852. String *signature = NewString("");
  853. String *signature2 = NULL;
  854. String *doc = NewString("");
  855. if (Getattr(n,"feature:immutable")) {
  856. Printv(signature, proc_name, NIL);
  857. Printv(doc, "Returns constant ", NIL);
  858. if ((tm = Getattr(n,"tmap:varout:doc"))) {
  859. Printv(doc,tm,NIL);
  860. } else {
  861. String *s = SwigType_str(t,0);
  862. Chop(s);
  863. Printf(doc,"<%s>",s);
  864. Delete(s);
  865. }
  866. }
  867. else if (emit_setters) {
  868. Printv(signature, proc_name, NIL);
  869. signature2 = NewString("");
  870. Printv(signature2, "set! (", proc_name, ") ", NIL);
  871. handle_documentation_typemap(signature2, NIL, n, "tmap:varin:arglist",
  872. "new-value");
  873. Printv(doc, "Get or set the value of the C variable, \n", NIL);
  874. Printv(doc, "which is of type ", NIL);
  875. handle_documentation_typemap(doc, NIL, n, "tmap:varout:doc",
  876. "$1_type");
  877. Printv(doc, ".");
  878. }
  879. else {
  880. Printv(signature, proc_name,
  881. " #:optional ", NIL);
  882. if ((tm = Getattr(n,"tmap:varin:doc"))) {
  883. Printv(signature,tm,NIL);
  884. } else {
  885. String *s = SwigType_str(t,0);
  886. Chop(s);
  887. Printf(signature,"new-value <%s>",s);
  888. Delete(s);
  889. }
  890. Printv(doc, "If NEW-VALUE is provided, "
  891. "set C variable to this value.\n", NIL);
  892. Printv(doc, "Returns variable value ", NIL);
  893. if ((tm = Getattr(n,"tmap:varout:doc"))) {
  894. Printv(doc,tm,NIL);
  895. } else {
  896. String *s = SwigType_str(t,0);
  897. Chop(s);
  898. Printf(doc,"<%s>",s);
  899. Delete(s);
  900. }
  901. }
  902. write_doc(proc_name, signature, doc, signature2);
  903. Delete(signature);
  904. if (signature2) Delete(signature2);
  905. Delete(doc);
  906. }
  907. } else {
  908. Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number,
  909. "Unsupported variable type %s (ignored).\n", SwigType_str(t,0));
  910. }
  911. Delete(proc_name);
  912. DelWrapper(f);
  913. return SWIG_OK;
  914. }
  915. /* ------------------------------------------------------------
  916. * constantWrapper()
  917. *
  918. * We create a read-only variable.
  919. * ------------------------------------------------------------ */
  920. virtual int constantWrapper(Node *n) {
  921. char *name = GetChar(n,"name");
  922. char *iname = GetChar(n,"sym:name");
  923. SwigType *type = Getattr(n,"type");
  924. String *value = Getattr(n,"value");
  925. String *proc_name;
  926. char var_name[256];
  927. String *rvalue;
  928. Wrapper *f;
  929. SwigType *nctype;
  930. String *tm;
  931. f = NewWrapper();
  932. // Make a static variable;
  933. sprintf (var_name, "%sconst_%s", prefix, iname);
  934. // Strip const qualifier from type if present
  935. nctype = NewString(type);
  936. if (SwigType_isconst(nctype)) {
  937. Delete(SwigType_pop(nctype));
  938. }
  939. // Build the name for scheme.
  940. proc_name = NewString(iname);
  941. Replaceall(proc_name,"_", "-");
  942. if ((SwigType_type(nctype) == T_USER) && (!is_a_pointer(nctype))) {
  943. Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number,
  944. "Unsupported constant value.\n");
  945. return SWIG_NOWRAP;
  946. }
  947. // See if there's a typemap
  948. if (SwigType_type(nctype) == T_STRING) {
  949. rvalue = NewStringf("\"%s\"", value);
  950. } else if (SwigType_type(nctype) == T_CHAR) {
  951. rvalue = NewStringf("\'%s\'", value);
  952. } else {
  953. rvalue = NewString(value);
  954. }
  955. if ((tm = Swig_typemap_lookup_new("constant",n,name,0))) {
  956. Replaceall(tm,"$source",rvalue);
  957. Replaceall(tm,"$value",rvalue);
  958. Replaceall(tm,"$target",name);
  959. Printv(f_header,tm,"\n",NIL);
  960. } else {
  961. // Create variable and assign it a value
  962. Printf (f_header, "static %s = %s;\n", SwigType_lstr(nctype,var_name),
  963. rvalue);
  964. }
  965. {
  966. /* Hack alert: will cleanup later -- Dave */
  967. Node *n = NewHash();
  968. Setattr(n,"name",var_name);
  969. Setattr(n,"sym:name",iname);
  970. Setattr(n,"type", nctype);
  971. Setattr(n,"feature:immutable", "1");
  972. variableWrapper(n);
  973. Delete(n);
  974. }
  975. Delete(nctype);
  976. Delete(proc_name);
  977. Delete(rvalue);
  978. DelWrapper(f);
  979. return SWIG_OK;
  980. }
  981. /* ------------------------------------------------------------
  982. * membervariableHandler()
  983. * ------------------------------------------------------------ */
  984. virtual int membervariableHandler(Node *n) {
  985. if (emit_setters) {
  986. struct_member = 1;
  987. Printf(f_init, "{\n");
  988. Language::membervariableHandler(n);
  989. Printf(f_init, "}\n");
  990. struct_member = 0;
  991. }
  992. else {
  993. /* Only emit traditional VAR-get and VAR-set procedures */
  994. Language::membervariableHandler(n);
  995. }
  996. return SWIG_OK;
  997. }
  998. /* ------------------------------------------------------------
  999. * pragmaDirective()
  1000. * ------------------------------------------------------------ */
  1001. virtual int pragmaDirective(Node *n)
  1002. {
  1003. if (!ImportMode) {
  1004. String *lang = Getattr(n,"lang");
  1005. String *cmd = Getattr(n,"name");
  1006. String *value = Getattr(n,"value");
  1007. # define store_pragma(PRAGMANAME) \
  1008. if (Strcmp(cmd, #PRAGMANAME) == 0) { \
  1009. if (PRAGMANAME) Delete(PRAGMANAME); \
  1010. PRAGMANAME = value ? NewString(value) : NULL; \
  1011. }
  1012. if (Strcmp(lang,"guile") == 0) {
  1013. store_pragma(beforereturn)
  1014. store_pragma(return_nothing_doc)
  1015. store_pragma(return_one_doc)
  1016. store_pragma(return_multi_doc);
  1017. # undef store_pragma
  1018. }
  1019. }
  1020. return Language::pragmaDirective(n);
  1021. }
  1022. /* ------------------------------------------------------------
  1023. * validIdentifier()
  1024. * ------------------------------------------------------------ */
  1025. virtual int validIdentifier(String *s) {
  1026. char *c = Char(s);
  1027. /* Check whether we have an R5RS identifier. Guile supports a
  1028. superset of R5RS identifiers, but it's probably a bad idea to use
  1029. those. */
  1030. /* <identifier> --> <initial> <subsequent>* | <peculiar identifier> */
  1031. /* <initial> --> <letter> | <special initial> */
  1032. if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%')
  1033. || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
  1034. || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
  1035. || (*c == '^') || (*c == '_') || (*c == '~'))) {
  1036. /* <peculiar identifier> --> + | - | ... */
  1037. if ((strcmp(c, "+") == 0)
  1038. || strcmp(c, "-") == 0
  1039. || strcmp(c, "...") == 0) return 1;
  1040. else return 0;
  1041. }
  1042. /* <subsequent> --> <initial> | <digit> | <special subsequent> */
  1043. while (*c) {
  1044. if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%')
  1045. || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
  1046. || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
  1047. || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+')
  1048. || (*c == '-') || (*c == '.') || (*c == '@'))) return 0;
  1049. c++;
  1050. }
  1051. return 1;
  1052. }
  1053. };
  1054. /* -----------------------------------------------------------------------------
  1055. * swig_guile() - Instantiate module
  1056. * ----------------------------------------------------------------------------- */
  1057. extern "C" Language *
  1058. swig_guile(void) {
  1059. return new GUILE();
  1060. }