1 /* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
7 * Ocaml language module for SWIG.
8 * ----------------------------------------------------------------------------- */
10 char cvsroot_ocaml_cxx[] = "$Id: ocaml.cxx 11246 2009-06-05 17:19:29Z wsfulton $";
16 static const char *usage = (char *)
17 ("Ocaml Options (available with -ocaml)\n"
18 "-prefix <name> - Set a prefix <name> to be prepended to all names\n"
19 "-where - Emit library location\n"
20 "-suffix <name> - Change .cxx to something else\n" "-oldvarnames - old intermediary method names for variable wrappers\n" "\n");
22 static int classmode = 0;
23 static int in_constructor = 0, in_destructor = 0, in_copyconst = 0;
24 static int const_enum = 0;
25 static int static_member_function = 0;
26 static int generate_sizeof = 0;
27 static char *prefix = 0;
28 static char *ocaml_path = (char *) "ocaml";
29 static bool old_variable_names = false;
30 static String *classname = 0;
31 static String *module = 0;
32 static String *init_func_def = 0;
33 static String *f_classtemplate = 0;
34 static String *name_qualifier = 0;
36 static Hash *seen_enums = 0;
37 static Hash *seen_enumvalues = 0;
38 static Hash *seen_constructors = 0;
40 static File *f_header = 0;
41 static File *f_begin = 0;
42 static File *f_runtime = 0;
43 static File *f_wrappers = 0;
44 static File *f_directors = 0;
45 static File *f_directors_h = 0;
46 static File *f_init = 0;
47 static File *f_mlout = 0;
48 static File *f_mliout = 0;
49 static File *f_mlbody = 0;
50 static File *f_mlibody = 0;
51 static File *f_mltail = 0;
52 static File *f_mlitail = 0;
53 static File *f_enumtypes_type = 0;
54 static File *f_enumtypes_value = 0;
55 static File *f_class_ctors = 0;
56 static File *f_class_ctors_end = 0;
57 static File *f_enum_to_int = 0;
58 static File *f_int_to_enum = 0;
60 class OCAML:public Language {
64 director_prot_ctor_code = NewString("");
65 Printv(director_prot_ctor_code,
66 "if ( $comparison ) { /* subclassed */\n",
67 " $director_new \n", "} else {\n", " failwith(\"accessing abstract class or protected constructor\"); \n", "}\n", NIL);
68 director_multiple_inheritance = 1;
69 director_language = 1;
72 String *Swig_class_name(Node *n) {
74 name = Copy(Getattr(n, "sym:name"));
78 void PrintIncludeArg() {
79 Printv(stdout, SWIG_LIB, SWIG_FILE_DELIMITER, ocaml_path, "\n", NIL);
82 /* ------------------------------------------------------------
84 * ------------------------------------------------------------ */
86 virtual void main(int argc, char *argv[]) {
91 SWIG_library_directory(ocaml_path);
93 // Look for certain command line options
94 for (i = 1; i < argc; i++) {
96 if (strcmp(argv[i], "-help") == 0) {
99 } else if (strcmp(argv[i], "-where") == 0) {
102 } else if (strcmp(argv[i], "-prefix") == 0) {
104 prefix = new char[strlen(argv[i + 1]) + 2];
105 strcpy(prefix, argv[i + 1]);
107 Swig_mark_arg(i + 1);
112 } else if (strcmp(argv[i], "-suffix") == 0) {
114 SWIG_config_cppext(argv[i + 1]);
116 Swig_mark_arg(i + 1);
120 } else if (strcmp(argv[i], "-oldvarnames") == 0) {
122 old_variable_names = true;
127 // If a prefix has been specified make sure it ends in a '_'
130 if (prefix[strlen(prefix)] != '_') {
131 prefix[strlen(prefix) + 1] = 0;
132 prefix[strlen(prefix)] = '_';
135 prefix = (char *) "swig_";
137 // Add a symbol for this module
139 Preprocessor_define("SWIGOCAML 1", 0);
140 // Set name of typemaps
142 SWIG_typemap_lang("ocaml");
144 // Read in default typemaps */
145 SWIG_config_file("ocaml.i");
150 /* Swig_director_declaration()
152 * Generate the full director class declaration, complete with base classes.
153 * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
157 String *Swig_director_declaration(Node *n) {
158 String *classname = Swig_class_name(n);
159 String *directorname = NewStringf("SwigDirector_%s", classname);
160 String *base = Getattr(n, "classtype");
161 String *declaration = Swig_class_declaration(n, directorname);
162 Printf(declaration, " : public %s, public Swig::Director {\n", base);
164 Delete(directorname);
168 /* ------------------------------------------------------------
171 * Recognize the %module, and capture the module name.
172 * Create the default enum cases.
173 * Set up the named outputs:
183 * ------------------------------------------------------------ */
185 virtual int top(Node *n) {
186 /* Set comparison with none for ConstructorToFunction */
187 setSubclassInstanceCheck(NewString("caml_list_nth(args,0) != Val_unit"));
189 /* check if directors are enabled for this module. note: this
190 * is a "master" switch, without which no director code will be
191 * emitted. %feature("director") statements are also required
192 * to enable directors for individual classes or methods.
194 * use %module(directors="1") modulename at the start of the
195 * interface file to enable director generation.
198 Node *module = Getattr(n, "module");
200 Node *options = Getattr(module, "options");
202 if (Getattr(options, "directors")) {
205 if (Getattr(options, "dirprot")) {
208 if (Getattr(options, "sizeof")) {
215 /* Initialize all of the output files */
216 String *outfile = Getattr(n, "outfile");
218 f_begin = NewFile(outfile, "w", SWIG_output_files());
220 FileErrorDisplay(outfile);
221 SWIG_exit(EXIT_FAILURE);
223 f_runtime = NewString("");
224 f_init = NewString("");
225 f_header = NewString("");
226 f_wrappers = NewString("");
227 f_directors = NewString("");
228 f_directors_h = NewString("");
229 f_enumtypes_type = NewString("");
230 f_enumtypes_value = NewString("");
231 init_func_def = NewString("");
232 f_mlbody = NewString("");
233 f_mlibody = NewString("");
234 f_mltail = NewString("");
235 f_mlitail = NewString("");
236 f_class_ctors = NewString("");
237 f_class_ctors_end = NewString("");
238 f_enum_to_int = NewString("");
239 f_int_to_enum = NewString("");
240 f_classtemplate = NewString("");
242 module = Getattr(n, "name");
244 seen_constructors = NewHash();
245 seen_enums = NewHash();
246 seen_enumvalues = NewHash();
248 /* Register file targets with the SWIG file handler */
249 Swig_register_filebyname("init", init_func_def);
250 Swig_register_filebyname("header", f_header);
251 Swig_register_filebyname("wrapper", f_wrappers);
252 Swig_register_filebyname("begin", f_begin);
253 Swig_register_filebyname("runtime", f_runtime);
254 Swig_register_filebyname("mli", f_mlibody);
255 Swig_register_filebyname("ml", f_mlbody);
256 Swig_register_filebyname("mlitail", f_mlitail);
257 Swig_register_filebyname("mltail", f_mltail);
258 Swig_register_filebyname("director", f_directors);
259 Swig_register_filebyname("director_h", f_directors_h);
260 Swig_register_filebyname("classtemplate", f_classtemplate);
261 Swig_register_filebyname("class_ctors", f_class_ctors);
263 if (old_variable_names) {
264 Swig_name_register("set", "%v__set__");
265 Swig_name_register("get", "%v__get__");
268 Swig_banner(f_begin);
270 Printf(f_runtime, "\n");
271 Printf(f_runtime, "#define SWIGOCAML\n");
272 Printf(f_runtime, "#define SWIG_MODULE \"%s\"\n", module);
274 Printf(f_mlbody, "let module_name = \"%s\"\n", module);
275 Printf(f_mlibody, "val module_name : string\n");
276 Printf(f_enum_to_int,
277 "let enum_to_int x (v : c_obj) =\n"
280 " (let y = _y in match (x : c_enum_type) with\n"
281 " `unknown -> " " (match y with\n" " `Int x -> (Swig.C_int x)\n" " | _ -> raise (LabelNotFromThisEnum v))\n");
283 Printf(f_int_to_enum, "let int_to_enum x y =\n" " match (x : c_enum_type) with\n" " `unknown -> C_enum (`Int y)\n");
285 if (directorsEnabled()) {
286 Printf(f_runtime, "#define SWIG_DIRECTORS\n");
289 Printf(f_runtime, "\n");
291 /* Produce the enum_to_int and int_to_enum functions */
293 Printf(f_enumtypes_type, "open Swig\n" "type c_enum_type = [ \n `unknown\n");
294 Printf(f_enumtypes_value, "type c_enum_value = [ \n `Int of int\n");
295 String *mlfile = NewString("");
296 String *mlifile = NewString("");
298 Printv(mlfile, module, ".ml", NIL);
299 Printv(mlifile, module, ".mli", NIL);
301 String *mlfilen = NewStringf("%s%s", SWIG_output_directory(), mlfile);
302 if ((f_mlout = NewFile(mlfilen, "w", SWIG_output_files())) == 0) {
303 FileErrorDisplay(mlfilen);
304 SWIG_exit(EXIT_FAILURE);
306 String *mlifilen = NewStringf("%s%s", SWIG_output_directory(), mlifile);
307 if ((f_mliout = NewFile(mlifilen, "w", SWIG_output_files())) == 0) {
308 FileErrorDisplay(mlifilen);
309 SWIG_exit(EXIT_FAILURE);
314 Printf(f_enum_to_int, ") | _ -> (C_int (get_int v))\n" "let _ = Callback.register \"%s_enum_to_int\" enum_to_int\n", module);
315 Printf(f_mlibody, "val enum_to_int : c_enum_type -> c_obj -> Swig.c_obj\n");
317 Printf(f_int_to_enum, "let _ = Callback.register \"%s_int_to_enum\" int_to_enum\n", module);
318 Printf(f_mlibody, "val int_to_enum : c_enum_type -> int -> c_obj\n");
319 Printf(f_init, "#define SWIG_init f_%s_init\n" "%s" "}\n", module, init_func_def);
320 Printf(f_mlbody, "external f_init : unit -> unit = \"f_%s_init\" ;;\n" "let _ = f_init ()\n", module);
321 Printf(f_enumtypes_type, "]\n");
322 Printf(f_enumtypes_value, "]\n\n" "type c_obj = c_enum_value c_obj_t\n");
324 if (directorsEnabled()) {
325 // Insert director runtime into the f_runtime file (make it occur before %header section)
326 Swig_insert_file("director.swg", f_runtime);
329 SwigType_emit_type_table(f_runtime, f_wrappers);
330 /* Close all of the files */
331 Dump(f_runtime, f_begin);
332 Dump(f_directors_h, f_header);
333 Dump(f_header, f_begin);
334 Dump(f_directors, f_wrappers);
335 Dump(f_wrappers, f_begin);
336 Wrapper_pretty_print(f_init, f_begin);
344 Dump(f_enumtypes_type, f_mlout);
345 Dump(f_enumtypes_value, f_mlout);
346 Dump(f_mlbody, f_mlout);
347 Dump(f_enum_to_int, f_mlout);
348 Dump(f_int_to_enum, f_mlout);
349 Delete(f_int_to_enum);
350 Delete(f_enum_to_int);
351 Dump(f_class_ctors, f_mlout);
352 Dump(f_class_ctors_end, f_mlout);
353 Dump(f_mltail, f_mlout);
357 Dump(f_enumtypes_type, f_mliout);
358 Dump(f_enumtypes_value, f_mliout);
359 Dump(f_mlibody, f_mliout);
360 Dump(f_mlitail, f_mliout);
367 /* Produce an error for the given type */
368 void throw_unhandled_ocaml_type_error(SwigType *d, const char *types) {
369 Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s (%s).\n", SwigType_str(d, 0), types);
372 /* Return true iff T is a pointer type */
374 is_a_pointer(SwigType *t) {
375 return SwigType_ispointer(SwigType_typedef_resolve_all(t));
379 * Delete one reference from a given type.
382 void oc_SwigType_del_reference(SwigType *t) {
384 if (strncmp(c, "q(", 2) == 0) {
385 Delete(SwigType_pop(t));
388 if (strncmp(c, "r.", 2)) {
389 printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n");
392 Replace(t, "r.", "", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
395 void oc_SwigType_del_array(SwigType *t) {
397 if (strncmp(c, "q(", 2) == 0) {
398 Delete(SwigType_pop(t));
401 if (strncmp(c, "a(", 2) == 0) {
402 Delete(SwigType_pop(t));
407 * Return true iff T is a reference type
411 is_a_reference(SwigType *t) {
412 return SwigType_isreference(SwigType_typedef_resolve_all(t));
416 is_an_array(SwigType *t) {
417 return SwigType_isarray(SwigType_typedef_resolve_all(t));
420 /* ------------------------------------------------------------
422 * Create a function declaration and register it with the interpreter.
423 * ------------------------------------------------------------ */
425 virtual int functionWrapper(Node *n) {
426 char *iname = GetChar(n, "sym:name");
427 SwigType *d = Getattr(n, "type");
428 String *return_type_normalized = normalizeTemplatedClassName(d);
429 ParmList *l = Getattr(n, "parms");
430 int director_method = 0;
433 Wrapper *f = NewWrapper();
434 String *proc_name = NewString("");
435 String *source = NewString("");
436 String *target = NewString("");
437 String *arg = NewString("");
438 String *cleanup = NewString("");
439 String *outarg = NewString("");
440 String *build = NewString("");
446 int newobj = GetFlag(n, "feature:new");
447 String *nodeType = Getattr(n, "nodeType");
448 int destructor = (!Cmp(nodeType, "destructor"));
449 String *overname = 0;
450 bool isOverloaded = Getattr(n, "sym:overloaded") ? true : false;
452 // Make a wrapper name for this
453 String *wname = Swig_name_wrapper(iname);
455 overname = Getattr(n, "sym:overname");
457 if (!addSymbol(iname, n)) {
463 Append(wname, overname);
465 /* Do this to disambiguate functions emitted from different modules */
466 Append(wname, module);
468 Setattr(n, "wrap:name", wname);
470 // Build the name for Scheme.
471 Printv(proc_name, "_", iname, NIL);
472 String *mangled_name = mangleNameForCaml(proc_name);
474 if (classmode && in_constructor) { // Emit constructor for object
475 String *mangled_name_nounder = NewString((char *) (Char(mangled_name)) + 1);
476 Printf(f_class_ctors_end, "let %s clst = _%s clst\n", mangled_name_nounder, mangled_name_nounder);
477 Printf(f_mlibody, "val %s : c_obj -> c_obj\n", mangled_name_nounder);
478 Delete(mangled_name_nounder);
479 } else if (classmode && in_destructor) {
480 Printf(f_class_ctors, " \"~\", %s ;\n", mangled_name);
481 } else if (classmode && !in_constructor && !in_destructor && !static_member_function) {
482 String *opname = Copy(Getattr(n, "memberfunctionHandler:sym:name"));
484 Replaceall(opname, "operator ", "");
486 if (strstr(Char(mangled_name), "__get__")) {
487 String *set_name = Copy(mangled_name);
488 if (!GetFlag(n, "feature:immutable")) {
489 Replaceall(set_name, "__get__", "__set__");
490 Printf(f_class_ctors, " \"%s\", (fun args -> " "if args = (C_list [ raw_ptr ]) then %s args else %s args) ;\n", opname, mangled_name, set_name);
493 Printf(f_class_ctors, " \"%s\", (fun args -> " "if args = (C_list [ raw_ptr ]) then %s args else C_void) ;\n", opname, mangled_name);
495 } else if (strstr(Char(mangled_name), "__set__")) {
496 ; /* Nothing ... handled by the case above */
498 Printf(f_class_ctors, " \"%s\", %s ;\n", opname, mangled_name);
504 if (classmode && in_constructor) {
505 Setattr(seen_constructors, mangled_name, "true");
507 // writing the function wrapper function
508 Printv(f->def, "SWIGEXT CAML_VALUE ", wname, " (", NIL);
509 Printv(f->def, "CAML_VALUE args", NIL);
510 Printv(f->def, ")\n{", NIL);
512 /* Define the scheme name in C. This define is used by several
514 //Printv(f->def, "#define FUNC_NAME \"", mangled_name, "\"", NIL);
516 // adds local variables
517 Wrapper_add_local(f, "args", "CAMLparam1(args)");
518 Wrapper_add_local(f, "ret", "SWIG_CAMLlocal2(swig_result,rv)");
519 Wrapper_add_local(f, "_v", "int _v = 0");
521 Wrapper_add_local(f, "i", "int i");
522 Wrapper_add_local(f, "argc", "int argc = caml_list_length(args)");
523 Wrapper_add_local(f, "argv", "CAML_VALUE *argv");
526 "argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
527 "for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL);
529 d = SwigType_typedef_qualified(d);
530 emit_parameter_variables(l, f);
532 /* Attach the standard typemaps */
533 emit_attach_parmmaps(l, f);
534 Setattr(n, "wrap:parms", l);
536 numargs = emit_num_arguments(l);
537 numreq = emit_num_required(l);
539 Printf(f->code, "swig_result = Val_unit;\n");
541 // Now write code to extract the parameters (this is super ugly)
543 for (i = 0, p = l; i < numargs; i++) {
544 /* Skip ignored arguments */
545 while (checkAttribute(p, "tmap:in:numinputs", "0")) {
546 p = Getattr(p, "tmap:in:next");
549 SwigType *pt = Getattr(p, "type");
550 String *ln = Getattr(p, "lname");
551 pt = SwigType_typedef_qualified(pt);
553 // Produce names of source and target
557 Printf(source, "caml_list_nth(args,%d)", i);
558 Printf(target, "%s", ln);
559 Printv(arg, Getattr(p, "name"), NIL);
562 Printf(f->code, "if (caml_list_length(args) > %d) {\n", i);
564 // Handle parameter types.
565 if ((tm = Getattr(p, "tmap:in"))) {
566 Replaceall(tm, "$source", source);
567 Replaceall(tm, "$target", target);
568 Replaceall(tm, "$input", source);
569 Setattr(p, "emit:input", source);
570 Printv(f->code, tm, "\n", NIL);
571 p = Getattr(p, "tmap:in:next");
574 // check if typedef and resolve
575 throw_unhandled_ocaml_type_error(pt, "in");
579 Printf(f->code, "}\n");
583 /* Insert constraint checking code */
585 if ((tm = Getattr(p, "tmap:check"))) {
586 Replaceall(tm, "$target", Getattr(p, "lname"));
587 Printv(f->code, tm, "\n", NIL);
588 p = Getattr(p, "tmap:check:next");
594 // Pass output arguments back to the caller.
597 if ((tm = Getattr(p, "tmap:argout"))) {
598 Replaceall(tm, "$source", Getattr(p, "emit:input")); /* Deprecated */
599 Replaceall(tm, "$target", Getattr(p, "lname")); /* Deprecated */
600 Replaceall(tm, "$arg", Getattr(p, "emit:input"));
601 Replaceall(tm, "$input", Getattr(p, "emit:input"));
602 Replaceall(tm, "$ntype", normalizeTemplatedClassName(Getattr(p, "type")));
603 Printv(outarg, tm, "\n", NIL);
604 p = Getattr(p, "tmap:argout:next");
611 // Free up any memory allocated for the arguments.
613 /* Insert cleanup code */
615 if ((tm = Getattr(p, "tmap:freearg"))) {
616 Replaceall(tm, "$target", Getattr(p, "lname"));
617 Printv(cleanup, tm, "\n", NIL);
618 p = Getattr(p, "tmap:freearg:next");
624 /* if the object is a director, and the method call originated from its
625 * underlying python object, resolve the call by going up the c++
626 * inheritance chain. otherwise try to resolve the method in python.
627 * without this check an infinite loop is set up between the director and
628 * shadow class method calls.
631 // NOTE: this code should only be inserted if this class is the
632 // base class of a director class. however, in general we haven't
633 // yet analyzed all classes derived from this one to see if they are
634 // directors. furthermore, this class may be used as the base of
635 // a director class defined in a completely different module at a
636 // later time, so this test must be included whether or not directorbase
637 // is true. we do skip this code if directors have not been enabled
638 // at the command line to preserve source-level compatibility with
639 // non-polymorphic swig. also, if this wrapper is for a smart-pointer
640 // method, there is no need to perform the test since the calling object
641 // (the smart-pointer) and the director object (the "pointee") are
644 director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
645 if (director_method) {
646 Wrapper_add_local(f, "director", "Swig::Director *director = 0");
647 Printf(f->code, "director = dynamic_cast<Swig::Director *>(arg1);\n");
648 Wrapper_add_local(f, "upcall", "bool upcall = false");
649 Append(f->code, "upcall = (director);\n");
652 // Now write code to make the function call
653 Swig_director_emit_dynamic_cast(n, f);
654 String *actioncode = emit_action(n);
656 if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
657 Replaceall(tm, "$source", "swig_result");
658 Replaceall(tm, "$target", "rv");
659 Replaceall(tm, "$result", "rv");
660 Replaceall(tm, "$ntype", return_type_normalized);
661 Printv(f->code, tm, "\n", NIL);
663 throw_unhandled_ocaml_type_error(d, "out");
665 emit_return_variable(n, d, f);
667 // Dump the argument output code
668 Printv(f->code, Char(outarg), NIL);
670 // Dump the argument cleanup code
671 Printv(f->code, Char(cleanup), NIL);
673 // Look for any remaining cleanup
675 if (GetFlag(n, "feature:new")) {
676 if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
677 Replaceall(tm, "$source", "swig_result");
678 Printv(f->code, tm, "\n", NIL);
681 // Free any memory allocated by the function being wrapped..
683 if ((tm = Swig_typemap_lookup("swig_result", n, "result", 0))) {
684 Replaceall(tm, "$source", "result");
685 Printv(f->code, tm, "\n", NIL);
687 // Wrap things up (in a manner of speaking)
689 Printv(f->code, tab4, "swig_result = caml_list_append(swig_result,rv);\n", NIL);
691 Printv(f->code, "free(argv);\n", NIL);
692 Printv(f->code, tab4, "CAMLreturn(swig_result);\n", NIL);
693 Printv(f->code, "}\n", NIL);
695 /* Substitute the function name */
696 Replaceall(f->code, "$symname", iname);
698 Wrapper_print(f, f_wrappers);
701 if (!Getattr(n, "sym:nextSibling")) {
703 Wrapper *df = NewWrapper();
704 String *dispatch = Swig_overload_dispatch(n,
705 "free(argv);\n" "CAMLreturn(%s(args));\n",
708 Wrapper_add_local(df, "_v", "int _v = 0");
709 Wrapper_add_local(df, "argv", "CAML_VALUE *argv");
711 /* Undifferentiate name .. this is the dispatch function */
712 wname = Swig_name_wrapper(iname);
713 /* Do this to disambiguate functions emitted from different
715 Append(wname, module);
718 "SWIGEXT CAML_VALUE ", wname, "(CAML_VALUE args) {\n" " CAMLparam1(args);\n" " int i;\n" " int argc = caml_list_length(args);\n", NIL);
720 "argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
721 "for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL);
722 Printv(df->code, dispatch, "\n", NIL);
723 Printf(df->code, "failwith(\"No matching function for overloaded '%s'\");\n", iname);
724 Printv(df->code, "}\n", NIL);
725 Wrapper_print(df, f_wrappers);
733 "external %s_f : c_obj list -> c_obj list = \"%s\" ;;\n"
734 "let %s arg = match %s_f (fnhelper arg) with\n"
736 "| [x] -> (if %s then Gc.finalise \n"
737 " (fun x -> ignore ((invoke x) \"~\" C_void)) x) ; x\n"
738 "| lst -> C_list lst ;;\n", mangled_name, wname, mangled_name, mangled_name, newobj ? "true" : "false");
740 if (!classmode || in_constructor || in_destructor || static_member_function)
741 Printf(f_mlibody, "val %s : c_obj -> c_obj\n", mangled_name);
754 /* ------------------------------------------------------------
757 * Create a link to a C variable.
758 * This creates a single function _wrap_swig_var_varname().
759 * This function takes a single optional argument. If supplied, it means
760 * we are setting this variable to some value. If omitted, it means we are
761 * simply evaluating this variable. In the set case we return C_void.
763 * symname is the name of the variable with respect to C. This
764 * may need to differ from the original name in the case of enums.
765 * enumvname is the name of the variable with respect to ocaml. This
766 * will vary if the variable has been renamed.
767 * ------------------------------------------------------------ */
769 virtual int variableWrapper(Node *n) {
770 char *name = GetChar(n, "feature:symname");
771 String *iname = Getattr(n, "feature:enumvname");
772 String *mname = mangleNameForCaml(iname);
773 SwigType *t = Getattr(n, "type");
775 String *proc_name = NewString("");
777 String *tm2 = NewString("");;
778 String *argnum = NewString("0");
779 String *arg = NewString("SWIG_Field(args,0)");
783 name = GetChar(n, "name");
787 iname = Getattr(n, "sym:name");
788 mname = mangleNameForCaml(NewString(iname));
791 if (!iname || !addSymbol(iname, n))
796 // evaluation function names
797 String *var_name = Swig_name_wrapper(iname);
799 // Build the name for scheme.
800 Printv(proc_name, iname, NIL);
801 Setattr(n, "wrap:name", proc_name);
803 Printf(f->def, "SWIGEXT CAML_VALUE %s(CAML_VALUE args) {\n", var_name);
804 // Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
806 Wrapper_add_local(f, "swig_result", "CAML_VALUE swig_result");
808 if (!GetFlag(n, "feature:immutable")) {
809 /* Check for a setting of the variable value */
810 Printf(f->code, "if (args != Val_int(0)) {\n");
811 if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
812 Replaceall(tm, "$source", "args");
813 Replaceall(tm, "$target", name);
814 Replaceall(tm, "$input", "args");
815 /* Printv(f->code, tm, "\n",NIL); */
816 emit_action_code(n, f->code, tm);
817 } else if ((tm = Swig_typemap_lookup("in", n, name, 0))) {
818 Replaceall(tm, "$source", "args");
819 Replaceall(tm, "$target", name);
820 Replaceall(tm, "$input", "args");
821 Printv(f->code, tm, "\n", NIL);
823 throw_unhandled_ocaml_type_error(t, "varin/in");
825 Printf(f->code, "}\n");
827 // Now return the value of the variable (regardless
828 // of evaluating or setting)
830 if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
831 Replaceall(tm, "$source", name);
832 Replaceall(tm, "$target", "swig_result");
833 Replaceall(tm, "$result", "swig_result");
834 emit_action_code(n, f->code, tm);
835 } else if ((tm = Swig_typemap_lookup("out", n, name, 0))) {
836 Replaceall(tm, "$source", name);
837 Replaceall(tm, "$target", "swig_result");
838 Replaceall(tm, "$result", "swig_result");
839 Printf(f->code, "%s\n", tm);
841 throw_unhandled_ocaml_type_error(t, "varout/out");
844 Printf(f->code, "\nreturn swig_result;\n");
845 Printf(f->code, "}\n");
847 Wrapper_print(f, f_wrappers);
849 // Now add symbol to the Ocaml interpreter
851 if (GetFlag(n, "feature:immutable")) {
852 Printf(f_mlbody, "external _%s : c_obj -> Swig.c_obj = \"%s\" \n", mname, var_name);
853 Printf(f_mlibody, "val _%s : c_obj -> Swig.c_obj\n", iname);
855 Printf(f_enum_to_int, " | `%s -> _%s C_void\n", mname, mname);
856 Printf(f_int_to_enum, " if y = (get_int (_%s C_void)) then `%s else\n", mname, mname);
859 Printf(f_mlbody, "external _%s : c_obj -> c_obj = \"%s\"\n", mname, var_name);
860 Printf(f_mlibody, "external _%s : c_obj -> c_obj = \"%s\"\n", mname, var_name);
872 /* ------------------------------------------------------------
873 * staticmemberfunctionHandler --
874 * Overridden to set static_member_function
875 * ------------------------------------------------------------ */
877 virtual int staticmemberfunctionHandler(Node *n) {
879 static_member_function = 1;
880 rv = Language::staticmemberfunctionHandler(n);
881 static_member_function = 0;
885 /* ------------------------------------------------------------
888 * The one trick here is that we have to make sure we rename the
889 * constant to something useful that doesn't collide with the
890 * original if any exists.
891 * ------------------------------------------------------------ */
893 virtual int constantWrapper(Node *n) {
894 String *name = Getattr(n, "feature:symname");
895 SwigType *type = Getattr(n, "type");
896 String *value = Getattr(n, "value");
897 String *qvalue = Getattr(n, "qualified:value");
898 String *rvalue = NewString("");
905 name = mangleNameForCaml(Getattr(n, "name"));
906 Insert(name, 0, "_swig_wrap_");
907 Setattr(n, "feature:symname", name);
909 // See if there's a typemap
911 Printv(rvalue, value, NIL);
912 if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) {
915 Printv(rvalue, "\"", temp, "\"", NIL);
918 if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) {
921 Printv(rvalue, "'", temp, "'", NIL);
924 // Create variable and assign it a value
926 Printf(f_header, "static %s = ", SwigType_lstr(type, name));
927 if ((SwigType_type(type) == T_STRING)) {
928 Printf(f_header, "\"%s\";\n", value);
929 } else if (SwigType_type(type) == T_CHAR) {
930 Printf(f_header, "\'%s\';\n", value);
932 Printf(f_header, "%s;\n", value);
935 SetFlag(n, "feature:immutable");
940 int constructorHandler(Node *n) {
944 ret = Language::constructorHandler(n);
950 /* destructorHandler:
951 * Turn on destructor flag to inform decisions in functionWrapper
954 int destructorHandler(Node *n) {
958 ret = Language::destructorHandler(n);
964 /* copyconstructorHandler:
965 * Turn on constructor and copyconstructor flags for functionWrapper
968 int copyconstructorHandler(Node *n) {
973 ret = Language::copyconstructorHandler(n);
981 * A simple, somewhat general purpose function for writing to multiple
982 * streams from a source template. This allows the user to define the
983 * class definition in ways different from the one I have here if they
984 * want to. It will also make the class definition system easier to
985 * fiddle with when I want to change methods, etc.
988 void Multiwrite(String *s) {
989 char *find_marker = strstr(Char(s), "(*Stream:");
990 while (find_marker) {
991 char *next = strstr(find_marker, "*)");
992 find_marker += strlen("(*Stream:");
995 int num_chars = next - find_marker;
996 String *stream_name = NewString(find_marker);
997 Delslice(stream_name, num_chars, Len(stream_name));
998 File *fout = Swig_filebyname(stream_name);
1000 next += strlen("*)");
1001 char *following = strstr(next, "(*Stream:");
1002 find_marker = following;
1004 following = next + strlen(next);
1005 String *chunk = NewString(next);
1006 Delslice(chunk, following - next, Len(chunk));
1007 Printv(fout, chunk, NIL);
1013 bool isSimpleType(String *name) {
1014 char *ch = Char(name);
1016 return !(strchr(ch, '(') || strchr(ch, '<') || strchr(ch, ')') || strchr(ch, '>'));
1019 /* We accept all chars in identifiers because we use strings to index
1021 int validIdentifier(String *name) {
1022 return Len(name) > 0 ? 1 : 0;
1027 * Create a "class" definition for ocaml. I thought quite a bit about
1028 * how I should do this part of it, and arrived here, using a function
1029 * invocation to select a method, and dispatch. This can obviously be
1030 * done better, but I can't see how, given that I want to support
1031 * overloaded methods, out parameters, and operators.
1033 * I needed a system that would do this:
1035 * a Be able to call these methods:
1037 * float foo( int x, int &out );
1039 * b Be typeable, even in the presence of mutually dependent classes.
1041 * c Support some form of operator invocation.
1043 * (c) I chose strings for the method names so that "+=" would be a
1044 * valid method name, and the somewhat natural << (invoke x) "+=" y >>
1047 * (a) (b) Since the c_obj type exists, it's easy to return C_int in one
1048 * case and C_list [ C_float ; C_int ] in the other. This makes tricky
1049 * problems with out parameters disappear; they're simply appended to the
1052 * (b) Since every item that comes from C++ is the same type, there is no
1053 * problem with the following:
1056 * class Bar { Foo *toFoo(); }
1057 * class Foo { Bar *toBar(); }
1059 * Since the Objective caml types of Foo and Bar are the same. Now that
1060 * I correctly incorporate SWIG's typechecking, this isn't a big deal.
1062 * The class is in the form of a function returning a c_obj. The c_obj
1063 * is a C_obj containing a function which invokes a method on the
1064 * underlying object given its type.
1066 * The name emitted here is normalized before being sent to
1067 * Callback.register, because we need this string to look up properly
1068 * when the typemap passes the descriptor string. I've been considering
1069 * some, possibly more forgiving method that would do some transformations
1070 * on the $descriptor in order to find a potential match. This is for
1073 * Important things to note:
1075 * We rely on exception handling (BadMethodName) in order to call an
1076 * ancestor. This can be improved.
1078 * The method used to get :classof could be improved to look at the type
1079 * info that the base pointer contains. It's really an error to have a
1080 * SWIG-generated object that does not contain type info, since the
1081 * existence of the object means that SWIG knows the type.
1083 * :parents could use :classof to tell what class it is and make a better
1084 * decision. This could be nice, (i.e. provide a run-time graph of C++
1085 * classes represented);.
1087 * I can't think of a more elegant way of converting a C_obj fun to a
1088 * pointer than "operator &"...
1090 * Added a 'sizeof' that will allow you to do the expected thing.
1091 * This should help users to fill buffer structs and the like (as is
1092 * typical in windows-styled code). It's only enabled if you give
1093 * %feature(sizeof) and then, only for simple types.
1095 * Overall, carrying the list of methods and base classes has worked well.
1096 * It allows me to give the Ocaml user introspection over their objects.
1099 int classHandler(Node *n) {
1100 String *name = Getattr(n, "name");
1105 String *mangled_sym_name = mangleNameForCaml(name);
1106 String *this_class_def = NewString(f_classtemplate);
1107 String *name_normalized = normalizeTemplatedClassName(name);
1108 String *old_class_ctors = f_class_ctors;
1109 String *base_classes = NewString("");
1110 f_class_ctors = NewString("");
1111 bool sizeof_feature = generate_sizeof && isSimpleType(name);
1114 classname = mangled_sym_name;
1116 int rv = Language::classHandler(n);
1119 if (sizeof_feature) {
1121 "SWIGEXT CAML_VALUE _wrap_%s_sizeof( CAML_VALUE args ) {\n"
1122 " CAMLparam1(args);\n" " CAMLreturn(Val_int(sizeof(%s)));\n" "}\n", mangled_sym_name, name_normalized);
1124 Printf(f_mlbody, "external __%s_sizeof : unit -> int = " "\"_wrap_%s_sizeof\"\n", classname, mangled_sym_name);
1128 /* Insert sizeof operator for concrete classes */
1129 if (sizeof_feature) {
1130 Printv(f_class_ctors, "\"sizeof\" , (fun args -> C_int (__", classname, "_sizeof ())) ;\n", NIL);
1132 /* Handle up-casts in a nice way */
1133 List *baselist = Getattr(n, "bases");
1134 if (baselist && Len(baselist)) {
1136 b = First(baselist);
1138 String *bname = Getattr(b.item, "name");
1140 String *base_create = NewString("");
1141 Printv(base_create, "(create_class \"", bname, "\")", NIL);
1142 Printv(f_class_ctors, " \"::", bname, "\", (fun args -> ", base_create, " args) ;\n", NIL);
1143 Printv(base_classes, base_create, " ;\n", NIL);
1149 Replaceall(this_class_def, "$classname", classname);
1150 Replaceall(this_class_def, "$normalized", name_normalized);
1151 Replaceall(this_class_def, "$realname", name);
1152 Replaceall(this_class_def, "$baselist", base_classes);
1153 Replaceall(this_class_def, "$classbody", f_class_ctors);
1155 Delete(f_class_ctors);
1156 f_class_ctors = old_class_ctors;
1158 // Actually write out the class definition
1160 Multiwrite(this_class_def);
1162 Setattr(n, "ocaml:ctor", classname);
1167 String *normalizeTemplatedClassName(String *name) {
1168 String *name_normalized = SwigType_typedef_resolve_all(name);
1172 took_action = false;
1174 if (is_a_pointer(name_normalized)) {
1175 SwigType_del_pointer(name_normalized);
1179 if (is_a_reference(name_normalized)) {
1180 oc_SwigType_del_reference(name_normalized);
1184 if (is_an_array(name_normalized)) {
1185 oc_SwigType_del_array(name_normalized);
1188 } while (took_action);
1190 return SwigType_str(name_normalized, 0);
1194 * Produce the symbol name that ocaml will use when referring to the
1195 * target item. I wonder if there's a better way to do this:
1197 * I shudder to think about doing it with a hash lookup, but that would
1198 * make a couple of things easier:
1201 String *mangleNameForCaml(String *s) {
1202 String *out = Copy(s);
1203 Replaceall(out, " ", "_xx");
1204 Replaceall(out, "::", "_xx");
1205 Replaceall(out, ",", "_x");
1206 Replaceall(out, "+", "_xx_plus");
1207 Replaceall(out, "-", "_xx_minus");
1208 Replaceall(out, "<", "_xx_ldbrace");
1209 Replaceall(out, ">", "_xx_rdbrace");
1210 Replaceall(out, "!", "_xx_not");
1211 Replaceall(out, "%", "_xx_mod");
1212 Replaceall(out, "^", "_xx_xor");
1213 Replaceall(out, "*", "_xx_star");
1214 Replaceall(out, "&", "_xx_amp");
1215 Replaceall(out, "|", "_xx_or");
1216 Replaceall(out, "(", "_xx_lparen");
1217 Replaceall(out, ")", "_xx_rparen");
1218 Replaceall(out, "[", "_xx_lbrace");
1219 Replaceall(out, "]", "_xx_rbrace");
1220 Replaceall(out, "~", "_xx_bnot");
1221 Replaceall(out, "=", "_xx_equals");
1222 Replaceall(out, "/", "_xx_slash");
1223 Replaceall(out, ".", "_xx_dot");
1227 String *fully_qualify_enum_name(Node *n, String *name) {
1229 String *qualification = NewString("");
1230 String *fully_qualified_name = NewString("");
1231 String *parent_type = 0;
1232 String *normalized_name;
1234 parent = parentNode(n);
1236 parent_type = nodeType(parent);
1237 if (Getattr(parent, "name")) {
1238 String *parent_copy = NewStringf("%s::", Getattr(parent, "name"));
1239 if (!Cmp(parent_type, "class") || !Cmp(parent_type, "namespace"))
1240 Insert(qualification, 0, parent_copy);
1241 Delete(parent_copy);
1243 if (!Cmp(parent_type, "class"))
1245 parent = parentNode(parent);
1248 Printf(fully_qualified_name, "%s%s", qualification, name);
1250 normalized_name = normalizeTemplatedClassName(fully_qualified_name);
1251 if (!strncmp(Char(normalized_name), "enum ", 5)) {
1252 Insert(normalized_name, 5, qualification);
1255 return normalized_name;
1258 /* Benedikt Grundmann inspired --> Enum wrap styles */
1260 int enumvalueDeclaration(Node *n) {
1261 String *name = Getattr(n, "name");
1264 if (name_qualifier) {
1265 qvalue = Copy(name_qualifier);
1266 Printv(qvalue, name, NIL);
1269 if (const_enum && name && !Getattr(seen_enumvalues, name)) {
1270 Setattr(seen_enumvalues, name, "true");
1271 SetFlag(n, "feature:immutable");
1272 Setattr(n, "feature:enumvalue", "1"); // this does not appear to be used
1275 Setattr(n, "qualified:value", qvalue);
1277 String *evname = SwigType_manglestr(qvalue);
1278 Insert(evname, 0, "SWIG_ENUM_");
1280 Setattr(n, "feature:enumvname", name);
1281 Setattr(n, "feature:symname", evname);
1283 Printf(f_enumtypes_value, "| `%s\n", name);
1285 return Language::enumvalueDeclaration(n);
1290 /* -------------------------------------------------------------------
1291 * This function is a bit uglier than it deserves.
1293 * I used to direct lookup the name of the enum. Now that certain fixes
1294 * have been made in other places, the names of enums are now fully
1295 * qualified, which is a good thing, overall, but requires me to do
1298 * The other thing that uglifies this function is the varying way that
1299 * typedef enum and enum are handled. I need to produce consistent names,
1300 * which means looking up and registering by typedef and enum name. */
1301 int enumDeclaration(Node *n) {
1302 String *name = Getattr(n, "name");
1304 String *oname = NewString(name);
1305 /* name is now fully qualified */
1306 String *fully_qualified_name = NewString(name);
1307 bool seen_enum = false;
1309 Delete(name_qualifier);
1310 char *strip_position;
1311 name_qualifier = fully_qualify_enum_name(n, NewString(""));
1313 strip_position = strstr(Char(oname), "::");
1315 while (strip_position) {
1316 strip_position += 2;
1317 oname = NewString(strip_position);
1318 strip_position = strstr(Char(oname), "::");
1321 seen_enum = (Getattr(seen_enums, fully_qualified_name) ? true : false);
1325 Printf(f_enum_to_int, "| `%s -> (match y with\n", oname);
1326 Printf(f_int_to_enum, "| `%s -> C_enum (\n", oname);
1327 /* * * * A note about enum name resolution * * * *
1328 * This code should now work, but I think we can do a bit better.
1329 * The problem I'm having is that swig isn't very precise about
1330 * typedef name resolution. My opinion is that SwigType_typedef
1331 * resolve_all should *always* return the enum tag if one exists,
1332 * rather than the admittedly friendlier enclosing typedef.
1334 * This would make one of the cases below unnecessary.
1336 Printf(f_mlbody, "let _ = Callback.register \"%s_marker\" (`%s)\n", fully_qualified_name, oname);
1337 if (!strncmp(Char(fully_qualified_name), "enum ", 5)) {
1338 String *fq_noenum = NewString(Char(fully_qualified_name) + 5);
1340 "let _ = Callback.register \"%s_marker\" (`%s)\n" "let _ = Callback.register \"%s_marker\" (`%s)\n", fq_noenum, oname, fq_noenum, name);
1343 Printf(f_enumtypes_type, "| `%s\n", oname);
1344 Insert(fully_qualified_name, 0, "enum ");
1345 Setattr(seen_enums, fully_qualified_name, n);
1349 int ret = Language::enumDeclaration(n);
1352 Printf(f_int_to_enum, "`Int y)\n");
1353 Printf(f_enum_to_int, "| `Int x -> Swig.C_int x\n" "| _ -> raise (LabelNotFromThisEnum v))\n");
1361 /* ----------------------------------------------------------------------------
1362 * BEGIN C++ Director Class modifications
1363 * ------------------------------------------------------------------------- */
1366 * Modified polymorphism code for Ocaml language module.
1368 * C++/Python polymorphism demo code, copyright (C) 2002 Mark Rose
1369 * <mrose@stm.lbl.gov>
1373 * Move some boilerplate code generation to Swig_...() functions.
1377 /* ---------------------------------------------------------------
1378 * classDirectorMethod()
1380 * Emit a virtual director method to pass a method call on to the
1381 * underlying Python object.
1383 * --------------------------------------------------------------- */
1385 int classDirectorMethod(Node *n, Node *parent, String *super) {
1394 String *c_classname = Getattr(parent, "name");
1395 String *declaration;
1399 String *wrap_args = NewString("");
1400 String *return_type;
1401 int status = SWIG_OK;
1403 bool pure_virtual = false;
1404 bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
1406 storage = Getattr(n, "storage");
1407 value = Getattr(n, "value");
1408 classname = Getattr(parent, "sym:name");
1409 type = Getattr(n, "type");
1410 name = Getattr(n, "name");
1412 if (Cmp(storage, "virtual") == 0) {
1413 if (Cmp(value, "0") == 0) {
1414 pure_virtual = true;
1419 declaration = NewString("");
1420 Wrapper_add_local(w, "swig_result", "CAMLparam0();\n" "SWIG_CAMLlocal2(swig_result,args)");
1422 /* determine if the method returns a pointer */
1423 decl = Getattr(n, "decl");
1424 is_pointer = SwigType_ispointer_return(decl);
1425 is_void = (!Cmp(type, "void") && !is_pointer);
1427 /* form complete return type */
1428 return_type = Copy(type);
1430 SwigType *t = Copy(decl);
1432 f = SwigType_pop_function(t);
1433 SwigType_push(return_type, t);
1438 /* virtual method definition */
1439 l = Getattr(n, "parms");
1441 String *pclassname = NewStringf("SwigDirector_%s", classname);
1442 String *qualified_name = NewStringf("%s::%s", pclassname, name);
1443 SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : type;
1444 target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
1445 Printf(w->def, "%s {", target);
1446 Delete(qualified_name);
1448 /* header declaration */
1449 target = Swig_method_decl(rtype, decl, name, l, 0, 1);
1450 Printf(declaration, " virtual %s;", target);
1453 /* declare method return value
1454 * if the return value is a reference or const reference, a specialized typemap must
1455 * handle it, including declaration of c_result ($result).
1458 if (!(ignored_method && !pure_virtual)) {
1459 Wrapper_add_localv(w, "c_result", SwigType_lstr(return_type, "c_result"), NIL);
1463 if (ignored_method) {
1464 if (!pure_virtual) {
1466 Printf(w->code, "return ");
1467 String *super_call = Swig_method_call(super, l);
1468 Printf(w->code, "%s;\n", super_call);
1471 Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
1472 SwigType_namestr(name));
1475 /* attach typemaps to arguments (C/C++ -> Ocaml) */
1476 String *arglist = NewString("");
1478 Swig_typemap_attach_parms("in", l, 0);
1479 Swig_typemap_attach_parms("directorin", l, 0);
1480 Swig_typemap_attach_parms("directorargout", l, w);
1483 int num_arguments = emit_num_arguments(l);
1491 /* build argument list and type conversion string */
1492 for (i = 0, idx = 0, p = l; i < num_arguments; i++) {
1494 while (Getattr(p, "tmap:ignore")) {
1495 p = Getattr(p, "tmap:ignore:next");
1498 if (Getattr(p, "tmap:directorargout") != 0)
1501 String *pname = Getattr(p, "name");
1502 String *ptype = Getattr(p, "type");
1505 if ((tm = Getattr(p, "tmap:directorin")) != 0) {
1506 Replaceall(tm, "$input", pname);
1507 Replaceall(tm, "$owner", "0");
1510 Printv(wrap_args, tm, "\n", NIL);
1511 p = Getattr(p, "tmap:directorin:next");
1513 } else if (Cmp(ptype, "void")) {
1514 /* special handling for pointers to other C++ director classes.
1515 * ideally this would be left to a typemap, but there is currently no
1516 * way to selectively apply the dynamic_cast<> to classes that have
1517 * directors. in other words, the type "SwigDirector_$1_lname" only exists
1518 * for classes with directors. we avoid the problem here by checking
1519 * module.wrap::directormap, but it's not clear how to get a typemap to
1520 * do something similar. perhaps a new default typemap (in addition
1521 * to SWIGTYPE) called DIRECTORTYPE?
1523 if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
1524 Node *module = Getattr(parent, "module");
1525 Node *target = Swig_directormap(module, ptype);
1526 sprintf(source, "obj%d", idx++);
1527 String *nonconst = 0;
1528 /* strip pointer/reference --- should move to Swig/stype.c */
1529 String *nptype = NewString(Char(ptype) + 2);
1530 /* name as pointer */
1531 String *ppname = Copy(pname);
1532 if (SwigType_isreference(ptype)) {
1533 Insert(ppname, 0, "&");
1535 /* if necessary, cast away const since Python doesn't support it! */
1536 if (SwigType_isconst(nptype)) {
1537 nonconst = NewStringf("nc_tmp_%s", pname);
1538 String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(ptype, 0), ppname);
1539 Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
1541 Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
1542 "Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(ptype, pname),
1543 SwigType_namestr(c_classname), SwigType_namestr(name));
1545 nonconst = Copy(ppname);
1549 String *mangle = SwigType_manglestr(ptype);
1551 String *director = NewStringf("director_%s", mangle);
1552 Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
1553 Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
1554 Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst);
1555 Printf(wrap_args, "if (!%s) {\n", director);
1556 Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
1557 Printf(wrap_args, "} else {\n");
1558 Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
1559 Printf(wrap_args, "}\n");
1561 Printv(arglist, source, NIL);
1563 Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
1564 Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
1565 //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
1566 // source, nonconst, base);
1567 Printv(arglist, source, NIL);
1572 Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
1573 "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
1574 SwigType_namestr(c_classname), SwigType_namestr(name));
1575 status = SWIG_NOWRAP;
1582 Printv(w->code, "swig_result = Val_unit;\n", 0);
1583 Printf(w->code, "args = Val_unit;\n");
1585 /* wrap complex arguments to values */
1586 Printv(w->code, wrap_args, NIL);
1588 /* pass the method call on to the Python object */
1590 "swig_result = caml_swig_alloc(1,C_list);\n" "SWIG_Store_field(swig_result,0,args);\n" "args = swig_result;\n" "swig_result = Val_unit;\n", 0);
1591 Printf(w->code, "swig_result = " "callback3(*caml_named_value(\"swig_runmethod\")," "swig_get_self(),copy_string(\"%s\"),args);\n", Getattr(n, "name"));
1592 /* exception handling */
1593 tm = Swig_typemap_lookup("director:except", n, "result", 0);
1595 tm = Getattr(n, "feature:director:except");
1597 if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
1598 Printf(w->code, "if (result == NULL) {\n");
1599 Printf(w->code, " CAML_VALUE error = *caml_named_value(\"director_except\");\n");
1600 Replaceall(tm, "$error", "error");
1601 Printv(w->code, Str(tm), "\n", NIL);
1602 Printf(w->code, "}\n");
1606 * Python method may return a simple object, or a tuple.
1607 * for in/out aruments, we have to extract the appropriate values from the
1608 * argument list, then marshal everything back to C/C++ (return value and
1609 * output arguments).
1612 /* marshal return value and other outputs (if any) from value to C/C++
1615 String *cleanup = NewString("");
1616 String *outarg = NewString("");
1620 /* this seems really silly. the node's type excludes
1621 * qualifier/pointer/reference markers, which have to be retrieved
1622 * from the decl field to construct return_type. but the typemap
1623 * lookup routine uses the node's type, so we have to swap in and
1624 * out the correct type. it's not just me, similar silliness also
1625 * occurs in Language::cDeclaration().
1627 Setattr(n, "type", return_type);
1628 tm = Swig_typemap_lookup("directorout", n, "c_result", w);
1629 Setattr(n, "type", type);
1631 Replaceall(tm, "$input", "swig_result");
1632 /* TODO check this */
1633 if (Getattr(n, "wrap:disown")) {
1634 Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
1636 Replaceall(tm, "$disown", "0");
1638 Replaceall(tm, "$result", "c_result");
1639 Printv(w->code, tm, "\n", NIL);
1642 /* marshal outputs */
1644 if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
1645 Replaceall(tm, "$input", "swig_result");
1646 Replaceall(tm, "$result", Getattr(p, "name"));
1647 Printv(w->code, tm, "\n", NIL);
1648 p = Getattr(p, "tmap:directorargout:next");
1659 /* any existing helper functions to handle this? */
1661 if (!(ignored_method && !pure_virtual)) {
1662 /* A little explanation:
1663 * The director_enum test case makes a method whose return type
1664 * is an enum type. return_type here is "int". gcc complains
1665 * about an implicit enum conversion, and although i don't strictly
1666 * agree with it, I'm working on fixing the error:
1668 * Below is what I came up with. It's not great but it should
1669 * always essentially work.
1671 if (!SwigType_isreference(return_type)) {
1672 Printf(w->code, "CAMLreturn_type((%s)c_result);\n", SwigType_lstr(return_type, ""));
1674 Printf(w->code, "CAMLreturn_type(*c_result);\n");
1679 Printf(w->code, "}\n");
1681 // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
1682 String *inline_extra_method = NewString("");
1683 if (dirprot_mode() && !is_public(n) && !pure_virtual) {
1684 Printv(inline_extra_method, declaration, NIL);
1685 String *extra_method_name = NewStringf("%sSwigPublic", name);
1686 Replaceall(inline_extra_method, name, extra_method_name);
1687 Replaceall(inline_extra_method, ";\n", " {\n ");
1689 Printf(inline_extra_method, "return ");
1690 String *methodcall = Swig_method_call(super, l);
1691 Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
1693 Delete(extra_method_name);
1696 /* emit the director method */
1697 if (status == SWIG_OK) {
1698 if (!Getattr(n, "defaultargs")) {
1699 Wrapper_print(w, f_directors);
1700 Printv(f_directors_h, declaration, NIL);
1701 Printv(f_directors_h, inline_extra_method, NIL);
1707 Delete(return_type);
1713 /* ------------------------------------------------------------
1714 * classDirectorConstructor()
1715 * ------------------------------------------------------------ */
1717 int classDirectorConstructor(Node *n) {
1718 Node *parent = Getattr(n, "parentNode");
1719 String *sub = NewString("");
1720 String *decl = Getattr(n, "decl");
1721 String *supername = Swig_class_name(parent);
1722 String *classname = NewString("");
1723 Printf(classname, "SwigDirector_%s", supername);
1725 /* insert self parameter */
1727 ParmList *superparms = Getattr(n, "parms");
1728 ParmList *parms = CopyParmList(superparms);
1729 String *type = NewString("CAML_VALUE");
1730 p = NewParm(type, NewString("self"));
1732 set_nextSibling(q, superparms);
1733 set_nextSibling(p, parms);
1736 if (!Getattr(n, "defaultargs")) {
1739 Wrapper *w = NewWrapper();
1741 String *basetype = Getattr(parent, "classtype");
1742 String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
1743 call = Swig_csuperclass_call(0, basetype, superparms);
1744 Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call);
1746 Wrapper_print(w, f_directors);
1751 /* constructor header */
1753 String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
1754 Printf(f_directors_h, " %s;\n", target);
1759 Setattr(n, "parms", q);
1760 Language::classDirectorConstructor(n);
1770 /* ------------------------------------------------------------
1771 * classDirectorDefaultConstructor()
1772 * ------------------------------------------------------------ */
1774 int classDirectorDefaultConstructor(Node *n) {
1776 classname = Swig_class_name(n);
1778 /* insert self parameter */
1780 ParmList *superparms = Getattr(n, "parms");
1781 ParmList *parms = CopyParmList(superparms);
1782 String *type = NewString("CAML_VALUE");
1783 p = NewParm(type, NewString("self"));
1785 set_nextSibling(p, parms);
1789 Wrapper *w = NewWrapper();
1790 Printf(w->def, "SwigDirector_%s::SwigDirector_%s(CAML_VALUE self) : Swig::Director(self) { }", classname, classname);
1791 Wrapper_print(w, f_directors);
1794 Printf(f_directors_h, " SwigDirector_%s(CAML_VALUE self);\n", classname);
1796 Setattr(n, "parms", q);
1797 return Language::classDirectorDefaultConstructor(n);
1800 int classDirectorInit(Node *n) {
1801 String *declaration = Swig_director_declaration(n);
1802 Printf(f_directors_h, "\n" "%s\n" "public:\n", declaration);
1803 Delete(declaration);
1804 return Language::classDirectorInit(n);
1807 int classDirectorEnd(Node *n) {
1808 Printf(f_directors_h, "};\n\n");
1809 return Language::classDirectorEnd(n);
1812 /* ---------------------------------------------------------------------
1815 * This is here in order to maintain the correct association between
1816 * typedef names and enum names.
1818 * Since I implement enums as polymorphic variant tags, I need to call
1819 * back into ocaml to evaluate them. This requires a string that can
1820 * be generated in the typemaps, and also at SWIG time to be the same
1821 * string. The problem that arises is that SWIG variously generates
1826 * typedef enum e_name_tag { ... } e_typedef_name;
1828 * Since I need these strings to be consistent, I must maintain a correct
1829 * association list between typedef and enum names.
1830 * --------------------------------------------------------------------- */
1831 int typedefHandler(Node *n) {
1832 String *type = Getattr(n, "type");
1833 Node *enum_node = type ? Getattr(seen_enums, type) : 0;
1835 String *name = Getattr(enum_node, "name");
1837 Printf(f_mlbody, "let _ = Callback.register \"%s_marker\" (`%s)\n", Getattr(n, "name"), name);
1843 String *runtimeCode() {
1844 String *s = Swig_include_sys("ocaml.swg");
1846 Printf(stderr, "*** Unable to open 'ocaml.swg'\n");
1852 String *defaultExternalRuntimeFilename() {
1853 return NewString("swigocamlrun.h");
1857 /* -------------------------------------------------------------------------
1858 * swig_ocaml() - Instantiate module
1859 * ------------------------------------------------------------------------- */
1861 static Language *new_swig_ocaml() {
1864 extern "C" Language *swig_ocaml(void) {
1865 return new_swig_ocaml();