diff --git a/Doc/Manual/Ocaml.html b/Doc/Manual/Ocaml.html
index 3ca7ed609..fd434b77b 100644
--- a/Doc/Manual/Ocaml.html
+++ b/Doc/Manual/Ocaml.html
@@ -21,32 +21,33 @@
@@ -438,11 +439,21 @@ val x : Enum_test.c_obj = C_enum `a
- : Enum_test.c_obj = C_enum `c
-
-22.2.3 Arrays
+
+22.2.2.1 Enum typing in Ocaml
+
+The ocaml SWIG module now has support for loading and using multiple SWIG
+modules at the same time. This enhances modularity, but presents problems
+when used with a language which assumes that each module's types are complete
+at compile time. In order to achieve total soundness enum types are now
+isolated per-module. The type issue matters when values are shared between
+functions imported from different modules. You must convert values to master
+values using the swig_val function before sharing them with another module.
+
+22.2.3 Arrays
-22.2.3.1 Simple types of bounded arrays
+22.2.3.1 Simple types of bounded arrays
@@ -463,7 +474,7 @@ arrays of simple types with known bounds in your code, but this only works
for arrays whose bounds are completely specified.
-22.2.3.2 Complex and unbounded arrays
+22.2.3.2 Complex and unbounded arrays
@@ -476,7 +487,7 @@ SWIG can't predict which of these methods will be used in the array,
so you have to specify it for yourself in the form of a typemap.
-22.2.3.3 Using an object
+22.2.3.3 Using an object
@@ -490,7 +501,7 @@ Consider writing an object when the ending condition of your array is complex,
such as using a required centinel, etc.
-22.2.3.4 Example typemap for a function taking float * and int
+22.2.3.4 Example typemap for a function taking float * and int
@@ -541,7 +552,7 @@ void printfloats( float *tab, int len );
-
22.2.4 C++ Classes
+22.2.4 C++ Classes
C++ classes, along with structs and unions are represented by C_obj
@@ -579,7 +590,7 @@ Note that this string belongs to the wrapper object, and not
the underlying pointer, so using create_[x]_from_ptr alters the
returned value for the same object.
-22.2.4.1 STL vector and string Example
+22.2.4.1 STL vector and string Example
Standard typemaps are now provided for STL vector and string. More are in
@@ -657,7 +668,7 @@ baz
#
-22.2.4.2 C++ Class Example
+22.2.4.2 C++ Class Example
Here's a simple example using Trolltech's Qt Library:
@@ -685,7 +696,7 @@ public:
};
-22.2.4.3 Compiling the example
+22.2.4.3 Compiling the example
@@ -703,7 +714,7 @@ bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
-L$QTPATH/lib -cclib -lqt
-22.2.4.4 Sample Session
+22.2.4.4 Sample Session
@@ -730,10 +741,10 @@ Assuming you have a working installation of QT, you will see a window
containing the string "hi" in a button.
-22.2.5 Director Classes
+22.2.5 Director Classes
-22.2.5.1 Director Introduction
+22.2.5.1 Director Introduction
@@ -760,7 +771,7 @@ class foo {
};
-22.2.5.2 Overriding Methods in Ocaml
+22.2.5.2 Overriding Methods in Ocaml
@@ -788,7 +799,7 @@ In this example, I'll examine the objective caml code involved in providing
an overloaded class. This example is contained in Examples/ocaml/shapes.
-22.2.5.3 Director Usage Example
+22.2.5.3 Director Usage Example
@@ -847,7 +858,7 @@ in a more effortless style in ocaml, while leaving the "engine" part of the
program in C++.
-22.2.5.4 Creating director objects
+22.2.5.4 Creating director objects
The definition of the actual object triangle can be described this way:
@@ -885,7 +896,7 @@ object from causing a core dump, as long as the object is destroyed
properly.
-22.2.5.5 Typemaps for directors, directorin, directorout, directorargout
+22.2.5.5 Typemaps for directors, directorin, directorout, directorargout
@@ -896,7 +907,7 @@ well as a function return value in the same way you provide function arguments,
and to receive arguments the same way you normally receive function returns.
-22.2.5.6 directorin typemap
+22.2.5.6 directorin typemap
@@ -907,7 +918,7 @@ code receives when you are called. In general, a simple directorin typ
can use the same body as a simple out typemap.
-22.2.5.7 directorout typemap
+22.2.5.7 directorout typemap
@@ -918,7 +929,7 @@ for the same type, except when there are special requirements for object
ownership, etc.
-22.2.5.8 directorargout typemap
+22.2.5.8 directorargout typemap
@@ -935,7 +946,7 @@ In the event that you don't specify all of the necessary values, integral
values will read zero, and struct or object returns have undefined results.
-22.2.6 Exceptions
+22.2.6 Exceptions
Catching exceptions is now supported using SWIG's %exception feature. A simple
diff --git a/Examples/test-suite/imports_a.h b/Examples/test-suite/imports_a.h
index f6fd77cf0..28eaeac27 100644
--- a/Examples/test-suite/imports_a.h
+++ b/Examples/test-suite/imports_a.h
@@ -3,7 +3,7 @@ enum GlobalEnum { globalenum1=1, globalenum2 };
/* This function should be static as it will be emitted into the code for
* every module. All _static targets would fail here with a multiple
* definition if this is not static. */
-GlobalEnum global_test(GlobalEnum e) { return e; }
+static GlobalEnum global_test(GlobalEnum e) { return e; }
class A {
public:
diff --git a/Lib/ocaml/ocaml.i b/Lib/ocaml/ocaml.i
index 1ba299056..9e939e40e 100644
--- a/Lib/ocaml/ocaml.i
+++ b/Lib/ocaml/ocaml.i
@@ -12,6 +12,17 @@
/* Type registration */
%insert(init) "typeregister.swg"
+%insert(mlitail) %{
+ val swig_val : c_enum_type -> c_obj -> Swig.c_obj
+%}
+
+%insert(mltail) %{
+ let swig_val t v =
+ match v with
+ C_enum e -> enum_to_int t v
+ | _ -> Obj.magic v
+%}
+
/*#ifndef SWIG_NOINCLUDE*/
%insert(runtime) "ocaml.swg"
/*#endif*/
diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx
index 7c048b340..f0c62d802 100755
--- a/Source/Modules/ocaml.cxx
+++ b/Source/Modules/ocaml.cxx
@@ -56,6 +56,8 @@ static File *f_mlout = 0;
static File *f_mliout = 0;
static File *f_mlbody = 0;
static File *f_mlibody = 0;
+static File *f_mltail = 0;
+static File *f_mlitail = 0;
static File *f_enumtypes_type = 0;
static File *f_enumtypes_value = 0;
static File *f_class_ctors = 0;
@@ -225,6 +227,8 @@ public:
init_func_def = NewString("");
f_mlbody = NewString("");
f_mlibody = NewString("");
+ f_mltail = NewString("");
+ f_mlitail = NewString("");
f_class_ctors = NewString("");
f_class_ctors_end = NewString("");
f_enum_to_int = NewString("");
@@ -244,6 +248,8 @@ public:
Swig_register_filebyname("runtime",f_runtime);
Swig_register_filebyname("mli",f_mlibody);
Swig_register_filebyname("ml",f_mlbody);
+ Swig_register_filebyname("mlitail",f_mlitail);
+ Swig_register_filebyname("mltail",f_mltail);
Swig_register_filebyname("director",f_directors);
Swig_register_filebyname("director_h",f_directors_h);
Swig_register_filebyname("classtemplate",f_classtemplate);
@@ -265,7 +271,7 @@ public:
" (let y = _y in match (x : c_enum_type) with\n"
" `unknown -> "
" (match (Obj.magic y) with\n"
- " `Int x -> C_int x\n"
+ " `Int x -> Swig.C_int x\n"
" | _ -> raise (LabelNotFromThisEnum v))\n" );
Printf( f_int_to_enum,
@@ -305,11 +311,11 @@ public:
Language::top(n);
Printf( f_enum_to_int,
- ") | _ -> (C_int (get_int v))\n"
+ ") | _ -> (Swig.C_int (get_int v))\n"
"let _ = Callback.register \"%s_enum_to_int\" enum_to_int\n",
module );
Printf( f_mlibody,
- "val enum_to_int : c_enum_type -> c_obj -> c_obj\n" );
+ "val enum_to_int : c_enum_type -> c_obj -> Swig.c_obj\n" );
Printf( f_int_to_enum,
"let _ = Callback.register \"%s_int_to_enum\" int_to_enum\n",
@@ -351,12 +357,14 @@ public:
Delete(f_enum_to_int);
Dump(f_class_ctors,f_mlout);
Dump(f_class_ctors_end,f_mlout);
+ Dump(f_mltail,f_mlout);
Close(f_mlout);
Delete(f_mlout);
Dump(f_enumtypes_type,f_mliout);
Dump(f_enumtypes_value,f_mliout);
Dump(f_mlibody,f_mliout);
+ Dump(f_mlitail,f_mliout);
Close(f_mliout);
Delete(f_mliout);
@@ -894,21 +902,21 @@ public:
if( Getattr( n, "feature:immutable" ) ) {
Printf( f_mlbody,
- "external _%s : c_obj -> c_obj = \"%s\" \n",
+ "external _%s : Swig.c_obj -> Swig.c_obj = \"%s\" \n",
mname, var_name );
- Printf( f_mlibody, "val _%s : c_obj -> c_obj\n", iname );
+ Printf( f_mlibody, "val _%s : Swig.c_obj -> Swig.c_obj\n", iname );
if( const_enum ) {
Printf( f_enum_to_int,
- " | `%s -> _%s C_void\n",
+ " | `%s -> _%s Swig.C_void\n",
mname, mname );
Printf( f_int_to_enum,
- " if y = (get_int (_%s C_void)) then `%s else\n",
+ " if y = (get_int (_%s Swig.C_void)) then `%s else\n",
mname, mname );
}
} else {
- Printf( f_mlbody, "external _%s : c_obj -> c_obj = \"%s\"\n",
+ Printf( f_mlbody, "external _%s : Swig.c_obj -> Swig.c_obj = \"%s\"\n",
mname, var_name );
- Printf( f_mlibody, "external _%s : c_obj -> c_obj = \"%s\"\n",
+ Printf( f_mlibody, "external _%s : Swig.c_obj -> Swig.c_obj = \"%s\"\n",
mname, var_name );
}
@@ -1182,7 +1190,7 @@ public:
/* Insert sizeof operator for concrete classes */
if( sizeof_feature ) {
- Printv(f_class_ctors, "\"sizeof\" , (fun args -> C_int (__",
+ Printv(f_class_ctors, "\"sizeof\" , (fun args -> Swig.C_int (__",
classname, "_sizeof ())) ;\n", NIL);
}
/* Handle up-casts in a nice way */
@@ -1421,7 +1429,7 @@ public:
if( const_enum ) {
Printf( f_int_to_enum, "`Int y)\n" );
Printf( f_enum_to_int,
- "| `Int x -> C_int x\n"
+ "| `Int x -> Swig.C_int x\n"
"| _ -> raise (LabelNotFromThisEnum v))\n" );
}