PageRenderTime 60ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/rel-1-3-26/SWIG/Source/Modules/ocaml.cxx

#
C++ | 1965 lines | 1308 code | 263 blank | 394 comment | 211 complexity | 2b1ae9b4a3bb41e5a3e4676037b00d27 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 : Art Yerkes
  5. * Modified from mzscheme.cxx : David Beazley
  6. *
  7. * Please read the file LICENSE for the copyright and terms by which SWIG
  8. * can be used and distributed.
  9. *****************************************************************************/
  10. char cvsroot_ocaml_cxx[] = "$Header$";
  11. /***********************************************************************
  12. * $Header$
  13. *
  14. * ocaml.cxx
  15. *
  16. * Definitions for adding functions to Ocaml 101
  17. ***********************************************************************/
  18. #include "swigmod.h"
  19. #include <ctype.h>
  20. static const char *usage = (char*)
  21. ("Ocaml Options (available with -ocaml)\n"
  22. "-prefix <name> - Set a prefix <name> to be prepended to all names\n"
  23. "-where - Emit library location\n"
  24. "-suffix <name> - Change .cxx to something else\n"
  25. "-oldvarnames - old intermediary method names for variable wrappers\n"
  26. "\n");
  27. static int classmode = 0;
  28. static int in_constructor = 0, in_destructor = 0, in_copyconst = 0;
  29. static int const_enum = 0;
  30. static int static_member_function = 0;
  31. static int generate_sizeof = 0;
  32. static char *prefix=0;
  33. static char *ocaml_path=(char*)"ocaml";
  34. static bool old_variable_names = false;
  35. static String *classname=0;
  36. static String *module=0;
  37. static String *init_func_def = 0;
  38. static String *f_classtemplate = 0;
  39. static String *name_qualifier = 0;
  40. static Hash *seen_enums = 0;
  41. static Hash *seen_enumvalues = 0;
  42. static Hash *seen_constructors = 0;
  43. static File *f_header = 0;
  44. static File *f_runtime = 0;
  45. static File *f_wrappers = 0;
  46. static File *f_directors = 0;
  47. static File *f_directors_h = 0;
  48. static File *f_init = 0;
  49. static File *f_mlout = 0;
  50. static File *f_mliout = 0;
  51. static File *f_mlbody = 0;
  52. static File *f_mlibody = 0;
  53. static File *f_mltail = 0;
  54. static File *f_mlitail = 0;
  55. static File *f_enumtypes_type = 0;
  56. static File *f_enumtypes_value = 0;
  57. static File *f_class_ctors = 0;
  58. static File *f_class_ctors_end = 0;
  59. static File *f_enum_to_int = 0;
  60. static File *f_int_to_enum = 0;
  61. class OCAML : public Language {
  62. public:
  63. OCAML()
  64. {
  65. director_prot_ctor_code = NewString("");
  66. Printv(director_prot_ctor_code,
  67. "if ( $comparison ) { /* subclassed */\n",
  68. " $director_new \n",
  69. "} else {\n",
  70. " failwith(\"accessing abstract class or protected constructor\"); \n",
  71. "}\n", NIL);
  72. director_multiple_inheritance = 1;
  73. director_language = 1;
  74. }
  75. String *Swig_class_name(Node *n) {
  76. String *name;
  77. name = Copy(Getattr(n, "sym:name"));
  78. return name;
  79. }
  80. void PrintIncludeArg() {
  81. Printv(stdout,SWIG_LIB,SWIG_FILE_DELIMETER,ocaml_path,
  82. "\n",NIL);
  83. }
  84. /* ------------------------------------------------------------
  85. * main()
  86. * ------------------------------------------------------------ */
  87. virtual void main (int argc, char *argv[]) {
  88. int i;
  89. prefix = 0;
  90. SWIG_library_directory(ocaml_path);
  91. // Look for certain command line options
  92. for (i = 1; i < argc; i++) {
  93. if (argv[i]) {
  94. if (strcmp (argv[i], "-help") == 0) {
  95. fputs (usage, stdout);
  96. SWIG_exit (0);
  97. } else if (strcmp (argv[i], "-where") == 0) {
  98. PrintIncludeArg();
  99. SWIG_exit (0);
  100. } else if (strcmp (argv[i], "-prefix") == 0) {
  101. if (argv[i + 1]) {
  102. prefix = new char[strlen(argv[i + 1]) + 2];
  103. strcpy(prefix, argv[i + 1]);
  104. Swig_mark_arg (i);
  105. Swig_mark_arg (i + 1);
  106. i++;
  107. } else {
  108. Swig_arg_error();
  109. }
  110. } else if (strcmp (argv[i], "-suffix") == 0) {
  111. if (argv[i + 1]) {
  112. SWIG_config_cppext( argv[i+1] );
  113. Swig_mark_arg (i);
  114. Swig_mark_arg (i+1);
  115. i++;
  116. } else
  117. Swig_arg_error();
  118. } else if (strcmp(argv[i],"-oldvarnames") == 0) {
  119. Swig_mark_arg(i);
  120. old_variable_names = true;
  121. }
  122. }
  123. }
  124. // If a prefix has been specified make sure it ends in a '_'
  125. if (prefix) {
  126. if (prefix[strlen (prefix)] != '_') {
  127. prefix[strlen (prefix) + 1] = 0;
  128. prefix[strlen (prefix)] = '_';
  129. }
  130. } else
  131. prefix = (char*)"swig_";
  132. // Add a symbol for this module
  133. Preprocessor_define ("SWIGOCAML 1",0);
  134. // Set name of typemaps
  135. SWIG_typemap_lang("ocaml");
  136. // Read in default typemaps */
  137. SWIG_config_file("ocaml.i");
  138. allow_overloading();
  139. }
  140. /* Swig_director_declaration()
  141. *
  142. * Generate the full director class declaration, complete with base classes.
  143. * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
  144. *
  145. */
  146. String *Swig_director_declaration(Node *n) {
  147. String* classname = Swig_class_name(n);
  148. String *directorname = NewStringf("SwigDirector_%s", classname);
  149. String *base = Getattr(n, "classtype");
  150. String *declaration = Swig_class_declaration(n, directorname);
  151. Printf(declaration, " : public %s, public Swig::Director {\n", base);
  152. Delete(classname);
  153. Delete(directorname);
  154. return declaration;
  155. }
  156. /* ------------------------------------------------------------
  157. * top()
  158. *
  159. * Recognize the %module, and capture the module name.
  160. * Create the default enum cases.
  161. * Set up the named outputs:
  162. *
  163. * init
  164. * ml
  165. * mli
  166. * wrapper
  167. * header
  168. * runtime
  169. * directors
  170. * directors_h
  171. * ------------------------------------------------------------ */
  172. virtual int top(Node *n) {
  173. /* Set comparison with none for ConstructorToFunction */
  174. setSubclassInstanceCheck(NewString("caml_list_nth(args,0) != Val_unit"));
  175. /* check if directors are enabled for this module. note: this
  176. * is a "master" switch, without which no director code will be
  177. * emitted. %feature("director") statements are also required
  178. * to enable directors for individual classes or methods.
  179. *
  180. * use %module(directors="1") modulename at the start of the
  181. * interface file to enable director generation.
  182. */
  183. {
  184. Node *module = Getattr(n, "module");
  185. if (module) {
  186. Node *options = Getattr(module, "options");
  187. if (options) {
  188. if (Getattr(options, "directors")) {
  189. allow_directors();
  190. }
  191. if (Getattr(options, "dirprot")) {
  192. allow_dirprot();
  193. }
  194. if (Getattr(options, "sizeof")) {
  195. generate_sizeof = 1;
  196. }
  197. }
  198. }
  199. }
  200. /* Initialize all of the output files */
  201. String *outfile = Getattr(n,"outfile");
  202. f_runtime = NewFile(outfile,"w");
  203. if (!f_runtime) {
  204. FileErrorDisplay(outfile);
  205. SWIG_exit(EXIT_FAILURE);
  206. }
  207. f_init = NewString("");
  208. f_header = NewString("");
  209. f_wrappers = NewString("");
  210. f_directors = NewString("");
  211. f_directors_h = NewString("");
  212. f_enumtypes_type = NewString("");
  213. f_enumtypes_value = NewString("");
  214. init_func_def = NewString("");
  215. f_mlbody = NewString("");
  216. f_mlibody = NewString("");
  217. f_mltail = NewString("");
  218. f_mlitail = NewString("");
  219. f_class_ctors = NewString("");
  220. f_class_ctors_end = NewString("");
  221. f_enum_to_int = NewString("");
  222. f_int_to_enum = NewString("");
  223. f_classtemplate = NewString("");
  224. module = Getattr(n,"name");
  225. seen_constructors = NewHash();
  226. seen_enums = NewHash();
  227. seen_enumvalues = NewHash();
  228. /* Register file targets with the SWIG file handler */
  229. Swig_register_filebyname("init",init_func_def);
  230. Swig_register_filebyname("header",f_header);
  231. Swig_register_filebyname("wrapper",f_wrappers);
  232. Swig_register_filebyname("runtime",f_runtime);
  233. Swig_register_filebyname("mli",f_mlibody);
  234. Swig_register_filebyname("ml",f_mlbody);
  235. Swig_register_filebyname("mlitail",f_mlitail);
  236. Swig_register_filebyname("mltail",f_mltail);
  237. Swig_register_filebyname("director",f_directors);
  238. Swig_register_filebyname("director_h",f_directors_h);
  239. Swig_register_filebyname("classtemplate",f_classtemplate);
  240. Swig_register_filebyname("class_ctors",f_class_ctors);
  241. if (old_variable_names) {
  242. Swig_name_register("set","%v__set__");
  243. Swig_name_register("get","%v__get__");
  244. }
  245. Printf( f_runtime,
  246. "/* -*- buffer-read-only: t -*- vi: set ro: */\n" );
  247. Printf( f_runtime, "#define SWIG_MODULE \"%s\"\n", module );
  248. /* Module name */
  249. Printf( f_mlbody, "let module_name = \"%s\"\n", module );
  250. Printf( f_mlibody, "val module_name : string\n" );
  251. Printf( f_enum_to_int,
  252. "let enum_to_int x (v : c_obj) =\n"
  253. " match v with\n"
  254. " C_enum _y ->\n"
  255. " (let y = _y in match (x : c_enum_type) with\n"
  256. " `unknown -> "
  257. " (match y with\n"
  258. " `Int x -> (Swig.C_int x)\n"
  259. " | _ -> raise (LabelNotFromThisEnum v))\n" );
  260. Printf( f_int_to_enum,
  261. "let int_to_enum x y =\n"
  262. " match (x : c_enum_type) with\n"
  263. " `unknown -> C_enum (`Int y)\n" );
  264. Swig_banner (f_runtime);
  265. if( directorsEnabled() ) {
  266. Printf( f_runtime, "#define SWIG_DIRECTORS\n");
  267. Swig_insert_file("director.swg", f_directors_h);
  268. }
  269. /* Produce the enum_to_int and int_to_enum functions */
  270. Printf(f_enumtypes_type,"open Swig\n"
  271. "type c_enum_type = [ \n `unknown\n" );
  272. Printf(f_enumtypes_value,"type c_enum_value = [ \n `Int of int\n" );
  273. String *mlfile = NewString("");
  274. String *mlifile = NewString("");
  275. Printv(mlfile,module,".ml",NIL);
  276. Printv(mlifile,module,".mli",NIL);
  277. String *mlfilen = NewStringf("%s%s", SWIG_output_directory(),mlfile);
  278. if ((f_mlout = NewFile(mlfilen,"w")) == 0) {
  279. FileErrorDisplay(mlfilen);
  280. SWIG_exit (EXIT_FAILURE);
  281. }
  282. String *mlifilen = NewStringf("%s%s", SWIG_output_directory(),mlifile);
  283. if ((f_mliout = NewFile(mlifilen,"w")) == 0) {
  284. FileErrorDisplay(mlifilen);
  285. SWIG_exit (EXIT_FAILURE);
  286. }
  287. Language::top(n);
  288. Printf( f_enum_to_int,
  289. ") | _ -> (C_int (get_int v))\n"
  290. "let _ = Callback.register \"%s_enum_to_int\" enum_to_int\n",
  291. module );
  292. Printf( f_mlibody,
  293. "val enum_to_int : c_enum_type -> c_obj -> Swig.c_obj\n" );
  294. Printf( f_int_to_enum,
  295. "let _ = Callback.register \"%s_int_to_enum\" int_to_enum\n",
  296. module );
  297. Printf( f_mlibody,
  298. "val int_to_enum : c_enum_type -> int -> c_obj\n" );
  299. Printf( f_init,
  300. "#define SWIG_init f_%s_init\n"
  301. "%s"
  302. "}\n",
  303. module, init_func_def );
  304. Printf( f_mlbody,
  305. "external f_init : unit -> unit = \"f_%s_init\" ;;\n"
  306. "let _ = f_init ()\n",
  307. module, module );
  308. Printf( f_enumtypes_type, "]\n" );
  309. Printf( f_enumtypes_value, "]\n\n"
  310. "type c_obj = c_enum_value c_obj_t\n" );
  311. SwigType_emit_type_table (f_runtime, f_wrappers);
  312. /* Close all of the files */
  313. Dump(f_directors_h,f_header);
  314. Dump(f_header,f_runtime);
  315. Dump(f_directors,f_wrappers);
  316. Dump(f_wrappers,f_runtime);
  317. Wrapper_pretty_print(f_init,f_runtime);
  318. Delete(f_header);
  319. Delete(f_wrappers);
  320. Delete(f_init);
  321. Close(f_runtime);
  322. Delete(f_runtime);
  323. Dump(f_enumtypes_type,f_mlout);
  324. Dump(f_enumtypes_value,f_mlout);
  325. Dump(f_mlbody,f_mlout);
  326. Dump(f_enum_to_int,f_mlout);
  327. Dump(f_int_to_enum,f_mlout);
  328. Delete(f_int_to_enum);
  329. Delete(f_enum_to_int);
  330. Dump(f_class_ctors,f_mlout);
  331. Dump(f_class_ctors_end,f_mlout);
  332. Dump(f_mltail,f_mlout);
  333. Close(f_mlout);
  334. Delete(f_mlout);
  335. Dump(f_enumtypes_type,f_mliout);
  336. Dump(f_enumtypes_value,f_mliout);
  337. Dump(f_mlibody,f_mliout);
  338. Dump(f_mlitail,f_mliout);
  339. Close(f_mliout);
  340. Delete(f_mliout);
  341. return SWIG_OK;
  342. }
  343. /* Produce an error for the given type */
  344. void throw_unhandled_ocaml_type_error (SwigType *d, const char *types) {
  345. Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number,
  346. "Unable to handle type %s (%s).\n", SwigType_str(d,0),
  347. types );
  348. }
  349. /* Return true iff T is a pointer type */
  350. int
  351. is_a_pointer (SwigType *t) {
  352. return SwigType_ispointer(SwigType_typedef_resolve_all(t));
  353. }
  354. /*
  355. * Delete one reference from a given type.
  356. */
  357. void oc_SwigType_del_reference(SwigType *t) {
  358. char *c = Char(t);
  359. if (strncmp(c,"q(",2) == 0) {
  360. Delete(SwigType_pop(t));
  361. c = Char(t);
  362. }
  363. if (strncmp(c,"r.",2)) {
  364. printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n");
  365. abort();
  366. }
  367. Replace(t,"r.","", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
  368. }
  369. void oc_SwigType_del_array(SwigType *t) {
  370. char *c = Char(t);
  371. if (strncmp(c,"q(",2) == 0) {
  372. Delete(SwigType_pop(t));
  373. c = Char(t);
  374. }
  375. if (strncmp(c,"a(",2) == 0) {
  376. Delete(SwigType_pop(t));
  377. }
  378. }
  379. /*
  380. * Return true iff T is a reference type
  381. */
  382. int
  383. is_a_reference (SwigType *t) {
  384. return SwigType_isreference(SwigType_typedef_resolve_all(t));
  385. }
  386. int
  387. is_an_array (SwigType *t) {
  388. return SwigType_isarray(SwigType_typedef_resolve_all(t));
  389. }
  390. /* ------------------------------------------------------------
  391. * functionWrapper()
  392. * Create a function declaration and register it with the interpreter.
  393. * ------------------------------------------------------------ */
  394. virtual int functionWrapper(Node *n) {
  395. char *iname = GetChar(n,"sym:name");
  396. SwigType *d = Getattr(n,"type");
  397. String *return_type_normalized = normalizeTemplatedClassName(d);
  398. ParmList *l = Getattr(n,"parms");
  399. Parm *p;
  400. Wrapper *f = NewWrapper();
  401. String *proc_name = NewString("");
  402. String *source = NewString("");
  403. String *target = NewString("");
  404. String *arg = NewString("");
  405. String *cleanup = NewString("");
  406. String *outarg = NewString("");
  407. String *build = NewString("");
  408. String *tm;
  409. int argout_set = 0;
  410. int i = 0;
  411. int numargs;
  412. int numreq;
  413. int newobj = GetFlag(n,"feature:new");
  414. String *nodeType = Getattr(n, "nodeType");
  415. int constructor = !Cmp(nodeType, "constructor");
  416. int destructor = (!Cmp(nodeType, "destructor"));
  417. String *storage = Getattr(n,"storage");
  418. int isVirtual = !Cmp(storage,"virtual");
  419. String *overname = 0;
  420. bool isOverloaded = Getattr(n,"sym:overloaded") ? true : false;
  421. // Make a wrapper name for this
  422. String *wname = Swig_name_wrapper(iname);
  423. if (isOverloaded) {
  424. overname = Getattr(n,"sym:overname");
  425. } else {
  426. if (!addSymbol(iname,n)) return SWIG_ERROR;
  427. }
  428. if (overname) {
  429. Append(wname, overname);
  430. }
  431. /* Do this to disambiguate functions emitted from different modules */
  432. Append(wname, module);
  433. Setattr(n,"wrap:name",wname);
  434. // Build the name for Scheme.
  435. Printv(proc_name,"_",iname,NIL);
  436. String *mangled_name = mangleNameForCaml(proc_name);
  437. if( classmode && in_constructor ) { // Emit constructor for object
  438. String *mangled_name_nounder =
  439. NewString((char *)(Char(mangled_name))+1);
  440. Printf( f_class_ctors_end,
  441. "let %s clst = _%s clst\n",
  442. mangled_name_nounder, mangled_name_nounder );
  443. Printf(f_mlibody,
  444. "val %s : c_obj -> c_obj\n",
  445. mangled_name_nounder );
  446. Delete(mangled_name_nounder);
  447. } else if( classmode && in_destructor ) {
  448. Printf(f_class_ctors,
  449. " \"~\", %s ;\n", mangled_name );
  450. } else if( classmode && !in_constructor && !in_destructor &&
  451. !static_member_function ) {
  452. String *opname = Copy(Getattr(n,"name"));
  453. Replaceall(opname,"operator ","");
  454. if( strstr( Char(mangled_name), "__get__" ) ) {
  455. String *set_name = Copy(mangled_name);
  456. if( !GetFlag(n,"feature:immutable") ) {
  457. Replaceall(set_name,"__get__","__set__");
  458. Printf(f_class_ctors,
  459. " \"%s\", (fun args -> "
  460. "if args = (C_list [ raw_ptr ]) then %s args else %s args) ;\n",
  461. opname, mangled_name, set_name );
  462. Delete(set_name);
  463. } else {
  464. Printf(f_class_ctors,
  465. " \"%s\", (fun args -> "
  466. "if args = (C_list [ raw_ptr ]) then %s args else C_void) ;\n",
  467. opname, mangled_name );
  468. }
  469. } else if( strstr( Char(mangled_name), "__set__" ) ) {
  470. ; /* Nothing ... handled by the case above */
  471. } else {
  472. Printf(f_class_ctors,
  473. " \"%s\", %s ;\n",
  474. opname, mangled_name);
  475. }
  476. Delete(opname);
  477. }
  478. if( classmode && in_constructor ) {
  479. Setattr(seen_constructors,mangled_name,"true");
  480. }
  481. // writing the function wrapper function
  482. Printv(f->def,
  483. "SWIGEXT CAML_VALUE ", wname, " (", NIL);
  484. Printv(f->def, "CAML_VALUE args", NIL);
  485. Printv(f->def, ")\n{", NIL);
  486. /* Define the scheme name in C. This define is used by several
  487. macros. */
  488. //Printv(f->def, "#define FUNC_NAME \"", mangled_name, "\"", NIL);
  489. // adds local variables
  490. Wrapper_add_local(f, "args", "CAMLparam1(args)");
  491. Wrapper_add_local(f, "ret" , "SWIG_CAMLlocal2(swig_result,rv)");
  492. Wrapper_add_local(f, "_v" , "int _v = 0");
  493. if( isOverloaded ) {
  494. Wrapper_add_local(f, "i" , "int i");
  495. Wrapper_add_local(f, "argc", "int argc = caml_list_length(args)");
  496. Wrapper_add_local(f, "argv", "CAML_VALUE *argv");
  497. Printv( f->code,
  498. "argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
  499. "for( i = 0; i < argc; i++ ) {\n"
  500. " argv[i] = caml_list_nth(args,i);\n"
  501. "}\n", NIL );
  502. }
  503. // Declare return variable and arguments
  504. // number of parameters
  505. // they are called arg0, arg1, ...
  506. // the return value is called result
  507. d = SwigType_typedef_qualified(d);
  508. emit_args(d, l, f);
  509. /* Attach the standard typemaps */
  510. emit_attach_parmmaps(l,f);
  511. Setattr(n,"wrap:parms",l);
  512. numargs = emit_num_arguments(l);
  513. numreq = emit_num_required(l);
  514. Printf(f->code,"swig_result = Val_unit;\n" );
  515. // Now write code to extract the parameters (this is super ugly)
  516. for (i = 0, p = l; i < numargs; i++) {
  517. /* Skip ignored arguments */
  518. while (checkAttribute(p,"tmap:in:numinputs","0")) {
  519. p = Getattr(p,"tmap:in:next");
  520. }
  521. SwigType *pt = Getattr(p,"type");
  522. String *ln = Getattr(p,"lname");
  523. pt = SwigType_typedef_qualified(pt);
  524. // Produce names of source and target
  525. Clear(source);
  526. Clear(target);
  527. Clear(arg);
  528. Printf(source, "caml_list_nth(args,%d)", i);
  529. Printf(target, "%s",ln);
  530. Printv(arg, Getattr(p,"name"),NIL);
  531. if (i >= numreq) {
  532. Printf(f->code,"if (caml_list_length(args) > %d) {\n",i);
  533. }
  534. // Handle parameter types.
  535. if ((tm = Getattr(p,"tmap:in"))) {
  536. Replaceall(tm,"$source",source);
  537. Replaceall(tm,"$target",target);
  538. Replaceall(tm,"$input",source);
  539. Setattr(p,"emit:input",source);
  540. Printv(f->code, tm, "\n", NIL);
  541. p = Getattr(p,"tmap:in:next");
  542. } else {
  543. // no typemap found
  544. // check if typedef and resolve
  545. throw_unhandled_ocaml_type_error (pt,"in");
  546. p = nextSibling(p);
  547. }
  548. if (i >= numreq) {
  549. Printf(f->code,"}\n");
  550. }
  551. }
  552. /* Insert constraint checking code */
  553. for (p = l; p;) {
  554. if ((tm = Getattr(p,"tmap:check"))) {
  555. Replaceall(tm,"$target",Getattr(p,"lname"));
  556. Printv(f->code,tm,"\n",NIL);
  557. p = Getattr(p,"tmap:check:next");
  558. } else {
  559. p = nextSibling(p);
  560. }
  561. }
  562. // Pass output arguments back to the caller.
  563. for (p = l; p;) {
  564. if ((tm = Getattr(p,"tmap:argout"))) {
  565. Replaceall(tm,"$source",Getattr(p,"emit:input")); /* Deprecated */
  566. Replaceall(tm,"$target",Getattr(p,"lname")); /* Deprecated */
  567. Replaceall(tm,"$arg",Getattr(p,"emit:input"));
  568. Replaceall(tm,"$input",Getattr(p,"emit:input"));
  569. Replaceall(tm,"$ntype",
  570. normalizeTemplatedClassName(Getattr(p,"type")));
  571. Printv(outarg,tm,"\n",NIL);
  572. p = Getattr(p,"tmap:argout:next");
  573. argout_set = 1;
  574. } else {
  575. p = nextSibling(p);
  576. }
  577. }
  578. // Free up any memory allocated for the arguments.
  579. /* Insert cleanup code */
  580. for (p = l; p;) {
  581. if ((tm = Getattr(p,"tmap:freearg"))) {
  582. Replaceall(tm,"$target",Getattr(p,"lname"));
  583. Printv(cleanup,tm,"\n",NIL);
  584. p = Getattr(p,"tmap:freearg:next");
  585. } else {
  586. p = nextSibling(p);
  587. }
  588. }
  589. /* if the object is a director, and the method call originated from its
  590. * underlying python object, resolve the call by going up the c++
  591. * inheritance chain. otherwise try to resolve the method in python.
  592. * without this check an infinite loop is set up between the director and
  593. * shadow class method calls.
  594. */
  595. // NOTE: this code should only be inserted if this class is the
  596. // base class of a director class. however, in general we haven't
  597. // yet analyzed all classes derived from this one to see if they are
  598. // directors. furthermore, this class may be used as the base of
  599. // a director class defined in a completely different module at a
  600. // later time, so this test must be included whether or not directorbase
  601. // is true. we do skip this code if directors have not been enabled
  602. // at the command line to preserve source-level compatibility with
  603. // non-polymorphic swig. also, if this wrapper is for a smart-pointer
  604. // method, there is no need to perform the test since the calling object
  605. // (the smart-pointer) and the director object (the "pointee") are
  606. // distinct.
  607. if (directorsEnabled()) {
  608. if (!is_smart_pointer()) {
  609. if (/*directorbase &&*/ !constructor && !destructor
  610. && isVirtual && !Getattr(n,"feature:nodirector")) {
  611. Wrapper_add_local(f, "director", "Swig::Director *director = 0");
  612. Printf(f->code, "director = dynamic_cast<Swig::Director *>(arg1);\n");
  613. Printf(f->code,
  614. "if (director && !director->swig_get_up(false))"
  615. "director->swig_set_up();\n");
  616. }
  617. }
  618. }
  619. // Now write code to make the function call
  620. emit_action(n,f);
  621. // Now have return value, figure out what to do with it.
  622. if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) {
  623. Replaceall(tm,"$source","swig_result");
  624. Replaceall(tm,"$target","rv");
  625. Replaceall(tm,"$result","rv");
  626. Replaceall(tm,"$ntype",return_type_normalized);
  627. Printv(f->code, tm, "\n",NIL);
  628. } else {
  629. throw_unhandled_ocaml_type_error (d, "out");
  630. }
  631. // Dump the argument output code
  632. Printv(f->code, Char(outarg),NIL);
  633. // Dump the argument cleanup code
  634. Printv(f->code, Char(cleanup),NIL);
  635. // Look for any remaining cleanup
  636. if (GetFlag(n,"feature:new")) {
  637. if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) {
  638. Replaceall(tm,"$source","swig_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("swig_result",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. Printv(f->code,
  649. tab4, "swig_result = caml_list_append(swig_result,rv);\n", NIL);
  650. if( isOverloaded )
  651. Printv(f->code, "free(argv);\n", NIL);
  652. Printv(f->code,
  653. tab4, "CAMLreturn(swig_result);\n", NIL );
  654. Printv(f->code, "}\n",NIL);
  655. Wrapper_print(f, f_wrappers);
  656. if( isOverloaded ) {
  657. if( !Getattr(n,"sym:nextSibling") ) {
  658. int maxargs;
  659. Wrapper *df = NewWrapper();
  660. String *dispatch =
  661. Swig_overload_dispatch(n,
  662. "free(argv);\n"
  663. "CAMLreturn(%s(args));\n",
  664. &maxargs);
  665. Wrapper_add_local(df, "_v", "int _v = 0");
  666. Wrapper_add_local(df, "argv", "CAML_VALUE *argv");
  667. /* Undifferentiate name .. this is the dispatch function */
  668. wname = Swig_name_wrapper(iname);
  669. /* Do this to disambiguate functions emitted from different
  670. * modules */
  671. Append(wname, module);
  672. Printv(df->def,
  673. "SWIGEXT CAML_VALUE ",wname,"(CAML_VALUE args) {\n"
  674. " CAMLparam1(args);\n"
  675. " int i;\n"
  676. " int argc = caml_list_length(args);\n",NIL);
  677. Printv( df->code,
  678. "argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
  679. "for( i = 0; i < argc; i++ ) {\n"
  680. " argv[i] = caml_list_nth(args,i);\n"
  681. "}\n", NIL );
  682. Printv(df->code,dispatch,"\n",NIL);
  683. Printf(df->code,"failwith(\"No matching function for overloaded '%s'\");\n", iname);
  684. Printv(df->code,"}\n",NIL);
  685. Wrapper_print(df,f_wrappers);
  686. DelWrapper(df);
  687. Delete(dispatch);
  688. }
  689. }
  690. Printf(f_mlbody,
  691. "external %s_f : c_obj list -> c_obj list = \"%s\" ;;\n"
  692. "let %s arg = match %s_f (fnhelper arg) with\n"
  693. " [] -> C_void\n"
  694. "| [x] -> (if %s then Gc.finalise \n"
  695. " (fun x -> ignore ((invoke x) \"~\" C_void)) x) ; x\n"
  696. "| lst -> C_list lst ;;\n",
  697. mangled_name, wname,
  698. mangled_name, mangled_name, newobj ? "true" : "false");
  699. if( !classmode || in_constructor || in_destructor ||
  700. static_member_function )
  701. Printf(f_mlibody,
  702. "val %s : c_obj -> c_obj\n", mangled_name );
  703. Delete(proc_name);
  704. Delete(source);
  705. Delete(target);
  706. Delete(arg);
  707. Delete(outarg);
  708. Delete(cleanup);
  709. Delete(build);
  710. DelWrapper(f);
  711. return SWIG_OK;
  712. }
  713. /* ------------------------------------------------------------
  714. * variableWrapper()
  715. *
  716. * Create a link to a C variable.
  717. * This creates a single function _wrap_swig_var_varname().
  718. * This function takes a single optional argument. If supplied, it means
  719. * we are setting this variable to some value. If omitted, it means we are
  720. * simply evaluating this variable. In the set case we return C_void.
  721. *
  722. * symname is the name of the variable with respect to C. This
  723. * may need to differ from the original name in the case of enums.
  724. * enumvname is the name of the variable with respect to ocaml. This
  725. * will vary if the variable has been renamed.
  726. * ------------------------------------------------------------ */
  727. virtual int variableWrapper(Node *n) {
  728. char *name = GetChar(n,"feature:symname");
  729. String *iname = Getattr(n,"feature:enumvname");
  730. String *mname = mangleNameForCaml(iname);
  731. SwigType *t = Getattr(n,"type");
  732. String *proc_name = NewString("");
  733. char var_name[256];
  734. String *tm;
  735. String *tm2 = NewString("");;
  736. String *argnum = NewString("0");
  737. String *arg = NewString("SWIG_Field(args,0)");
  738. Wrapper *f;
  739. if( !name ) {
  740. name = GetChar(n,"name");
  741. }
  742. if( !iname ) {
  743. iname = Getattr(n,"sym:name");
  744. mname = mangleNameForCaml(NewString(iname));
  745. }
  746. if (!iname || !addSymbol(iname,n)) return SWIG_ERROR;
  747. f = NewWrapper();
  748. // evaluation function names
  749. strcpy(var_name, Char(Swig_name_wrapper(iname)));
  750. // Build the name for scheme.
  751. Printv(proc_name, iname, NIL);
  752. Printf (f->def,
  753. "SWIGEXT CAML_VALUE %s(CAML_VALUE args) {\n", var_name);
  754. // Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
  755. Wrapper_add_local (f, "swig_result", "CAML_VALUE swig_result");
  756. if (!GetFlag(n,"feature:immutable")) {
  757. /* Check for a setting of the variable value */
  758. Printf (f->code, "if (args != Val_int(0)) {\n");
  759. if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) {
  760. Replaceall(tm,"$source","args");
  761. Replaceall(tm,"$target",name);
  762. Replaceall(tm,"$input","args");
  763. Printv(f->code, tm, "\n",NIL);
  764. } else if ((tm = Swig_typemap_lookup_new("in",n,name,0))) {
  765. Replaceall(tm,"$source","args");
  766. Replaceall(tm,"$target",name);
  767. Replaceall(tm,"$input","args");
  768. Printv(f->code, tm, "\n",NIL);
  769. } else {
  770. throw_unhandled_ocaml_type_error (t, "varin/in");
  771. }
  772. Printf (f->code, "}\n");
  773. }
  774. // Now return the value of the variable (regardless
  775. // of evaluating or setting)
  776. if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) {
  777. Replaceall(tm,"$source",name);
  778. Replaceall(tm,"$target","swig_result");
  779. Replaceall(tm,"$result","swig_result");
  780. Printf (f->code, "%s\n", tm);
  781. } else if ((tm = Swig_typemap_lookup_new("out",n,name,0))) {
  782. Replaceall(tm,"$source",name);
  783. Replaceall(tm,"$target","swig_result");
  784. Replaceall(tm,"$result","swig_result");
  785. Printf (f->code, "%s\n", tm);
  786. } else {
  787. throw_unhandled_ocaml_type_error (t, "varout/out");
  788. }
  789. Printf (f->code, "\nreturn swig_result;\n");
  790. Printf (f->code, "}\n");
  791. Wrapper_print (f, f_wrappers);
  792. // Now add symbol to the Ocaml interpreter
  793. if( GetFlag( n, "feature:immutable" ) ) {
  794. Printf( f_mlbody,
  795. "external _%s : c_obj -> Swig.c_obj = \"%s\" \n",
  796. mname, var_name );
  797. Printf( f_mlibody, "val _%s : c_obj -> Swig.c_obj\n", iname );
  798. if( const_enum ) {
  799. Printf( f_enum_to_int,
  800. " | `%s -> _%s C_void\n",
  801. mname, mname );
  802. Printf( f_int_to_enum,
  803. " if y = (get_int (_%s C_void)) then `%s else\n",
  804. mname, mname );
  805. }
  806. } else {
  807. Printf( f_mlbody, "external _%s : c_obj -> c_obj = \"%s\"\n",
  808. mname, var_name );
  809. Printf( f_mlibody, "external _%s : c_obj -> c_obj = \"%s\"\n",
  810. mname, var_name );
  811. }
  812. Delete(proc_name);
  813. Delete(argnum);
  814. Delete(arg);
  815. Delete(tm2);
  816. DelWrapper(f);
  817. return SWIG_OK;
  818. }
  819. /* ------------------------------------------------------------
  820. * staticmemberfunctionHandler --
  821. * Overridden to set static_member_function
  822. * ------------------------------------------------------------ */
  823. virtual int staticmemberfunctionHandler( Node *n ) {
  824. int rv;
  825. static_member_function = 1;
  826. rv = Language::staticmemberfunctionHandler( n );
  827. static_member_function = 0;
  828. return SWIG_OK;
  829. }
  830. /* ------------------------------------------------------------
  831. * constantWrapper()
  832. *
  833. * The one trick here is that we have to make sure we rename the
  834. * constant to something useful that doesn't collide with the
  835. * original if any exists.
  836. * ------------------------------------------------------------ */
  837. virtual int constantWrapper(Node *n) {
  838. String *name = Getattr(n,"feature:symname");
  839. SwigType *type = Getattr(n,"type");
  840. String *value = Getattr(n,"value");
  841. String *qvalue = Getattr(n,"qualified:value");
  842. String *rvalue = NewString("");
  843. String *temp = 0;
  844. if( qvalue ) value = qvalue;
  845. if( !name ) {
  846. name = mangleNameForCaml(Getattr(n,"name"));
  847. Insert(name,0,"_swig_wrap_");
  848. Setattr(n,"feature:symname",name);
  849. }
  850. // See if there's a typemap
  851. Printv(rvalue, value,NIL);
  852. if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) {
  853. temp = Copy(rvalue);
  854. Clear(rvalue);
  855. Printv(rvalue, "\"", temp, "\"",NIL);
  856. Delete(temp);
  857. }
  858. if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) {
  859. temp = Copy(rvalue);
  860. Clear(rvalue);
  861. Printv(rvalue, "'", temp, "'",NIL);
  862. Delete(temp);
  863. }
  864. // Create variable and assign it a value
  865. Printf (f_header, "static %s = ", SwigType_lstr(type,name));
  866. if ((SwigType_type(type) == T_STRING)) {
  867. Printf (f_header, "\"%s\";\n", value);
  868. } else if (SwigType_type(type) == T_CHAR) {
  869. Printf (f_header, "\'%s\';\n", value);
  870. } else {
  871. Printf (f_header, "%s;\n", value);
  872. }
  873. SetFlag(n,"feature:immutable");
  874. variableWrapper(n);
  875. return SWIG_OK;
  876. }
  877. int constructorHandler(Node *n) {
  878. int ret;
  879. in_constructor = 1;
  880. ret = Language::constructorHandler(n);
  881. in_constructor = 0;
  882. return ret;
  883. }
  884. /* destructorHandler:
  885. * Turn on destructor flag to inform decisions in functionWrapper
  886. */
  887. int destructorHandler(Node *n) {
  888. int ret;
  889. in_destructor = 1;
  890. ret = Language::destructorHandler(n);
  891. in_destructor = 0;
  892. return ret;
  893. }
  894. /* copyconstructorHandler:
  895. * Turn on constructor and copyconstructor flags for functionWrapper
  896. */
  897. int copyconstructorHandler(Node *n) {
  898. int ret;
  899. in_copyconst = 1;
  900. in_constructor = 1;
  901. ret = Language::copyconstructorHandler(n);
  902. in_constructor = 0;
  903. in_copyconst = 0;
  904. return ret;
  905. }
  906. /**
  907. * A simple, somewhat general purpose function for writing to multiple
  908. * streams from a source template. This allows the user to define the
  909. * class definition in ways different from the one I have here if they
  910. * want to. It will also make the class definition system easier to
  911. * fiddle with when I want to change methods, etc.
  912. */
  913. void Multiwrite( String *s ) {
  914. char *find_marker = strstr(Char(s),"(*Stream:");
  915. while( find_marker ) {
  916. char *next = strstr(find_marker,"*)");
  917. find_marker += strlen("(*Stream:");
  918. if( next ) {
  919. int num_chars = next - find_marker;
  920. String *stream_name = NewString(find_marker);
  921. Delslice(stream_name,num_chars,Len(stream_name));
  922. File *fout = Swig_filebyname(stream_name);
  923. if( fout ) {
  924. next += strlen("*)");
  925. char *following = strstr(next,"(*Stream:");
  926. find_marker = following;
  927. if( !following ) following = next + strlen(next);
  928. String *chunk = NewString(next);
  929. Delslice(chunk,following-next,Len(chunk));
  930. Printv(fout,chunk,NIL);
  931. }
  932. }
  933. }
  934. }
  935. bool isSimpleType( String *name ) {
  936. char *ch = Char(name);
  937. return
  938. !(strchr(ch,'(') || strchr(ch,'<') ||
  939. strchr(ch,')') || strchr(ch,'>'));
  940. }
  941. /* We accept all chars in identifiers because we use strings to index
  942. * them. */
  943. int validIdentifier( String *name ) {
  944. return Len(name) > 0 ? 1 : 0;
  945. }
  946. /* classHandler
  947. *
  948. * Create a "class" definition for ocaml. I thought quite a bit about
  949. * how I should do this part of it, and arrived here, using a function
  950. * invocation to select a method, and dispatch. This can obviously be
  951. * done better, but I can't see how, given that I want to support
  952. * overloaded methods, out parameters, and operators.
  953. *
  954. * I needed a system that would do this:
  955. *
  956. * a Be able to call these methods:
  957. * int foo( int x );
  958. * float foo( int x, int &out );
  959. *
  960. * b Be typeable, even in the presence of mutually dependent classes.
  961. *
  962. * c Support some form of operator invocation.
  963. *
  964. * (c) I chose strings for the method names so that "+=" would be a
  965. * valid method name, and the somewhat natural << (invoke x) "+=" y >>
  966. * would work.
  967. *
  968. * (a) (b) Since the c_obj type exists, it's easy to return C_int in one
  969. * case and C_list [ C_float ; C_int ] in the other. This makes tricky
  970. * problems with out parameters disappear; they're simply appended to the
  971. * return list.
  972. *
  973. * (b) Since every item that comes from C++ is the same type, there is no
  974. * problem with the following:
  975. *
  976. * class Foo;
  977. * class Bar { Foo *toFoo(); }
  978. * class Foo { Bar *toBar(); }
  979. *
  980. * Since the Objective caml types of Foo and Bar are the same. Now that
  981. * I correctly incorporate SWIG's typechecking, this isn't a big deal.
  982. *
  983. * The class is in the form of a function returning a c_obj. The c_obj
  984. * is a C_obj containing a function which invokes a method on the
  985. * underlying object given its type.
  986. *
  987. * The name emitted here is normalized before being sent to
  988. * Callback.register, because we need this string to look up properly
  989. * when the typemap passes the descriptor string. I've been considering
  990. * some, possibly more forgiving method that would do some transformations
  991. * on the $descriptor in order to find a potential match. This is for
  992. * later.
  993. *
  994. * Important things to note:
  995. *
  996. * We rely on exception handling (BadMethodName) in order to call an
  997. * ancestor. This can be improved.
  998. *
  999. * The method used to get :classof could be improved to look at the type
  1000. * info that the base pointer contains. It's really an error to have a
  1001. * SWIG-generated object that does not contain type info, since the
  1002. * existence of the object means that SWIG knows the type.
  1003. *
  1004. * :parents could use :classof to tell what class it is and make a better
  1005. * decision. This could be nice, (i.e. provide a run-time graph of C++
  1006. * classes represented);.
  1007. *
  1008. * I can't think of a more elegant way of converting a C_obj fun to a
  1009. * pointer than "operator &"...
  1010. *
  1011. * Added a 'sizeof' that will allow you to do the expected thing.
  1012. * This should help users to fill buffer structs and the like (as is
  1013. * typical in windows-styled code). It's only enabled if you give
  1014. * %feature(sizeof) and then, only for simple types.
  1015. *
  1016. * Overall, carrying the list of methods and base classes has worked well.
  1017. * It allows me to give the Ocaml user introspection over their objects.
  1018. */
  1019. int classHandler( Node *n ) {
  1020. String *name = Getattr(n,"name");
  1021. String *mangled_sym_name = mangleNameForCaml(name);
  1022. String *this_class_def = NewString( f_classtemplate );
  1023. String *name_normalized = normalizeTemplatedClassName(name);
  1024. String *old_class_ctors = f_class_ctors;
  1025. String *base_classes = NewString("");
  1026. f_class_ctors = NewString("");
  1027. bool sizeof_feature = generate_sizeof && isSimpleType(name);
  1028. if( !name ) return SWIG_OK;
  1029. classname = mangled_sym_name;
  1030. classmode = true;
  1031. int rv = Language::classHandler(n);
  1032. classmode = false;
  1033. if( sizeof_feature ) {
  1034. Printf( f_wrappers,
  1035. "SWIGEXT CAML_VALUE _wrap_%s_sizeof( CAML_VALUE args ) {\n"
  1036. " CAMLparam1(args);\n"
  1037. " CAMLreturn(Val_int(sizeof(%s)));\n"
  1038. "}\n",
  1039. mangled_sym_name, name_normalized );
  1040. Printf( f_mlbody, "external __%s_sizeof : unit -> int = "
  1041. "\"_wrap_%s_sizeof\"\n",
  1042. classname, mangled_sym_name );
  1043. }
  1044. /* Insert sizeof operator for concrete classes */
  1045. if( sizeof_feature ) {
  1046. Printv(f_class_ctors, "\"sizeof\" , (fun args -> C_int (__",
  1047. classname, "_sizeof ())) ;\n", NIL);
  1048. }
  1049. /* Handle up-casts in a nice way */
  1050. List *baselist = Getattr(n,"bases");
  1051. if (baselist && Len(baselist)) {
  1052. Iterator b;
  1053. b = First(baselist);
  1054. while (b.item) {
  1055. String *bname = Getattr(b.item, "name");
  1056. if (bname) {
  1057. String *base_create = NewString("");
  1058. Printv(base_create,"(create_class \"",bname,"\")",NIL);
  1059. Printv(f_class_ctors,
  1060. " \"::",bname,"\", (fun args -> ",
  1061. base_create," args) ;\n",NIL);
  1062. Printv( base_classes, base_create, " ;\n", NIL );
  1063. }
  1064. b = Next(b);
  1065. }
  1066. }
  1067. Replaceall(this_class_def,"$classname",classname);
  1068. Replaceall(this_class_def,"$normalized",name_normalized);
  1069. Replaceall(this_class_def,"$realname",name);
  1070. Replaceall(this_class_def,"$baselist",base_classes);
  1071. Replaceall(this_class_def,"$classbody",f_class_ctors);
  1072. Delete(f_class_ctors);
  1073. f_class_ctors = old_class_ctors;
  1074. // Actually write out the class definition
  1075. Multiwrite( this_class_def );
  1076. Setattr(n,"ocaml:ctor",classname);
  1077. return rv;
  1078. }
  1079. String *normalizeTemplatedClassName( String *name ) {
  1080. String *name_normalized = SwigType_typedef_resolve_all(name);
  1081. bool took_action;
  1082. do {
  1083. took_action = false;
  1084. if( is_a_pointer(name_normalized) ) {
  1085. SwigType_del_pointer( name_normalized );
  1086. took_action = true;
  1087. }
  1088. if( is_a_reference(name_normalized) ) {
  1089. oc_SwigType_del_reference( name_normalized );
  1090. took_action = true;
  1091. }
  1092. if( is_an_array(name_normalized) ) {
  1093. oc_SwigType_del_array( name_normalized );
  1094. took_action = true;
  1095. }
  1096. } while( took_action );
  1097. return SwigType_str(name_normalized,0);
  1098. }
  1099. /*
  1100. * Produce the symbol name that ocaml will use when referring to the
  1101. * target item. I wonder if there's a better way to do this:
  1102. *
  1103. * I shudder to think about doing it with a hash lookup, but that would
  1104. * make a couple of things easier:
  1105. */
  1106. String *mangleNameForCaml( String *s ) {
  1107. String *out = Copy(s);
  1108. Replaceall(out," ","_xx");
  1109. Replaceall(out,"::","_xx");
  1110. Replaceall(out,",","_x");
  1111. Replaceall(out,"+","_xx_plus");
  1112. Replaceall(out,"-","_xx_minus");
  1113. Replaceall(out,"<","_xx_ldbrace");
  1114. Replaceall(out,">","_xx_rdbrace");
  1115. Replaceall(out,"!","_xx_not");
  1116. Replaceall(out,"%","_xx_mod");
  1117. Replaceall(out,"^","_xx_xor");
  1118. Replaceall(out,"*","_xx_star");
  1119. Replaceall(out,"&","_xx_amp");
  1120. Replaceall(out,"|","_xx_or");
  1121. Replaceall(out,"(","_xx_lparen");
  1122. Replaceall(out,")","_xx_rparen");
  1123. Replaceall(out,"[","_xx_lbrace");
  1124. Replaceall(out,"]","_xx_rbrace");
  1125. Replaceall(out,"~","_xx_bnot");
  1126. Replaceall(out,"=","_xx_equals");
  1127. Replaceall(out,"/","_xx_slash");
  1128. Replaceall(out,".","_xx_dot");
  1129. return out;
  1130. }
  1131. String *fully_qualify_enum_name( Node *n, String *name ) {
  1132. Node *parent = 0;
  1133. String *qualification = NewString("");
  1134. String *fully_qualified_name = NewString("");
  1135. String *parent_type = 0;
  1136. String *normalized_name;
  1137. parent = parentNode(n);
  1138. while( parent ) {
  1139. parent_type = nodeType(parent);
  1140. if( Getattr(parent,"name") ) {
  1141. String *parent_copy =
  1142. NewStringf("%s::",Getattr(parent,"name"));
  1143. if( !Cmp(parent_type,"class") ||
  1144. !Cmp(parent_type,"namespace") )
  1145. Insert(qualification,0,parent_copy);
  1146. Delete(parent_copy);
  1147. }
  1148. if( !Cmp( parent_type, "class" ) ) break;
  1149. parent = parentNode(parent);
  1150. }
  1151. Printf( fully_qualified_name, "%s%s", qualification, name );
  1152. normalized_name = normalizeTemplatedClassName(fully_qualified_name);
  1153. if( !strncmp(Char(normalized_name),"enum ",5) ) {
  1154. Insert(normalized_name,5,qualification);
  1155. }
  1156. return normalized_name;
  1157. }
  1158. /* Benedikt Grundmann inspired --> Enum wrap styles */
  1159. int enumvalueDeclaration(Node *n) {
  1160. String *name = Getattr(n,"name");
  1161. String *qvalue = 0;
  1162. if( name_qualifier ) {
  1163. qvalue = Copy(name_qualifier);
  1164. Printv( qvalue, name, NIL );
  1165. }
  1166. if( const_enum && name && !Getattr(seen_enumvalues,name) ) {
  1167. Setattr(seen_enumvalues,name,"true");
  1168. SetFlag(n,"feature:immutable");
  1169. Setattr(n,"feature:enumvalue","1"); // this does not appear to be used
  1170. if( qvalue )
  1171. Setattr(n,"qualified:value",qvalue);
  1172. String *evname = SwigType_manglestr(qvalue);
  1173. Insert( evname, 0, "SWIG_ENUM_" );
  1174. Setattr(n,"feature:enumvname",name);
  1175. Setattr(n,"feature:symname",evname);
  1176. Delete( evname );
  1177. Printf( f_enumtypes_value, "| `%s\n", name );
  1178. return Language::enumvalueDeclaration(n);
  1179. } else return SWIG_OK;
  1180. }
  1181. /* -------------------------------------------------------------------
  1182. * This function is a bit uglier than it deserves.
  1183. *
  1184. * I used to direct lookup the name of the enum. Now that certain fixes
  1185. * have been made in other places, the names of enums are now fully
  1186. * qualified, which is a good thing, overall, but requires me to do
  1187. * some legwork.
  1188. *
  1189. * The other thing that uglifies this function is the varying way that
  1190. * typedef enum and enum are handled. I need to produce consistent names,
  1191. * which means looking up and registering by typedef and enum name. */
  1192. int enumDeclaration(Node *n) {
  1193. String *name = Getattr(n,"name");
  1194. String *oname = name ? NewString(name) : NULL;
  1195. /* name is now fully qualified */
  1196. String *fully_qualified_name = NewString(name);
  1197. bool seen_enum = false;
  1198. if( name_qualifier )
  1199. Delete(name_qualifier);
  1200. char *strip_position;
  1201. name_qualifier = fully_qualify_enum_name(n,NewString(""));
  1202. /* Recent changes have distrubed enum and template naming again.
  1203. * Will try to keep it consistent by can't guarantee much given
  1204. * that these things move around a lot.
  1205. *
  1206. * I need to figure out a way to isolate this module better.
  1207. */
  1208. if( oname ) {
  1209. strip_position = strstr(Char(oname),"::");
  1210. while( strip_position ) {
  1211. strip_position += 2;
  1212. oname = NewString( strip_position );
  1213. strip_position = strstr( Char(oname), "::" );
  1214. }
  1215. }
  1216. seen_enum = oname ?
  1217. (Getattr(seen_enums,fully_qualified_name) ? true : false) : false;
  1218. if( oname && !seen_enum ) {
  1219. const_enum = true;
  1220. Printf( f_enum_to_int, "| `%s -> (match y with\n", oname );
  1221. Printf( f_int_to_enum, "| `%s -> C_enum (\n", oname );
  1222. /* * * * A note about enum name resolution * * * *
  1223. * This code should now work, but I think we can do a bit better.
  1224. * The problem I'm having is that swig isn't very precise about
  1225. * typedef name resolution. My opinion is that SwigType_typedef
  1226. * resolve_all should *always* return the enum tag if one exists,
  1227. * rather than the admittedly friendlier enclosing typedef.
  1228. *
  1229. * This would make one of the cases below unnecessary.
  1230. * * * */
  1231. Printf( f_mlbody,
  1232. "let _ = Callback.register \"%s_marker\" (`%s)\n",
  1233. fully_qualified_name, oname );
  1234. if( !strncmp(Char(fully_qualified_name),"enum ",5) ) {
  1235. String *fq_noenum = NewString(Char(fully_qualified_name) + 5);
  1236. Printf( f_mlbody,
  1237. "let _ = Callback.register \"%s_marker\" (`%s)\n"
  1238. "let _ = Callback.register \"%s_marker\" (`%s)\n",
  1239. fq_noenum, oname,
  1240. fq_noenum, name );
  1241. }
  1242. Printf( f_enumtypes_type,"| `%s\n", oname );
  1243. Insert(fully_qualified_name,0,"enum ");
  1244. Setattr(seen_enums,fully_qualified_name,n);
  1245. }
  1246. int ret = Language::enumDeclaration(n);
  1247. if( const_enum ) {
  1248. Printf( f_int_to_enum, "`Int y)\n" );
  1249. Printf( f_enum_to_int,
  1250. "| `Int x -> Swig.C_int x\n"
  1251. "| _ -> raise (LabelNotFromThisEnum v))\n" );
  1252. }
  1253. const_enum = false;
  1254. return ret;
  1255. }
  1256. /***************************************************************************
  1257. * BEGIN C++ Director Class modifications
  1258. ***************************************************************************/
  1259. /*
  1260. * Modified polymorphism code for Ocaml language module.
  1261. * Original:
  1262. * C++/Python polymorphism demo code, copyright (C) 2002 Mark Rose
  1263. * <mrose@stm.lbl.gov>
  1264. *
  1265. * TODO
  1266. *
  1267. * Move some boilerplate code generation to Swig_...() functions.
  1268. *
  1269. */
  1270. /* ---------------------------------------------------------------
  1271. * classDirectorMethod()
  1272. *
  1273. * Emit a virtual director method to pass a method call on to the
  1274. * underlying Python object.
  1275. *
  1276. * --------------------------------------------------------------- */
  1277. int classDirectorMethod(Node *n, Node *parent, String *super) {
  1278. int is_void = 0;
  1279. int is_pointer = 0;
  1280. String *storage;
  1281. String *value;
  1282. String *decl;
  1283. String *type;
  1284. String *name;
  1285. String *classname;
  1286. String *declaration;
  1287. ParmList *l;
  1288. Wrapper *w;
  1289. String *tm;
  1290. String *wrap_args;
  1291. String *return_type;
  1292. int status = SWIG_OK;
  1293. int idx;
  1294. bool pure_virtual = false;
  1295. storage = Getattr(n, "storage");
  1296. value = Getattr(n, "value");
  1297. classname = Getattr(parent, "sym:name");
  1298. type = Getattr(n, "type");
  1299. name = Getattr(n, "name");
  1300. if (Cmp(storage,"virtual") == 0) {
  1301. if (Cmp(value,"0") == 0) {
  1302. pure_virtual = true;
  1303. }
  1304. }
  1305. w = NewWrapper();
  1306. declaration = NewString("");
  1307. Wrapper_add_local(w,"swig_result",
  1308. "CAMLparam0();\n"
  1309. "SWIG_CAMLlocal2(swig_result,args)");
  1310. /* determine if the method returns a pointer */
  1311. decl = Getattr(n, "decl");
  1312. is_pointer = SwigType_ispointer_return(decl);
  1313. is_void = (!Cmp(type, "void") && !is_pointer);
  1314. /* form complete return type */
  1315. return_type = Copy(type);
  1316. {
  1317. SwigType *t = Copy(decl);
  1318. SwigType *f = 0;
  1319. f = SwigType_pop_function(t);
  1320. SwigType_push(return_type, t);
  1321. Delete(f);
  1322. Delete(t);
  1323. }
  1324. /* virtual method definition */
  1325. l = Getattr(n, "parms");
  1326. String *target;
  1327. String *pclassname = NewStringf("SwigDirector_%s", classname);
  1328. String *qualified_name = NewStringf("%s::%s", pclassname, name);
  1329. target = Swig_method_decl(decl, qualified_name, l, 0, 0);
  1330. String *rtype = SwigType_str(type, 0);
  1331. Printf(w->def, "%s %s {", rtype, target);
  1332. Delete(qualified_name);
  1333. Delete(target);
  1334. /* header declaration */
  1335. target = Swig_method_decl(decl, name, l, 0, 1);
  1336. Printf(declaration, " virtual %s %s;\n", rtype, target);
  1337. Delete(target);
  1338. /* attach typemaps to arguments (C/C++ -> Ocaml) */
  1339. String *arglist = NewString("");
  1340. Swig_typemap_attach_parms("in", l, 0);
  1341. Swig_typemap_attach_parms("directorin", l, 0);
  1342. Swig_typemap_attach_parms("directorargout", l, w);
  1343. Parm* p;
  1344. int num_arguments = emit_num_arguments(l);
  1345. int i;
  1346. char source[256];
  1347. wrap_args = NewString("");
  1348. int outputs = 0;
  1349. if (!is_void) outputs++;
  1350. /* build argument list and type conversion string */
  1351. for (i=0, idx=0, p = l; i < num_arguments; i++) {
  1352. while (Getattr(p, "tmap:ignore")) {
  1353. p = Getattr(p, "tmap:ignore:next");
  1354. }
  1355. if (Getattr(p, "tmap:directorargout") != 0) outputs++;
  1356. String* pname = Getattr(p, "name");
  1357. String* ptype = Getattr(p, "type");
  1358. Putc(',',arglist);
  1359. if ((tm = Getattr(p, "tmap:directorin")) != 0) {
  1360. Replaceall(tm, "$input", pname);
  1361. Replaceall(tm, "$owner", "0");
  1362. if (Len(tm) == 0) Append(tm, pname);
  1363. Printv(wrap_args, tm, "\n", NIL);
  1364. p = Getattr(p, "tmap:directorin:next");
  1365. continue;
  1366. } else
  1367. if (Cmp(ptype, "void")) {
  1368. /* special handling for pointers to other C++ director classes.
  1369. * ideally this would be left to a typemap, but there is currently no
  1370. * way to selectively apply the dynamic_cast<> to classes that have
  1371. * directors. in other words, the type "SwigDirector_$1_lname" only exists
  1372. * for classes with directors. we avoid the problem here by checking
  1373. * module.wrap::directormap, but it's not clear how to get a typemap to
  1374. * do something similar. perhaps a new default typemap (in addition
  1375. * to SWIGTYPE) called DIRECTORTYPE?
  1376. */
  1377. if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
  1378. Node *module = Getattr(parent, "module");
  1379. Node *target = Swig_directormap(module, ptype);
  1380. sprintf(source, "obj%d", idx++);
  1381. String *nonconst = 0;
  1382. /* strip pointer/reference --- should move to Swig/stype.c */
  1383. String *nptype = NewString(Char(ptype)+2);
  1384. /* name as pointer */
  1385. String *ppname = Copy(pname);
  1386. if (SwigType_isreference(ptype)) {
  1387. Insert(ppname,0,"&");
  1388. }
  1389. /* if necessary, cast away const since Python doesn't support it! */
  1390. if (SwigType_isconst(nptype)) {
  1391. nonconst = NewStringf("nc_tmp_%s", pname);
  1392. String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(ptype, 0), ppname);
  1393. Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
  1394. Delete(nonconst_i);
  1395. Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
  1396. "Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(ptype, pname), classname, name);
  1397. } else {
  1398. nonconst = Copy(ppname);
  1399. }
  1400. Delete(nptype);
  1401. Delete(ppname);
  1402. String *mangle = SwigType_manglestr(ptype);
  1403. if (target) {
  1404. String *director = NewStringf("director_%s", mangle);
  1405. Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
  1406. Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
  1407. Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst);
  1408. Printf(wrap_args, "if (!%s) {\n", director);
  1409. Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
  1410. Printf(wrap_args, "} else {\n");
  1411. Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
  1412. Printf(wrap_args, "}\n");
  1413. Delete(director);
  1414. Printv(arglist, source, NIL);
  1415. } else {
  1416. Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
  1417. Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n",
  1418. source, nonconst, mangle);
  1419. //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
  1420. // source, nonconst, base);
  1421. Printv(arglist, source, NIL);
  1422. }
  1423. Delete(mangle);
  1424. Delete(nonconst);
  1425. } else {
  1426. Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
  1427. "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), classname, name);
  1428. status = SWIG_NOWRAP;
  1429. break;
  1430. }
  1431. }
  1432. p = nextSibling(p);
  1433. }
  1434. /* declare method return value
  1435. * if the return value is a reference or const reference, a specialized typemap must
  1436. * handle it, including declaration of c_result ($result).
  1437. */
  1438. if (!is_void) {
  1439. Wrapper_add_localv(w, "c_result", SwigType_lstr(return_type, "c_result"), NIL);
  1440. }
  1441. Printv(w->code, "swig_result = Val_unit;\n",0);
  1442. Printf(w->code,"args = Val_unit;\n");
  1443. /* direct call to superclass if _up is set */
  1444. if( pure_virtual ) {
  1445. Printf(w->code, "if (swig_get_up()) {\n");
  1446. Printf(w->code, " throw Swig::DirectorPureVirtualException();\n");
  1447. Printf(w->code, "}\n");
  1448. } else {
  1449. Printf(w->code, "if (swig_get_up()) {\n");
  1450. Printf(w->code, "CAMLreturn(%s);\n", Swig_method_call(super,l));
  1451. Printf(w->code, "}\n");
  1452. }
  1453. /* wrap complex arguments to values */
  1454. Printv(w->code, wrap_args, NIL);
  1455. /* pass the method call on to the Python object */
  1456. Printv(w->code,
  1457. "swig_result = caml_swig_alloc(1,C_list);\n"
  1458. "SWIG_Store_field(swig_result,0,args);\n"
  1459. "args = swig_result;\n"
  1460. "swig_result = Val_unit;\n",0);
  1461. Printf(w->code,
  1462. "swig_result = "
  1463. "callback3(*caml_named_value(\"swig_runmethod\"),"
  1464. "swig_get_self(),copy_string(\"%s\"),args);\n",
  1465. Getattr(n,"name"));
  1466. /* exception handling */
  1467. tm = Swig_typemap_lookup_new("director:except", n, "result", 0);
  1468. if (!tm) {
  1469. tm = Getattr(n, "feature:director:except");
  1470. }
  1471. if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
  1472. Printf(w->code, "if (result == NULL) {\n");
  1473. Printf(w->code, " CAML_VALUE error = *caml_named_value(\"director_except\");\n");
  1474. Replaceall(tm, "$error", "error");
  1475. Printv(w->code, Str(tm), "\n", NIL);
  1476. Printf(w->code, "}\n");
  1477. }
  1478. /*
  1479. * Python method may return a simple object, or a tuple.
  1480. * for in/out aruments, we have to extract the appropriate values from the
  1481. * argument list, then marshal everything back to C/C++ (return value and
  1482. * output arguments).
  1483. */
  1484. /* marshal return value and other outputs (if any) from value to C/C++
  1485. * type */
  1486. String* cleanup = NewString("");
  1487. String* outarg = NewString("");
  1488. idx = 0;
  1489. /* this seems really silly. the node's type excludes
  1490. * qualifier/pointer/reference markers, which have to be retrieved
  1491. * from the decl field to construct return_type. but the typemap
  1492. * lookup routine uses the node's type, so we have to swap in and
  1493. * out the correct type. it's not just me, similar silliness also
  1494. * occurs in Language::cDeclaration().
  1495. */
  1496. Setattr(n, "type", return_type);
  1497. tm = Swig_typemap_lookup_new("directorout", n, "c_result", w);
  1498. Setattr(n, "type", type);
  1499. if (tm == 0) {
  1500. String *name = NewString("c_result");
  1501. tm = Swig_typemap_search("directorout", return_type, name, NULL);
  1502. Delete(name);
  1503. }
  1504. if (tm != 0) {
  1505. Replaceall(tm, "$input", "swig_result");
  1506. /* TODO check this */
  1507. if (Getattr(n,"wrap:disown")) {
  1508. Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
  1509. } else {
  1510. Replaceall(tm,"$disown","0");
  1511. }
  1512. Replaceall(tm, "$result", "c_result");
  1513. Printv(w->code, tm, "\n", NIL);
  1514. }
  1515. /* marshal outputs */
  1516. for (p = l; p; ) {
  1517. if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
  1518. Replaceall(tm, "$input", "swig_result");
  1519. Replaceall(tm, "$result", Getattr(p, "name"));
  1520. Printv(w->code, tm, "\n", NIL);
  1521. p = Getattr(p, "tmap:directorargout:next");
  1522. } else {
  1523. p = nextSibling(p);
  1524. }
  1525. }
  1526. /* any existing helper functions to handle this? */
  1527. if (!is_void) {
  1528. /* A little explanation:
  1529. * The director_enum test case makes a method whose return type
  1530. * is an enum type. return_type here is "int". gcc complains
  1531. * about an implicit enum conversion, and although i don't strictly
  1532. * agree with it, I'm working on fixing the error:
  1533. *
  1534. * Below is what I came up with. It's not great but it should
  1535. * always essentially work.
  1536. */
  1537. if( !SwigType_isreference(return_type) ) {
  1538. Printf(w->code, "CAMLreturn((%s)c_result);\n",
  1539. SwigType_lstr(return_type, ""));
  1540. } else {
  1541. Printf(w->code, "CAMLreturn(*c_result);\n");
  1542. }
  1543. }
  1544. Printf(w->code, "}\n");
  1545. /* emit the director method */
  1546. if (status == SWIG_OK) {
  1547. if (!Getattr(n,"defaultargs")) {
  1548. Wrapper_print(w, f_directors);
  1549. Printv(f_directors_h, declaration, NIL);
  1550. }
  1551. }
  1552. /* clean up */
  1553. Delete(wrap_args);
  1554. Delete(arglist);
  1555. Delete(rtype);
  1556. Delete(return_type);
  1557. Delete(pclassname);
  1558. Delete(cleanup);
  1559. Delete(outarg);
  1560. DelWrapper(w);
  1561. return status;
  1562. }
  1563. /* ------------------------------------------------------------
  1564. * classDirectorConstructor()
  1565. * ------------------------------------------------------------ */
  1566. int classDirectorConstructor(Node *n) {
  1567. Node *parent = Getattr(n, "parentNode");
  1568. String *sub = NewString("");
  1569. String *decl = Getattr(n, "decl");
  1570. String *supername = Swig_class_name(parent);
  1571. String *classname = NewString("");
  1572. Printf(classname, "SwigDirector_%s", supername);
  1573. /* insert self parameter */
  1574. Parm *p, *q;
  1575. ParmList *superparms = Getattr(n, "parms");
  1576. ParmList *parms = CopyParmList(superparms);
  1577. String *type = NewString("CAML_VALUE");
  1578. p = NewParm(type, NewString("self"));
  1579. q = Copy(p);
  1580. set_nextSibling(q, superparms);
  1581. set_nextSibling(p, parms);
  1582. parms = p;
  1583. if (!Getattr(n,"defaultargs")) {
  1584. /* constructor */
  1585. {
  1586. Wrapper *w = NewWrapper();
  1587. String *call;
  1588. String *basetype = Getattr(parent, "classtype");
  1589. String *target = Swig_method_decl(decl, classname, parms, 0, 0);
  1590. call = Swig_csuperclass_call(0, basetype, superparms);
  1591. Printf( w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call );
  1592. Delete(target);
  1593. Wrapper_print(w, f_directors);
  1594. Delete(call);
  1595. DelWrapper(w);
  1596. }
  1597. /* constructor header */
  1598. {
  1599. String *target = Swig_method_decl(decl, classname, parms, 0, 1);
  1600. Printf(f_directors_h, " %s;\n", target);
  1601. Delete(target);
  1602. }
  1603. }
  1604. Setattr(n,"parms",q);
  1605. Language::classDirectorConstructor(n);
  1606. Delete(sub);
  1607. Delete(classname);
  1608. Delete(supername);
  1609. //Delete(parms);
  1610. return SWIG_OK;
  1611. }
  1612. /* ------------------------------------------------------------
  1613. * classDirectorDefaultConstructor()
  1614. * ------------------------------------------------------------ */
  1615. int classDirectorDefaultConstructor(Node *n) {
  1616. String *classname;
  1617. classname = Swig_class_name(n);
  1618. /* insert self parameter */
  1619. Parm *p, *q;
  1620. ParmList *superparms = Getattr(n, "parms");
  1621. ParmList *parms = CopyParmList(superparms);
  1622. String *type = NewString("CAML_VALUE");
  1623. p = NewParm(type, NewString("self"));
  1624. q = Copy(p);
  1625. set_nextSibling(p, parms);
  1626. parms = p;
  1627. {
  1628. Wrapper *w = NewWrapper();
  1629. Printf(w->def, "SwigDirector_%s::SwigDirector_%s(CAML_VALUE self) : Swig::Director(self) { }", classname, classname);
  1630. Wrapper_print(w, f_directors);
  1631. DelWrapper(w);
  1632. }
  1633. Printf(f_directors_h, " SwigDirector_%s(CAML_VALUE self);\n", classname);
  1634. Delete(classname);
  1635. Setattr(n,"parms",q);
  1636. return Language::classDirectorDefaultConstructor(n);
  1637. }
  1638. int classDirectorInit( Node *n ) {
  1639. String *declaration = Swig_director_declaration(n);
  1640. Printf( f_directors_h,
  1641. "\n"
  1642. "%s\n"
  1643. "public:\n", declaration );
  1644. Delete( declaration );
  1645. return Language::classDirectorInit( n );
  1646. }
  1647. int classDirectorEnd( Node *n ) {
  1648. Printf( f_directors_h, "};\n\n" );
  1649. return Language::classDirectorEnd( n );
  1650. }
  1651. /* ---------------------------------------------------------------------
  1652. * typedefHandler
  1653. *
  1654. * This is here in order to maintain the correct association between
  1655. * typedef names and enum names.
  1656. *
  1657. * Since I implement enums as polymorphic variant tags, I need to call
  1658. * back into ocaml to evaluate them. This requires a string that can
  1659. * be generated in the typemaps, and also at SWIG time to be the same
  1660. * string. The problem that arises is that SWIG variously generates
  1661. * enum e_name_tag
  1662. * e_name_tag
  1663. * e_typedef_name
  1664. * for
  1665. * typedef enum e_name_tag { ... } e_typedef_name;
  1666. *
  1667. * Since I need these strings to be consistent, I must maintain a correct
  1668. * association list between typedef and enum names.
  1669. * --------------------------------------------------------------------- */
  1670. int typedefHandler( Node *n ) {
  1671. String *type = Getattr(n,"type");
  1672. Node *enum_node = type ?
  1673. Getattr(seen_enums,type) : 0;
  1674. if( enum_node ) {
  1675. String *name = Getattr(enum_node,"name");
  1676. Printf( f_mlbody,
  1677. "let _ = Callback.register \"%s_marker\" (`%s)\n",
  1678. Getattr(n,"name"), name );
  1679. }
  1680. return SWIG_OK;
  1681. }
  1682. String *runtimeCode() {
  1683. String *s = Swig_include_sys("ocaml.swg");
  1684. if (!s) {
  1685. Printf(stderr, "*** Unable to open 'ocaml.swg'\n");
  1686. s = NewString("");
  1687. }
  1688. return s;
  1689. }
  1690. String *defaultExternalRuntimeFilename() {
  1691. return NewString("swigocamlrun.h");
  1692. }
  1693. };
  1694. /* -------------------------------------------------------------------------
  1695. * swig_ocaml() - Instantiate module
  1696. * ------------------------------------------------------------------------- */
  1697. static Language * new_swig_ocaml() {
  1698. return new OCAML();
  1699. }
  1700. extern "C" Language * swig_ocaml(void) {
  1701. return new_swig_ocaml();
  1702. }