%feature("docstring")
@@ -5114,14 +5116,15 @@ introspection, then life is good once more.
which when attached to a node in the parse tree will cause a docstring
to be generated that includes the name of the function, parameter
names, default values if any, and return type if any. There are also
-three options for autodoc controlled by the value given to the
-feature, described below.
+four levels for autodoc controlled by the value given to the
+feature, %feature("autodoc", "level").
+The four values for level are covered in the following sub-sections.
33.10.2.1 %feature("autodoc", "0")
-When the "0" option is given then the types of the parameters will
+When level "0" is used then the types of the parameters will
not be included in the autodoc string. For example, given
this function prototype:
@@ -5150,14 +5153,15 @@ def function_name(*args, **kwargs):
-When the "1" option is used then the parameter types will be
+When level "1" is used then the parameter types will be
used in the autodoc string. In addition, an attempt is made to
simplify the type name such that it makes more sense to the Python
-user. Pointer, reference and const info is removed,
-%rename's are evaluated, etc. (This is not always
-successful, but works most of the time. See the next section for what
-to do when it doesn't.) Given the example above, then turning on the
-parameter types with the "1" option will result in Python code like
+user. Pointer, reference and const info is removed if the associated type
+is has an associated Python type (%rename's are thus shown correctly).
+This works most of the time, otherwise a C/C++ type will be used.
+See the next section for the "docstring" feature for tweaking the docstrings to your liking.
+Given the example above, then turning on the
+parameter types with level "1" will result in Python code like
this:
@@ -5170,8 +5174,92 @@ def function_name(*args, **kwargs):
+33.10.2.3 %feature("autodoc", "2")
-33.10.2.3 %feature("autodoc", "docstring")
+
+
+Level "2" results in the function prototype as per level "0". In addition, a line of
+documentation is generated for each parameter. Using the previous example, the generated
+code will be:
+
+
+
+
+def function_name(*args, **kwargs):
+ """
+ function_name(x, y, foo=None, bar=None) -> bool
+
+ Parameters:
+ x: int
+ y: int
+ foo: Foo *
+ bar: Bar *
+
+ """
+ ...
+
+
+
+
+Note that the documentation for each parameter is sourced from the "doc" typemap which by default shows the
+C/C++ type rather than the simplified Python type name described earlier for level "1".
+Typemaps can of course change the output for any particular type, for example the int x parameter:
+
+
+
+
+%feature("autodoc", "2");
+%typemap("doc") int x "$1_name (C++ type: $1_type) -- Input $1_name dimension"
+bool function_name(int x, int y, Foo* foo=NULL, Bar* bar=NULL);
+
+
+
+
+resulting in
+
+
+
+
+def function_name(*args, **kwargs):
+ """
+ function_name(x, y, foo=None, bar=None) -> bool
+
+ Parameters:
+ x (C++ type: int) -- Input x dimension
+ y: int
+ foo: Foo *
+ bar: Bar *
+
+ """
+
+
+
+33.10.2.4 %feature("autodoc", "3")
+
+
+
+Level "3" results in the function prototype as per level "1" but also contains the same additional line of documentation for each parameter as per level "2". Using our earlier example again, the generated code will be:
+
+
+
+
+def function_name(*args, **kwargs):
+ """
+ function_name(int x, int y, Foo foo=None, Bar bar=None) -> bool
+
+ Parameters:
+ x: int
+ y: int
+ foo: Foo *
+ bar: Bar *
+
+ """
+ ...
+
+
+
+
+33.10.2.5 %feature("autodoc", "docstring")
@@ -5285,7 +5373,7 @@ SWIG is able to generate proxy method definitions like this:
- def foo(self, bar : "int" = 0) -> "void" : ...
+ def foo(self, bar : "int"=0) -> "void" : ...
@@ -5294,7 +5382,7 @@ still could be generated:
- def foo(self, bar = 0): ...
+ def foo(self, bar=0): ...
diff --git a/Examples/test-suite/autodoc.i b/Examples/test-suite/autodoc.i
index c363e4384..23aa3f0b7 100644
--- a/Examples/test-suite/autodoc.i
+++ b/Examples/test-suite/autodoc.i
@@ -1,9 +1,9 @@
-%module(docstring="hello") python_autodoc
+%module(docstring="hello") autodoc
%feature("autodoc");
-// especial typemap and its docs
-%typemap(in) (int c, int d) "$1 =0; $2 = 0;";
+// special typemap and its docs
+%typemap(in) (int c, int d) "$1 = 0; $2 = 0;";
%typemap(doc,name="hello",type="Tuple") (int c, int d) "hello: int tuple[2]";
// testing for different documentation levels
@@ -12,7 +12,22 @@
%feature("autodoc","2") A::func2; // extended
%feature("autodoc","3") A::func3; // extended + types
-%feature("autodoc","just a string") A::func; // names
+%feature("autodoc","0") A::func0default; // names
+%feature("autodoc","1") A::func1default; // names + types
+%feature("autodoc","2") A::func2default; // extended
+%feature("autodoc","3") A::func3default; // extended + types
+
+%feature("autodoc","0") A::func0static; // names
+%feature("autodoc","1") A::func1static; // names + types
+%feature("autodoc","2") A::func2static; // extended
+%feature("autodoc","3") A::func3static; // extended + types
+
+%feature("autodoc","0") A::variable_a; // names
+%feature("autodoc","1") A::variable_b; // names + types
+%feature("autodoc","2") A::variable_c; // extended
+%feature("autodoc","3") A::variable_d; // extended + types
+
+%feature("autodoc","just a string") A::funk; // names
%inline {
@@ -20,36 +35,29 @@
hi, hello
};
- struct A
- {
- A(int a, short b, Hola h)
- {
- }
+ struct A {
+ A(int a, short b, Hola h) {}
+ int funk(int a) { return a; }
- int func(int a)
- {
- return a;
- }
+ int func0(short, int c, int d) { return c; }
+ int func1(short, int c, int d) { return c; }
+ int func2(short, int c, int d) { return c; }
+ int func3(short, int c, int d) { return c; }
- int func0(int c, int d)
- {
- return c;
- }
-
- int func1(int c, int d)
- {
- return c;
- }
+ int func0default(A *e, short, int c, int d, double f = 2) { return 0; }
+ int func1default(A *e, short, int c, int d, double f = 2) { return 0; }
+ int func2default(A *e, short, int c, int d, double f = 2) { return 0; }
+ int func3default(A *e, short, int c, int d, double f = 2) { return 0; }
- int func2(A* c, double d = 2)
- {
- return 2;
- }
+ static int func0static(A *e, short, int c, int d, double f = 2) { return 0; }
+ static int func1static(A *e, short, int c, int d, double f = 2) { return 0; }
+ static int func2static(A *e, short, int c, int d, double f = 2) { return 0; }
+ static int func3static(A *e, short, int c, int d, double f = 2) { return 0; }
- int func3(A* c, double d = 2)
- {
- return 2;
- }
+ int variable_a;
+ int variable_b;
+ int variable_c;
+ int variable_d;
};
}
@@ -62,34 +70,66 @@
%typemap(doc) int a "a: special comment for parameter a";
%typemap(doc) int b "b: another special comment for parameter b";
-%callback(1) func_cb;
+%feature("autodoc","0") C::C(int a, int b, Hola h); // names
+%feature("autodoc","1") D::D(int a, int b, Hola h); // names + types
+%feature("autodoc","2") E::E(int a, int b, Hola h); // extended
+%feature("autodoc","3") F::F(int a, int b, Hola h); // extended + types
%inline {
- struct B
- {
- B(int a, int b, Hola h)
- {
- }
-
-
- int func(int c, int d)
- {
- return c;
- }
-
+ struct B {
+ B(int a, int b, Hola h) {}
+ int funk(int c, int d) { return c; }
};
- int func(int c, int d) {
- return c;
- }
+ struct C {
+ C(int a, int b, Hola h) {}
+ };
+ struct D {
+ D(int a, int b, Hola h) {}
+ };
+ struct E {
+ E(int a, int b, Hola h) {}
+ };
+ struct F {
+ F(int a, int b, Hola h) {}
+ };
- int funcio(int *INOUT) {
+ int funk(A *e, short, int c, int d) { return c; }
+ int funkdefaults(A *e, short, int c, int d, double f = 2) { return c; }
+}
+
+%include
+%inline %{
+ int func_input(int *INPUT) {
return 1;
}
-
- int func_cb(int c, int d) {
- return c;
+ int func_output(int *OUTPUT) {
+ *OUTPUT = 2;
+ return 1;
}
-
+ int func_inout(int *INOUT) {
+ *INOUT += 1;
+ return 1;
+ }
+%}
+
+%callback(1) func_cb;
+
+%inline {
+ int func_cb(int c, int d) { return c; }
}
+
+// Bug 3310528
+%feature("autodoc","1") banana; // names + types
+%inline %{
+typedef struct tagS {
+ int a;
+ char b;
+} S;
+
+typedef int Integer;
+
+void banana(S *a, const struct tagS *b, int c, Integer d) {}
+%}
+
diff --git a/Examples/test-suite/python/autodoc_runme.py b/Examples/test-suite/python/autodoc_runme.py
new file mode 100644
index 000000000..c65ebba24
--- /dev/null
+++ b/Examples/test-suite/python/autodoc_runme.py
@@ -0,0 +1,176 @@
+from autodoc import *
+
+def check(got, expected):
+ if expected != got:
+ raise RuntimeError("\n" + "Expected: [" + expected + "]\n" + "Got : [" + got + "]")
+
+check(A.__doc__, "Proxy of C++ A class")
+check(A.funk.__doc__, "just a string")
+check(A.func0.__doc__, "func0(self, arg2, hello) -> int")
+check(A.func1.__doc__, "func1(A self, short arg2, Tuple hello) -> int")
+check(A.func2.__doc__, "\n"
+" func2(self, arg2, hello) -> int\n"
+"\n"
+" Parameters:\n"
+" arg2: short\n"
+" hello: int tuple[2]\n"
+"\n"
+" "
+)
+check(A.func3.__doc__, "\n"
+" func3(A self, short arg2, Tuple hello) -> int\n"
+"\n"
+" Parameters:\n"
+" arg2: short\n"
+" hello: int tuple[2]\n"
+"\n"
+" "
+)
+
+check(A.func0default.__doc__, "\n"
+" func0default(self, e, arg3, hello, f=2) -> int\n"
+" func0default(self, e, arg3, hello) -> int\n"
+" "
+)
+check(A.func1default.__doc__, "\n"
+" func1default(A self, A e, short arg3, Tuple hello, double f=2) -> int\n"
+" func1default(A self, A e, short arg3, Tuple hello) -> int\n"
+" "
+)
+check(A.func2default.__doc__, "\n"
+" func2default(self, e, arg3, hello, f=2) -> int\n"
+"\n"
+" Parameters:\n"
+" e: A *\n"
+" arg3: short\n"
+" hello: int tuple[2]\n"
+" f: double\n"
+"\n"
+" func2default(self, e, arg3, hello) -> int\n"
+"\n"
+" Parameters:\n"
+" e: A *\n"
+" arg3: short\n"
+" hello: int tuple[2]\n"
+"\n"
+" "
+)
+check(A.func3default.__doc__, "\n"
+" func3default(A self, A e, short arg3, Tuple hello, double f=2) -> int\n"
+"\n"
+" Parameters:\n"
+" e: A *\n"
+" arg3: short\n"
+" hello: int tuple[2]\n"
+" f: double\n"
+"\n"
+" func3default(A self, A e, short arg3, Tuple hello) -> int\n"
+"\n"
+" Parameters:\n"
+" e: A *\n"
+" arg3: short\n"
+" hello: int tuple[2]\n"
+"\n"
+" "
+)
+
+check(A.func0static.__doc__, "\n"
+" func0static(e, arg2, hello, f=2) -> int\n"
+" func0static(e, arg2, hello) -> int\n"
+" "
+)
+check(A.func1static.__doc__, "\n"
+" func1static(A e, short arg2, Tuple hello, double f=2) -> int\n"
+" func1static(A e, short arg2, Tuple hello) -> int\n"
+" "
+)
+check(A.func2static.__doc__, "\n"
+" func2static(e, arg2, hello, f=2) -> int\n"
+"\n"
+" Parameters:\n"
+" e: A *\n"
+" arg2: short\n"
+" hello: int tuple[2]\n"
+" f: double\n"
+"\n"
+" func2static(e, arg2, hello) -> int\n"
+"\n"
+" Parameters:\n"
+" e: A *\n"
+" arg2: short\n"
+" hello: int tuple[2]\n"
+"\n"
+" "
+)
+check(A.func3static.__doc__, "\n"
+" func3static(A e, short arg2, Tuple hello, double f=2) -> int\n"
+"\n"
+" Parameters:\n"
+" e: A *\n"
+" arg2: short\n"
+" hello: int tuple[2]\n"
+" f: double\n"
+"\n"
+" func3static(A e, short arg2, Tuple hello) -> int\n"
+"\n"
+" Parameters:\n"
+" e: A *\n"
+" arg2: short\n"
+" hello: int tuple[2]\n"
+"\n"
+" "
+)
+
+check(A.variable_a.__doc__, "A_variable_a_get(self) -> int")
+check(A.variable_b.__doc__, "A_variable_b_get(A self) -> int")
+check(A.variable_c.__doc__, "\n"
+"A_variable_c_get(self) -> int\n"
+"\n"
+"Parameters:\n"
+" self: A *\n"
+"\n"
+)
+check(A.variable_d.__doc__, "\n"
+"A_variable_d_get(A self) -> int\n"
+"\n"
+"Parameters:\n"
+" self: A *\n"
+"\n"
+)
+
+check(B.__doc__, "Proxy of C++ B class")
+check(C.__init__.__doc__, "__init__(self, a, b, h) -> C")
+check(D.__init__.__doc__, "__init__(D self, int a, int b, Hola h) -> D")
+check(E.__init__.__doc__, "\n"
+" __init__(self, a, b, h) -> E\n"
+"\n"
+" Parameters:\n"
+" a: special comment for parameter a\n"
+" b: another special comment for parameter b\n"
+" h: enum Hola\n"
+"\n"
+" "
+)
+check(F.__init__.__doc__, "\n"
+" __init__(F self, int a, int b, Hola h) -> F\n"
+"\n"
+" Parameters:\n"
+" a: special comment for parameter a\n"
+" b: another special comment for parameter b\n"
+" h: enum Hola\n"
+"\n"
+" "
+)
+
+check(B.funk.__doc__, "funk(B self, int c, int d) -> int")
+check(funk.__doc__, "funk(A e, short arg2, int c, int d) -> int")
+check(funkdefaults.__doc__, "\n"
+" funkdefaults(A e, short arg2, int c, int d, double f=2) -> int\n"
+" funkdefaults(A e, short arg2, int c, int d) -> int\n"
+" "
+)
+
+check(func_input.__doc__, "func_input(int * INPUT) -> int")
+check(func_output.__doc__, "func_output() -> int")
+check(func_inout.__doc__, "func_inout(int * INOUT) -> int")
+check(banana.__doc__, "banana(S a, S b, int c, Integer d)")
diff --git a/Lib/python/pydocs.swg b/Lib/python/pydocs.swg
index 862339da7..f4ab9db23 100644
--- a/Lib/python/pydocs.swg
+++ b/Lib/python/pydocs.swg
@@ -1,18 +1,22 @@
-// basic doc for primitive types....
+// Documentation for use with the autodoc feature.
#ifdef SWIG_DOC_DOXYGEN_STYLE
-%typemap(doc) SWIGTYPE "@param $1_name $1_type value";
-%typemap(doc) SWIGTYPE * "@param $1_name $1_type value";
-%typemap(doc) const SWIGTYPE & "@param $1_name $1_type value";
-%typemap(doc) enum SWIGTYPE "@param $1_name enum $1_type value";
-#else
-%typemap(doc) SWIGTYPE "$1_name: $1_type value";
-%typemap(doc) SWIGTYPE * "$1_name: $1_type value";
-%typemap(doc) const SWIGTYPE & "$1_name: $1_type value";
-%typemap(doc) enum SWIGTYPE "$1_name: enum $1_type value";
+%typemap(doc) SWIGTYPE "@param $1_name $1_type";
+%typemap(doc) SWIGTYPE * "@param $1_name $1_type";
+%typemap(doc) const SWIGTYPE & "@param $1_name $1_type";
+%typemap(doc) enum SWIGTYPE "@param $1_name enum $1_type";
-%typemap(doc) SWIGTYPE *INOUT "$1_name: $1_type input/ouput value";
-%typemap(doc) SWIGTYPE *INPUT "$1_name: $1_type input value";
-%typemap(doc) SWIGTYPE *OUTPUT "$1_name: $1_type output value";
+%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "@param $1_name $1_type (input/output)";
+%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "@param $1_name $1_type (input)";
+%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "@param $1_name $1_type (output)";
+#else
+%typemap(doc) SWIGTYPE "$1_name: $1_type";
+%typemap(doc) SWIGTYPE * "$1_name: $1_type";
+%typemap(doc) const SWIGTYPE & "$1_name: $1_type";
+%typemap(doc) enum SWIGTYPE "$1_name: enum $1_type";
+
+%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "$1_name: $1_type (input/output)";
+%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "$1_name: $1_type (input)";
+%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "$1_name: $1_type (output)";
#endif
diff --git a/Lib/python/pythonkw.swg b/Lib/python/pythonkw.swg
index 2dd4f2f49..8ad0ef11b 100644
--- a/Lib/python/pythonkw.swg
+++ b/Lib/python/pythonkw.swg
@@ -3,7 +3,7 @@
*/
#define PYTHONKW(x) %keywordwarn("'" `x` "' is a python keyword, renaming to '_" `x` "'", rename="_%s") `x`
-#define PYTHONBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in python") "::"`x`
+#define PYTHONBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in python") `x`
/*
@@ -105,7 +105,6 @@ PYTHONBN(setattr);
PYTHONBN(slice);
PYTHONBN(sorted);
PYTHONBN(staticmethod);
-PYTHONBN(staticmethod);
PYTHONBN(str);
PYTHONBN(sum);
PYTHONBN(super);
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index 00f6ebfff..737ecc555 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -1122,9 +1122,9 @@ public:
initial++;
c++;
}
- if (*c && !isspace(*c))
+ if (*c && !isspace(*c)) {
break;
- else {
+ } else {
initial = 0;
}
}
@@ -1267,35 +1267,29 @@ public:
}
/* -----------------------------------------------------------------------------
- * makeParameterName()
- * Note: the generated name should consist with that in kwnames[]
+ * addMissingParameterNames()
+ * For functions that have not had nameless parameters set in the Language class.
*
* Inputs:
- * n - Node
- * p - parameter node
- * arg_num - parameter argument number
- * Return:
- * arg - a unique parameter name
+ * plist - entire parameter list
+ * arg_offset - argument number for first parameter
+ * Side effects:
+ * The "lname" attribute in each parameter in plist will be contain a parameter name
* ----------------------------------------------------------------------------- */
- String *makeParameterName(ParmList *plist, Parm *p, int arg_num) {
- String *arg = 0;
- String *pn = Swig_name_make(p, 0, Getattr(p, "name"), 0, 0);
- // Use C parameter name unless it is a duplicate or an empty parameter name
- int count = 0;
- if (SwigType_isvarargs(Getattr(p, "type"))) {
- return NewString("*args");
+ void addMissingParameterNames(ParmList *plist, int arg_offset) {
+ Parm *p = plist;
+ int i = arg_offset;
+ while (p) {
+ if (!Getattr(p, "lname")) {
+ String *pname = Swig_cparm_name(p, i);
+ Delete(pname);
+ }
+ i++;
+ p = nextSibling(p);
}
- while (plist) {
- if ((Cmp(pn, Getattr(plist, "name")) == 0))
- count++;
- plist = nextSibling(plist);
- }
- arg = (!pn || !Len(pn) || (count > 1)) ? NewStringf("arg%d", arg_num) : Copy(pn);
- return arg;
}
-
/* ------------------------------------------------------------
* make_autodocParmList()
* Generate the documentation for the function parameters
@@ -1305,25 +1299,21 @@ public:
String *make_autodocParmList(Node *n, bool showTypes, bool calling = false, bool func_annotation = false) {
-
String *doc = NewString("");
- String *pdocs = Copy(Getattr(n, "feature:pdocs"));
+ String *pdocs = 0;
ParmList *plist = CopyParmList(Getattr(n, "parms"));
Parm *p;
Parm *pnext;
- Node *lookup;
int lines = 0;
- int arg_num = 0;
- const int maxwidth = 50;
+ int start_arg_num = is_wrapping_class() ? 1 : 0;
+ const int maxwidth = 80;
if (calling)
func_annotation = false;
- if (pdocs)
- Append(pdocs, "\n");
-
+ addMissingParameterNames(plist, start_arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
Swig_typemap_attach_parms("in", plist, 0);
Swig_typemap_attach_parms("doc", plist, 0);
@@ -1354,18 +1344,15 @@ public:
value = Getattr(p, "tmap:doc:value");
}
+ // Note: the generated name should be consistent with that in kwnames[]
name = name ? name : Getattr(p, "name");
+ name = name ? name : Getattr(p, "lname");
+
type = type ? type : Getattr(p, "type");
value = value ? value : Getattr(p, "value");
- name = makeParameterName(plist, p, arg_num);
- // Reset it for convinient in further use. (mainly for makeParameterName())
- // Since the plist is created by CopyParmList,
- // we can hope that the set would have no side effect
- Setattr(p, "name", name);
-
- arg_num++;
-
+ if (SwigType_isvarargs(type))
+ break;
if (Len(doc)) {
// add a comma to the previous one if any
@@ -1378,39 +1365,35 @@ public:
}
}
- type = SwigType_base(type);
- lookup = Swig_symbol_clookup(type, 0);
- if (lookup)
- type = Getattr(lookup, "sym:name");
-
// Do the param type too?
+ Node *nn = classLookup(Getattr(p, "type"));
+ String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
if (showTypes)
- Printf(doc, "%s ", type);
-
+ Printf(doc, "%s ", type_str);
Append(doc, name);
if (pdoc) {
if (!pdocs)
- pdocs = NewString("Parameters:\n");
- Printf(pdocs, " %s\n", pdoc);
+ pdocs = NewString("\nParameters:\n");
+ Printf(pdocs, " %s\n", pdoc);
}
- // Write the function annoation
+ // Write the function annotation
if (func_annotation)
- Printf(doc, " : '%s'", type);
+ Printf(doc, " : '%s'", type_str);
// Write default value
if (value && !calling) {
String *pv = pyvalue(value, Getattr(p, "type"));
- if (pv)
+ if (pv) {
value = pv;
- else {
- lookup = Swig_symbol_clookup(value, 0);
- if (lookup) {
+ } else {
+ Node *lookup = Swig_symbol_clookup(value, 0);
+ if (lookup)
value = Getattr(lookup, "sym:name");
- }
}
- Printf(doc, " = %s", value);
+ Printf(doc, "=%s", value);
}
+ Delete(type_str);
}
if (pdocs)
Setattr(n, "feature:pdocs", pdocs);
@@ -1430,7 +1413,7 @@ public:
String *make_autodoc(Node *n, autodoc_t ad_type) {
int extended = 0;
- // If the function is overloaded then this funciton is called
+ // If the function is overloaded then this function is called
// for the last one. Rewind to the first so the docstrings are
// in order.
while (Getattr(n, "sym:previousSibling"))
@@ -1468,15 +1451,14 @@ public:
if (!skipAuto) {
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
+ String *type_str = NULL;
if (type) {
- if (Strcmp(type, "void") == 0)
- type = NULL;
- else {
- type = SwigType_base(type);
- Node *lookup = Swig_symbol_clookup(type, 0);
- if (lookup)
- type = Getattr(lookup, "sym:name");
+ if (Strcmp(type, "void") == 0) {
+ type_str = NULL;
+ } else {
+ Node *nn = classLookup(type);
+ type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
}
}
@@ -1497,40 +1479,50 @@ public:
case AUTODOC_CTOR:
if (Strcmp(class_name, symname) == 0) {
String *paramList = make_autodocParmList(n, showTypes);
+ Printf(doc, "__init__(");
+ if (showTypes)
+ Printf(doc, "%s ", getClassName());
if (Len(paramList))
- Printf(doc, "__init__(self, %s) -> %s", paramList, class_name);
+ Printf(doc, "self, %s) -> %s", paramList, class_name);
else
- Printf(doc, "__init__(self) -> %s", class_name);
+ Printf(doc, "self) -> %s", class_name);
} else
Printf(doc, "%s(%s) -> %s", symname, make_autodocParmList(n, showTypes), class_name);
break;
case AUTODOC_DTOR:
- Append(doc, "__del__(self)");
+ if (showTypes)
+ Printf(doc, "__del__(%s self)", getClassName());
+ else
+ Printf(doc, "__del__(self)");
break;
case AUTODOC_STATICFUNC:
Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes));
- if (type)
- Printf(doc, " -> %s", type);
+ if (type_str)
+ Printf(doc, " -> %s", type_str);
break;
case AUTODOC_FUNC:
Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes));
- if (type)
- Printf(doc, " -> %s", type);
+ if (type_str)
+ Printf(doc, " -> %s", type_str);
break;
case AUTODOC_METHOD:
String *paramList = make_autodocParmList(n, showTypes);
+ Printf(doc, "%s(", symname);
+ if (showTypes)
+ Printf(doc, "%s ", class_name);
if (Len(paramList))
- Printf(doc, "%s(self, %s)", symname, paramList);
+ Printf(doc, "self, %s)", paramList);
else
- Printf(doc, "%s(self)", symname);
- if (type)
- Printf(doc, " -> %s", type);
+ Printf(doc, "self)");
+ if (type_str)
+ Printf(doc, " -> %s", type_str);
break;
}
+ Delete(type_str);
}
if (extended) {
String *pdocs = Getattr(n, "feature:pdocs");
@@ -1935,7 +1927,7 @@ public:
/* Create a shadow for this function (if enabled and not in a member function) */
if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) {
- emitFunctionShadowHelper(n, f_shadow_stubs, symname, 0);
+ emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, symname, 0);
}
DelWrapper(f);
Delete(dispatch);
@@ -3914,7 +3906,7 @@ public:
// Can't use checkAttribute(n, "access", "public") because
// "access" attr isn't set on %extend methods
if (!checkAttribute(n, "access", "private") && strncmp(Char(symname), "operator ", 9) && !Getattr(class_members, symname)) {
- String *fullname = Swig_name_member(NULL, class_name, symname);
+ String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname);
String *wname = Swig_name_wrapper(fullname);
Setattr(class_members, symname, n);
int argcount = Getattr(n, "python:argcount") ? atoi(Char(Getattr(n, "python:argcount"))) : 2;
@@ -3940,12 +3932,13 @@ public:
if (!Getattr(n, "sym:nextSibling")) {
if (shadow && !builtin) {
int fproxy = fastproxy;
+ String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname);
if (Strcmp(symname, "__repr__") == 0) {
have_repr = 1;
}
if (Getattr(n, "feature:shadow")) {
String *pycode = pythoncode(Getattr(n, "feature:shadow"), tab4);
- String *pyaction = NewStringf("%s.%s", module, Swig_name_member(NSPACE_TODO, class_name, symname));
+ String *pyaction = NewStringf("%s.%s", module, fullname);
Replaceall(pycode, "$action", pyaction);
Delete(pyaction);
Printv(f_shadow, pycode, "\n", NIL);
@@ -3958,7 +3951,7 @@ public:
if (!have_addtofunc(n)) {
if (!fastproxy || olddefs) {
Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":", NIL);
- Printv(f_shadow, " return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL);
+ Printv(f_shadow, " return ", funcCall(fullname, callParms), "\n", NIL);
}
} else {
Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":", NIL);
@@ -3971,11 +3964,11 @@ public:
}
if (have_pythonappend(n)) {
fproxy = 0;
- Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL);
+ Printv(f_shadow, tab8, "val = ", funcCall(fullname, callParms), "\n", NIL);
Printv(f_shadow, pythoncode(pythonappend(n), tab8), "\n", NIL);
Printv(f_shadow, tab8, "return val\n\n", NIL);
} else {
- Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n\n", NIL);
+ Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n\n", NIL);
}
}
}
@@ -3988,6 +3981,7 @@ public:
}
Append(shadow_list, symname);
}
+ Delete(fullname);
}
}
return SWIG_OK;
@@ -4012,7 +4006,7 @@ public:
if (builtin && in_class) {
if ((GetFlagAttr(n, "feature:extend") || checkAttribute(n, "access", "public"))
&& !Getattr(class_members, symname)) {
- String *fullname = Swig_name_member(NULL, class_name, symname);
+ String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname);
String *wname = Swig_name_wrapper(fullname);
Setattr(class_members, symname, n);
int funpack = modernargs && fastunpack && !Getattr(n, "sym:overloaded");
From a4f8ed4fc9a5f1e8ccacf39919b7ac48a89f407c Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 10 Jun 2011 20:26:07 +0000
Subject: [PATCH 002/147] Fix last checkin for renamed parameters
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12736 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Source/Modules/python.cxx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index 737ecc555..aab40ca94 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -1347,6 +1347,7 @@ public:
// Note: the generated name should be consistent with that in kwnames[]
name = name ? name : Getattr(p, "name");
name = name ? name : Getattr(p, "lname");
+ name = Swig_name_make(p, 0, name, 0, 0); // rename parameter if a keyword
type = type ? type : Getattr(p, "type");
value = value ? value : Getattr(p, "value");
@@ -1394,6 +1395,7 @@ public:
Printf(doc, "=%s", value);
}
Delete(type_str);
+ Delete(name);
}
if (pdocs)
Setattr(n, "feature:pdocs", pdocs);
@@ -2198,7 +2200,7 @@ public:
String *tmp = 0;
String *name = pn;
if (!Getattr(p, "hidden")) {
- name = tmp = Swig_name_make(p, 0, pn, 0, 0);
+ name = tmp = Swig_name_make(p, 0, pn, 0, 0); // rename parameter if a keyword
}
Printf(kwargs, "(char *) \"%s\",", name);
if (tmp)
From 665b70e887e4058ce822670275aa3a0cb085b8e2 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 10 Jun 2011 22:48:32 +0000
Subject: [PATCH 003/147] Change test to fail rather than print a message
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12737 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Examples/test-suite/python/typename_runme.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Examples/test-suite/python/typename_runme.py b/Examples/test-suite/python/typename_runme.py
index 59a0f1f76..10c7bff1b 100644
--- a/Examples/test-suite/python/typename_runme.py
+++ b/Examples/test-suite/python/typename_runme.py
@@ -5,8 +5,8 @@ b = typename.Bar()
x = typename.twoFoo(f)
if not isinstance(x,types.FloatType):
- print "Wrong return type!"
+ raise RuntimeError,"Wrong return type (FloatType) !"
y = typename.twoBar(b)
if not isinstance(y,types.IntType):
- print "Wrong return type!"
+ raise RuntimeError,"Wrong return type (IntType)!"
From 3cb76bb45ec9cc6e5be0aae7dc5b7d61ca6a1220 Mon Sep 17 00:00:00 2001
From: Stefan Zager
Date: Sat, 11 Jun 2011 05:49:49 +0000
Subject: [PATCH 004/147] Slight tweak to output typemap for int
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12738 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Lib/python/pyprimtypes.swg | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/Lib/python/pyprimtypes.swg b/Lib/python/pyprimtypes.swg
index a11e87409..aa5ddaf62 100644
--- a/Lib/python/pyprimtypes.swg
+++ b/Lib/python/pyprimtypes.swg
@@ -25,6 +25,16 @@ SWIG_AsVal_dec(bool)(PyObject *obj, bool *val)
}
}
+/* int */
+
+%fragment(SWIG_From_frag(int),"header") {
+SWIGINTERNINLINE PyObject*
+ SWIG_From_dec(int)(int value)
+{
+ return PyInt_FromLong((long) value);
+}
+}
+
/* long */
%fragment(SWIG_From_frag(long),"header") {
From 58e74e8675499dba4791429b379ca1aef207467a Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 13 Jun 2011 17:38:08 +0000
Subject: [PATCH 005/147] Rename python_kwargs testcase to kwargs_feature. Add
kwargs_feature to Ruby and fix Ruby warnings when using kwargs feature. Add
%kwargs macro for Ruby
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12739 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
.../test-suite/{python_kwargs.i => kwargs_feature.i} | 2 +-
Examples/test-suite/python/Makefile.in | 2 +-
...{python_kwargs_runme.py => kwargs_feature_runme.py} | 2 +-
Examples/test-suite/ruby/Makefile.in | 1 +
Lib/ruby/rubyuserdir.swg | 10 ++++++++++
Source/Modules/ruby.cxx | 2 +-
6 files changed, 15 insertions(+), 4 deletions(-)
rename Examples/test-suite/{python_kwargs.i => kwargs_feature.i} (98%)
rename Examples/test-suite/python/{python_kwargs_runme.py => kwargs_feature_runme.py} (96%)
diff --git a/Examples/test-suite/python_kwargs.i b/Examples/test-suite/kwargs_feature.i
similarity index 98%
rename from Examples/test-suite/python_kwargs.i
rename to Examples/test-suite/kwargs_feature.i
index 28089bbf1..87153109a 100644
--- a/Examples/test-suite/python_kwargs.i
+++ b/Examples/test-suite/kwargs_feature.i
@@ -1,4 +1,4 @@
-%module python_kwargs
+%module kwargs_feature
%nocopyctor;
%kwargs;
diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in
index 7eb700124..185ca2298 100644
--- a/Examples/test-suite/python/Makefile.in
+++ b/Examples/test-suite/python/Makefile.in
@@ -41,6 +41,7 @@ CPP_TEST_CASES += \
inout \
inplaceadd \
input \
+ kwargs_feature \
li_cstring \
li_cwstring \
li_factory \
@@ -58,7 +59,6 @@ CPP_TEST_CASES += \
primitive_types \
python_abstractbase \
python_append \
- python_kwargs \
python_nondynamic \
python_overload_simple_cast \
python_richcompare \
diff --git a/Examples/test-suite/python/python_kwargs_runme.py b/Examples/test-suite/python/kwargs_feature_runme.py
similarity index 96%
rename from Examples/test-suite/python/python_kwargs_runme.py
rename to Examples/test-suite/python/kwargs_feature_runme.py
index fb6e191dd..5539e211d 100644
--- a/Examples/test-suite/python/python_kwargs_runme.py
+++ b/Examples/test-suite/python/kwargs_feature_runme.py
@@ -1,4 +1,4 @@
-from python_kwargs import *
+from kwargs_feature import *
class MyFoo(Foo):
def __init__(self, a , b = 0):
diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in
index 27996616e..e157e72ca 100644
--- a/Examples/test-suite/ruby/Makefile.in
+++ b/Examples/test-suite/ruby/Makefile.in
@@ -10,6 +10,7 @@ top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
CPP_TEST_CASES = \
+ kwargs_feature \
li_cdata \
li_cstring \
li_factory \
diff --git a/Lib/ruby/rubyuserdir.swg b/Lib/ruby/rubyuserdir.swg
index 2f67c9ec6..638433c2d 100644
--- a/Lib/ruby/rubyuserdir.swg
+++ b/Lib/ruby/rubyuserdir.swg
@@ -8,3 +8,13 @@
#define %nooutput %feature("outputs","0")
#define %initstack %feature("initstack", "1")
#define %ignorestack %feature("initstack", "0")
+
+/* ------------------------------------------------------------------------- */
+/*
+ Enable keywords paramaters
+*/
+
+#define %kwargs %feature("kwargs")
+#define %nokwargs %feature("kwargs", "0")
+#define %clearkwargs %feature("kwargs", "")
+
diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx
index dfb199b6e..d2ce97592 100644
--- a/Source/Modules/ruby.cxx
+++ b/Source/Modules/ruby.cxx
@@ -1477,7 +1477,7 @@ public:
/* Finish argument marshalling */
Printf(kwargs, " NULL }");
if (allow_kwargs) {
- Printv(f->locals, tab4, "char *kwnames[] = ", kwargs, ";\n", NIL);
+ Printv(f->locals, tab4, "const char *kwnames[] = ", kwargs, ";\n", NIL);
}
/* Trailing varargs */
From 72ffdb930dcbbe0ae2a1cf7164a7ca4b632b1fee Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 13 Jun 2011 20:46:20 +0000
Subject: [PATCH 006/147] Repeat autodoc fixes for Octave and Ruby as done
previously for Python
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12740 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 3 +
Source/Modules/octave.cxx | 113 +++++++++++-----
Source/Modules/python.cxx | 12 +-
Source/Modules/ruby.cxx | 263 +++++++++++++++++++++++---------------
4 files changed, 252 insertions(+), 139 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index 269c71bf7..b47de9b69 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -5,6 +5,9 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.5 (in progress)
===========================
+2011-06-13: wsfulton
+ [Ruby, Octave] SF #3310528 Autodoc fixes similar to those described below for Python.
+
2011-06-10: wsfulton
[Python] Few subtle bugfixes in autodoc documentation generation,
- Unnamed argument names fix for autodoc levels > 0.
diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx
index 11fbc46fd..c22d90195 100644
--- a/Source/Modules/octave.cxx
+++ b/Source/Modules/octave.cxx
@@ -383,20 +383,54 @@ public:
return conv ? "SWIG_POINTER_IMPLICIT_CONV" : "0";
}
+ /* -----------------------------------------------------------------------------
+ * addMissingParameterNames()
+ * For functions that have not had nameless parameters set in the Language class.
+ *
+ * Inputs:
+ * plist - entire parameter list
+ * arg_offset - argument number for first parameter
+ * Side effects:
+ * The "lname" attribute in each parameter in plist will be contain a parameter name
+ * ----------------------------------------------------------------------------- */
+
+ void addMissingParameterNames(ParmList *plist, int arg_offset) {
+ Parm *p = plist;
+ int i = arg_offset;
+ while (p) {
+ if (!Getattr(p, "lname")) {
+ String *pname = Swig_cparm_name(p, i);
+ Delete(pname);
+ }
+ i++;
+ p = nextSibling(p);
+ }
+ }
+
void make_autodocParmList(Node *n, String *decl_str, String *args_str) {
- String *pdocs = Copy(Getattr(n, "feature:pdocs"));
+ String *pdocs = 0;
ParmList *plist = CopyParmList(Getattr(n, "parms"));
Parm *p;
Parm *pnext;
- Node *lookup;
+ int start_arg_num = is_wrapping_class() ? 1 : 0;
- if (pdocs)
- Append(pdocs, "\n");
+ addMissingParameterNames(plist, start_arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
Swig_typemap_attach_parms("in", plist, 0);
Swig_typemap_attach_parms("doc", plist, 0);
for (p = plist; p; p = pnext) {
+
+ String *tm = Getattr(p, "tmap:in");
+ if (tm) {
+ pnext = Getattr(p, "tmap:in:next");
+ if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ continue;
+ }
+ } else {
+ pnext = nextSibling(p);
+ }
+
String *name = 0;
String *type = 0;
String *value = 0;
@@ -407,60 +441,81 @@ public:
value = Getattr(p, "tmap:doc:value");
}
+ // Note: the generated name should be consistent with that in kwnames[]
name = name ? name : Getattr(p, "name");
+ name = name ? name : Getattr(p, "lname");
+ name = Swig_name_make(p, 0, name, 0, 0); // rename parameter if a keyword
+
type = type ? type : Getattr(p, "type");
value = value ? value : Getattr(p, "value");
+ if (SwigType_isvarargs(type))
+ break;
+
String *tex_name = NewString("");
if (name)
Printf(tex_name, "@var{%s}", name);
else
Printf(tex_name, "@var{?}");
- String *tm = Getattr(p, "tmap:in");
- if (tm) {
- pnext = Getattr(p, "tmap:in:next");
- } else {
- pnext = nextSibling(p);
- }
-
if (Len(decl_str))
Append(decl_str, ", ");
Append(decl_str, tex_name);
if (value) {
- if (Strcmp(value, "NULL") == 0)
- value = NewString("nil");
- else if (Strcmp(value, "true") == 0 || Strcmp(value, "TRUE") == 0)
- value = NewString("true");
- else if (Strcmp(value, "false") == 0 || Strcmp(value, "FALSE") == 0)
- value = NewString("false");
- else {
- lookup = Swig_symbol_clookup(value, 0);
+ String *new_value = convertValue(value, Getattr(p, "type"));
+ if (new_value) {
+ value = new_value;
+ } else {
+ Node *lookup = Swig_symbol_clookup(value, 0);
if (lookup)
value = Getattr(lookup, "sym:name");
}
Printf(decl_str, " = %s", value);
}
- if (type) {
- String *type_str = NewString("");
- type = SwigType_base(type);
- lookup = Swig_symbol_clookup(type, 0);
- if (lookup)
- type = Getattr(lookup, "sym:name");
- Printf(type_str, "%s is of type %s. ", tex_name, type);
- Append(args_str, type_str);
- Delete(type_str);
- }
+ Node *nn = classLookup(Getattr(p, "type"));
+ String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
+ Printf(args_str, "%s is of type %s. ", tex_name, type_str);
+ Delete(type_str);
Delete(tex_name);
+ Delete(name);
}
if (pdocs)
Setattr(n, "feature:pdocs", pdocs);
Delete(plist);
}
+ /* ------------------------------------------------------------
+ * convertValue()
+ * Check if string v can be an Octave value literal,
+ * (eg. number or string), or translate it to an Octave literal.
+ * ------------------------------------------------------------ */
+ String *convertValue(String *v, SwigType *t) {
+ if (v && Len(v) > 0) {
+ char fc = (Char(v))[0];
+ if (('0' <= fc && fc <= '9') || '\'' == fc || '"' == fc) {
+ /* number or string (or maybe NULL pointer) */
+ if (SwigType_ispointer(t) && Strcmp(v, "0") == 0)
+ return NewString("None");
+ else
+ return v;
+ }
+ if (Strcmp(v, "NULL") == 0)
+ return SwigType_ispointer(t) ? NewString("nil") : NewString("0");
+ else if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0)
+ return NewString("true");
+ else if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
+ return NewString("false");
+ if (Strcmp(v, "true") == 0 || Strcmp(v, "FALSE") == 0)
+ return NewString("true");
+ if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
+ return NewString("false");
+ }
+ return 0;
+ }
+
virtual int functionWrapper(Node *n) {
Wrapper *f = NewWrapper();
Parm *p;
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index aab40ca94..e1dad5259 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -1384,9 +1384,9 @@ public:
// Write default value
if (value && !calling) {
- String *pv = pyvalue(value, Getattr(p, "type"));
- if (pv) {
- value = pv;
+ String *new_value = convertValue(value, Getattr(p, "type"));
+ if (new_value) {
+ value = new_value;
} else {
Node *lookup = Swig_symbol_clookup(value, 0);
if (lookup)
@@ -1542,11 +1542,11 @@ public:
}
/* ------------------------------------------------------------
- * pyvalue()
+ * convertValue()
* Check if string v can be a Python value literal,
* (eg. number or string), or translate it to a Python literal.
* ------------------------------------------------------------ */
- String *pyvalue(String *v, SwigType *t) {
+ String *convertValue(String *v, SwigType *t) {
if (v && Len(v) > 0) {
char fc = (Char(v))[0];
if (('0' <= fc && fc <= '9') || '\'' == fc || '"' == fc) {
@@ -1589,7 +1589,7 @@ public:
}
String *type = Getattr(p, "type");
String *value = Getattr(p, "value");
- if (!pyvalue(value, type))
+ if (!convertValue(value, type))
return false;
}
return true;
diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx
index d2ce97592..1ad1241ee 100644
--- a/Source/Modules/ruby.cxx
+++ b/Source/Modules/ruby.cxx
@@ -296,6 +296,30 @@ private:
return doc;
}
+ /* -----------------------------------------------------------------------------
+ * addMissingParameterNames()
+ * For functions that have not had nameless parameters set in the Language class.
+ *
+ * Inputs:
+ * plist - entire parameter list
+ * arg_offset - argument number for first parameter
+ * Side effects:
+ * The "lname" attribute in each parameter in plist will be contain a parameter name
+ * ----------------------------------------------------------------------------- */
+
+ void addMissingParameterNames(ParmList *plist, int arg_offset) {
+ Parm *p = plist;
+ int i = arg_offset;
+ while (p) {
+ if (!Getattr(p, "lname")) {
+ String *pname = Swig_cparm_name(p, i);
+ Delete(pname);
+ }
+ i++;
+ p = nextSibling(p);
+ }
+ }
+
/* ------------------------------------------------------------
* make_autodocParmList()
* Generate the documentation for the function parameters
@@ -303,22 +327,36 @@ private:
String *make_autodocParmList(Node *n, bool showTypes) {
String *doc = NewString("");
- String *pdocs = Copy(Getattr(n, "feature:pdocs"));
+ String *pdocs = 0;
ParmList *plist = CopyParmList(Getattr(n, "parms"));
Parm *p;
Parm *pnext;
- Node *lookup;
int lines = 0;
- const int maxwidth = 50;
-
- if (pdocs)
- Append(pdocs, ".\n");
+ int start_arg_num = is_wrapping_class() ? 1 : 0;
+ const int maxwidth = 80;
+ addMissingParameterNames(plist, start_arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
Swig_typemap_attach_parms("in", plist, 0);
Swig_typemap_attach_parms("doc", plist, 0);
+ if (Strcmp(ParmList_protostr(plist), "void") == 0) {
+ //No parameters actually
+ return doc;
+ }
+
for (p = plist; p; p = pnext) {
+
+ String *tm = Getattr(p, "tmap:in");
+ if (tm) {
+ pnext = Getattr(p, "tmap:in:next");
+ if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ continue;
+ }
+ } else {
+ pnext = nextSibling(p);
+ }
+
String *name = 0;
String *type = 0;
String *value = 0;
@@ -329,21 +367,16 @@ private:
value = Getattr(p, "tmap:doc:value");
}
+ // Note: the generated name should be consistent with that in kwnames[]
name = name ? name : Getattr(p, "name");
+ name = name ? name : Getattr(p, "lname");
+ name = Swig_name_make(p, 0, name, 0, 0); // rename parameter if a keyword
+
type = type ? type : Getattr(p, "type");
value = value ? value : Getattr(p, "value");
-
- String *tm = Getattr(p, "tmap:in");
- if (tm) {
- pnext = Getattr(p, "tmap:in:next");
- } else {
- pnext = nextSibling(p);
- }
-
- // Skip ignored input attributes
- if (checkAttribute(p, "tmap:in:numinputs", "0"))
- continue;
+ if (SwigType_isvarargs(type))
+ break;
// Skip the 'self' parameter which in ruby is implicit
if ( Cmp(name, "self") == 0 )
@@ -362,40 +395,33 @@ private:
lines += 1;
}
}
- // Do the param type too?
- if (showTypes) {
- type = SwigType_base(type);
- lookup = Swig_symbol_clookup(type, 0);
- if (lookup)
- type = Getattr(lookup, "sym:name");
- Printf(doc, "%s ", type);
- }
- if (name) {
- Append(doc, name);
- if (pdoc) {
- if (!pdocs)
- pdocs = NewString("Parameters:\n");
- Printf(pdocs, " %s.\n", pdoc);
- }
- } else {
- Append(doc, "?");
+ // Do the param type too?
+ Node *nn = classLookup(Getattr(p, "type"));
+ String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
+ if (showTypes)
+ Printf(doc, "%s ", type_str);
+
+ Append(doc, name);
+ if (pdoc) {
+ if (!pdocs)
+ pdocs = NewString("Parameters:\n");
+ Printf(pdocs, " %s.\n", pdoc);
}
if (value) {
- if (Strcmp(value, "NULL") == 0)
- value = NewString("nil");
- else if (Strcmp(value, "true") == 0 || Strcmp(value, "TRUE") == 0)
- value = NewString("true");
- else if (Strcmp(value, "false") == 0 || Strcmp(value, "FALSE") == 0)
- value = NewString("false");
- else {
- lookup = Swig_symbol_clookup(value, 0);
+ String *new_value = convertValue(value, Getattr(p, "type"));
+ if (new_value) {
+ value = new_value;
+ } else {
+ Node *lookup = Swig_symbol_clookup(value, 0);
if (lookup)
value = Getattr(lookup, "sym:name");
}
Printf(doc, "=%s", value);
}
+ Delete(type_str);
+ Delete(name);
}
if (pdocs)
Setattr(n, "feature:pdocs", pdocs);
@@ -425,55 +451,53 @@ private:
String* super_names = NewString("");
String* class_name = Getattr(pn, "sym:name") ;
- if ( !class_name ) class_name = NewString("");
- else
- {
- class_name = Copy(class_name);
- List *baselist = Getattr(pn, "bases");
- if (baselist && Len(baselist)) {
- Iterator base = First(baselist);
- while (base.item && GetFlag(base.item, "feature:ignore")) {
- base = Next(base);
- }
-
- int count = 0;
- for ( ;base.item; ++count) {
- if ( count ) Append(super_names, ", ");
- String *basename = Getattr(base.item, "sym:name");
+ if ( !class_name ) {
+ class_name = NewString("");
+ } else {
+ class_name = Copy(class_name);
+ List *baselist = Getattr(pn, "bases");
+ if (baselist && Len(baselist)) {
+ Iterator base = First(baselist);
+ while (base.item && GetFlag(base.item, "feature:ignore")) {
+ base = Next(base);
+ }
- String* basenamestr = NewString(basename);
- Node* parent = parentNode(base.item);
- while (parent)
- {
- String *parent_name = Copy( Getattr(parent, "sym:name") );
- if ( !parent_name ) {
- Node* mod = Getattr(parent, "module");
- if ( mod )
- parent_name = Copy( Getattr(mod, "name") );
- if ( parent_name )
- {
- (Char(parent_name))[0] = (char)toupper((Char(parent_name))[0]);
- }
- }
- if ( parent_name )
- {
- Insert(basenamestr, 0, "::");
- Insert(basenamestr, 0, parent_name);
- Delete(parent_name);
- }
- parent = parentNode(parent);
- }
+ int count = 0;
+ for ( ;base.item; ++count) {
+ if ( count ) Append(super_names, ", ");
+ String *basename = Getattr(base.item, "sym:name");
- Append(super_names, basenamestr );
- Delete(basenamestr);
- base = Next(base);
+ String* basenamestr = NewString(basename);
+ Node* parent = parentNode(base.item);
+ while (parent)
+ {
+ String *parent_name = Copy( Getattr(parent, "sym:name") );
+ if ( !parent_name ) {
+ Node* mod = Getattr(parent, "module");
+ if ( mod )
+ parent_name = Copy( Getattr(mod, "name") );
+ if ( parent_name )
+ (Char(parent_name))[0] = (char)toupper((Char(parent_name))[0]);
+ }
+ if ( parent_name ) {
+ Insert(basenamestr, 0, "::");
+ Insert(basenamestr, 0, parent_name);
+ Delete(parent_name);
+ }
+ parent = parentNode(parent);
}
+
+ Append(super_names, basenamestr );
+ Delete(basenamestr);
+ base = Next(base);
}
}
+ }
String* full_name;
if ( module ) {
full_name = NewString(module);
- if (class_name && Len(class_name) > 0) Append(full_name, "::");
+ if (class_name && Len(class_name) > 0)
+ Append(full_name, "::");
}
else
full_name = NewString("");
@@ -508,6 +532,7 @@ private:
bool skipAuto = false;
Node* on = n;
for ( ; n; ++counter ) {
+ String *type_str = NULL;
skipAuto = false;
bool showTypes = false;
String *autodoc = Getattr(n, "feature:autodoc");
@@ -537,17 +562,15 @@ private:
SwigType *type = Getattr(n, "type");
if (type) {
- if (Strcmp(type, "void") == 0)
- type = NULL;
- else {
+ if (Strcmp(type, "void") == 0) {
+ type_str = NULL;
+ } else {
SwigType *qt = SwigType_typedef_resolve_all(type);
- if (SwigType_isenum(qt))
- type = NewString("int");
- else {
- type = SwigType_base(type);
- Node *lookup = Swig_symbol_clookup(type, 0);
- if (lookup)
- type = Getattr(lookup, "sym:name");
+ if (SwigType_isenum(qt)) {
+ type_str = NewString("int");
+ } else {
+ Node *nn = classLookup(type);
+ type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
}
}
}
@@ -582,7 +605,6 @@ private:
}
}
-
if (skipAuto) {
if ( counter == 0 ) Printf(doc, " call-seq:\n");
switch( ad_type )
@@ -597,21 +619,21 @@ private:
Printf(doc, " %s(%s)", symname, paramList);
else
Printf(doc, " %s", symname);
- if (type)
- Printf(doc, " -> %s", type);
+ if (type_str)
+ Printf(doc, " -> %s", type_str);
break;
}
case AUTODOC_SETTER:
{
Printf(doc, " %s=(x)", symname);
- if (type) Printf(doc, " -> %s", type);
+ if (type_str)
+ Printf(doc, " -> %s", type_str);
break;
}
default:
break;
}
- }
- else {
+ } else {
switch (ad_type) {
case AUTODOC_CLASS:
{
@@ -627,7 +649,8 @@ private:
}
break;
case AUTODOC_CTOR:
- if (counter == 0) Printf(doc, " call-seq:\n");
+ if (counter == 0)
+ Printf(doc, " call-seq:\n");
if (Strcmp(class_name, symname) == 0) {
String *paramList = make_autodocParmList(n, showTypes);
if (Len(paramList))
@@ -647,21 +670,23 @@ private:
case AUTODOC_METHOD:
case AUTODOC_GETTER:
{
- if (counter == 0) Printf(doc, " call-seq:\n");
+ if (counter == 0)
+ Printf(doc, " call-seq:\n");
String *paramList = make_autodocParmList(n, showTypes);
if (Len(paramList))
Printf(doc, " %s(%s)", symname, paramList);
else
Printf(doc, " %s", symname);
- if (type)
- Printf(doc, " -> %s", type);
+ if (type_str)
+ Printf(doc, " -> %s", type_str);
break;
}
case AUTODOC_SETTER:
{
Printf(doc, " call-seq:\n");
Printf(doc, " %s=(x)", symname);
- if (type) Printf(doc, " -> %s", type);
+ if (type_str)
+ Printf(doc, " -> %s", type_str);
break;
}
}
@@ -671,6 +696,7 @@ private:
n = Getattr(n, "sym:nextSibling");
if (n)
Append(doc, "\n");
+ Delete(type_str);
}
Printf(doc, "\n\n");
@@ -748,6 +774,35 @@ private:
return doc;
}
+ /* ------------------------------------------------------------
+ * convertValue()
+ * Check if string v can be a Ruby value literal,
+ * (eg. number or string), or translate it to a Ruby literal.
+ * ------------------------------------------------------------ */
+ String *convertValue(String *v, SwigType *t) {
+ if (v && Len(v) > 0) {
+ char fc = (Char(v))[0];
+ if (('0' <= fc && fc <= '9') || '\'' == fc || '"' == fc) {
+ /* number or string (or maybe NULL pointer) */
+ if (SwigType_ispointer(t) && Strcmp(v, "0") == 0)
+ return NewString("None");
+ else
+ return v;
+ }
+ if (Strcmp(v, "NULL") == 0)
+ return SwigType_ispointer(t) ? NewString("nil") : NewString("0");
+ else if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0)
+ return NewString("true");
+ else if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
+ return NewString("false");
+ if (Strcmp(v, "true") == 0 || Strcmp(v, "FALSE") == 0)
+ return NewString("True");
+ if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
+ return NewString("False");
+ }
+ return 0;
+ }
+
public:
/* ---------------------------------------------------------------------
From 8a6e006a7b6835fdd7c851f718d6fb39b352ffc6 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 17 Jun 2011 06:41:53 +0000
Subject: [PATCH 007/147] Marshalling char[] and char[ANY] to Java byte[] is
now a bit easier
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12742 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Examples/test-suite/java/java_lib_arrays_runme.java | 7 +++++++
Examples/test-suite/java_lib_arrays.i | 13 +++++++++++++
Lib/java/arrays_java.i | 12 +++++++-----
3 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/Examples/test-suite/java/java_lib_arrays_runme.java b/Examples/test-suite/java/java_lib_arrays_runme.java
index 9ee36210a..09a175ebb 100644
--- a/Examples/test-suite/java/java_lib_arrays_runme.java
+++ b/Examples/test-suite/java/java_lib_arrays_runme.java
@@ -23,6 +23,7 @@ public class java_lib_arrays_runme {
// Create arrays for all the array types that ArrayStruct can handle
String array_c = "X";
+ byte[] array_c_extra = {11, 22};
byte[] array_sc = {10, 20};
short[] array_uc = {101, 201};
short[] array_s = {1002, 2002};
@@ -105,6 +106,12 @@ public class java_lib_arrays_runme {
as.setArray_struct(array_struct);
check_struct_array(array_struct, as.getArray_struct());
+
+ // Extended element (for char[])
+ ArrayStructExtra ase = new ArrayStructExtra();
+ ase.setArray_c2(array_c_extra);
+ check_byte_array(array_c_extra, ase.getArray_c2());
+
}
// Functions to check that the array values were set correctly
diff --git a/Examples/test-suite/java_lib_arrays.i b/Examples/test-suite/java_lib_arrays.i
index 0551cd100..8f9b0fd65 100644
--- a/Examples/test-suite/java_lib_arrays.i
+++ b/Examples/test-suite/java_lib_arrays.i
@@ -8,6 +8,7 @@
JAVA_ARRAYSOFCLASSES(SimpleStruct)
%apply ARRAYSOFENUMS[ANY] { finger[ANY] }
+//%apply signed char[ANY] { char array_c2[ANY] }
%include "arrays.i"
@@ -54,3 +55,15 @@ typedef enum { Big, Little } toe;
void toestest(toe *t, toe tt[], toe ttt[2]) {}
%}
+
+JAVA_ARRAYS_IMPL(char, jbyte, Byte, Char)
+JAVA_ARRAYS_TYPEMAPS(char, byte, jbyte, Char, "[B")
+%typecheck(SWIG_TYPECHECK_INT8_ARRAY) /* Java byte[] */
+ signed char[ANY], signed char[]
+ ""
+
+%inline %{
+struct ArrayStructExtra {
+ char array_c2[ARRAY_LEN];
+};
+%}
diff --git a/Lib/java/arrays_java.i b/Lib/java/arrays_java.i
index ddaf7408c..64b85a89a 100644
--- a/Lib/java/arrays_java.i
+++ b/Lib/java/arrays_java.i
@@ -147,19 +147,19 @@ JAVA_ARRAYS_IMPL(double, jdouble, Double, Double) /* double[] */
%typemap(jstype) CTYPE[ANY], CTYPE[] %{JTYPE[]%}
%typemap(in) CTYPE[] (JNITYPE *jarr)
-%{ if (!SWIG_JavaArrayIn##JFUNCNAME(jenv, &jarr, &$1, $input)) return $null; %}
+%{ if (!SWIG_JavaArrayIn##JFUNCNAME(jenv, &jarr, (CTYPE **)&$1, $input)) return $null; %}
%typemap(in) CTYPE[ANY] (JNITYPE *jarr)
%{ if ($input && JCALL1(GetArrayLength, jenv, $input) != $1_size) {
SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "incorrect array size");
return $null;
}
- if (!SWIG_JavaArrayIn##JFUNCNAME(jenv, &jarr, &$1, $input)) return $null; %}
+ if (!SWIG_JavaArrayIn##JFUNCNAME(jenv, &jarr, (CTYPE **)&$1, $input)) return $null; %}
%typemap(argout) CTYPE[ANY], CTYPE[]
-%{ SWIG_JavaArrayArgout##JFUNCNAME(jenv, jarr$argnum, $1, $input); %}
+%{ SWIG_JavaArrayArgout##JFUNCNAME(jenv, jarr$argnum, (CTYPE *)$1, $input); %}
%typemap(out) CTYPE[ANY]
-%{$result = SWIG_JavaArrayOut##JFUNCNAME(jenv, $1, $1_dim0); %}
+%{$result = SWIG_JavaArrayOut##JFUNCNAME(jenv, (CTYPE *)$1, $1_dim0); %}
%typemap(out) CTYPE[]
-%{$result = SWIG_JavaArrayOut##JFUNCNAME(jenv, $1, FillMeInAsSizeCannotBeDeterminedAutomatically); %}
+%{$result = SWIG_JavaArrayOut##JFUNCNAME(jenv, (CTYPE *)$1, FillMeInAsSizeCannotBeDeterminedAutomatically); %}
%typemap(freearg) CTYPE[ANY], CTYPE[]
#ifdef __cplusplus
%{ delete [] $1; %}
@@ -172,6 +172,8 @@ JAVA_ARRAYS_IMPL(double, jdouble, Double, Double) /* double[] */
return $jnicall;
}
+%typemap(memberin) CTYPE[ANY], CTYPE[];
+%typemap(globalin) CTYPE[ANY], CTYPE[];
%enddef
JAVA_ARRAYS_TYPEMAPS(bool, boolean, jboolean, Bool, "[Z") /* bool[ANY] */
From eb398f692d316b8e29911fa1db286765618066df Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 17 Jun 2011 06:50:19 +0000
Subject: [PATCH 008/147] Marshalling char[] and char[ANY] to Java byte[] is
now a bit easier
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12743 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/CHANGES.current b/CHANGES.current
index b47de9b69..3b6691c65 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.5 (in progress)
===========================
+2011-06-17: wsfulton
+ [Java] SF #3312505 - slightly easier to wrap char[] or char[ANY] with a Java byte[]
+ using arrays_java.i.
+
2011-06-13: wsfulton
[Ruby, Octave] SF #3310528 Autodoc fixes similar to those described below for Python.
From 88d540683e8168dbf224da296ba2d6ebe95804a8 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Sat, 18 Jun 2011 04:24:19 +0000
Subject: [PATCH 009/147] [Tcl] Fix variable declarations in middle of blocks
which isn't permitted in C90 (issue probably introduced in 2.0.3 by patch
#3224663). Reported by Paul Obermeier in SF#3288586.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12744 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 5 +++++
Lib/tcl/tclinit.swg | 5 ++---
Lib/tcl/tclrun.swg | 3 ++-
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index 3b6691c65..848dd25dd 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -5,6 +5,11 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.5 (in progress)
===========================
+2011-06-18: olly
+ [Tcl] Fix variable declarations in middle of blocks which isn't
+ permitted in C90 (issue probably introduced in 2.0.3 by patch #3224663).
+ Reported by Paul Obermeier in SF#3288586.
+
2011-06-17: wsfulton
[Java] SF #3312505 - slightly easier to wrap char[] or char[ANY] with a Java byte[]
using arrays_java.i.
diff --git a/Lib/tcl/tclinit.swg b/Lib/tcl/tclinit.swg
index 87e398d91..3140bdcdb 100644
--- a/Lib/tcl/tclinit.swg
+++ b/Lib/tcl/tclinit.swg
@@ -77,13 +77,12 @@ SWIG_Tcl_InstallMethodLookupTables(void) {
swig_type_info *type = swig_module.type_initial[i];
if (type->clientdata) {
swig_class* klass = (swig_class*) type->clientdata;
+ swig_method* meth;
Tcl_InitHashTable(&(klass->hashtable), TCL_STRING_KEYS);
- swig_method* meth = klass->methods;
- while (meth && meth->name) {
+ for (meth = klass->methods; meth && meth->name; ++meth) {
int newEntry;
Tcl_HashEntry* hashentry = Tcl_CreateHashEntry(&(klass->hashtable), meth->name, &newEntry);
Tcl_SetHashValue(hashentry, (ClientData)meth->method);
- ++meth;
}
}
}
diff --git a/Lib/tcl/tclrun.swg b/Lib/tcl/tclrun.swg
index 66bb4d201..c91a7e511 100644
--- a/Lib/tcl/tclrun.swg
+++ b/Lib/tcl/tclrun.swg
@@ -340,6 +340,7 @@ SWIG_Tcl_MethodCommand(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_
cls_stack_bi[cls_stack_top] = -1;
cls = inst->classptr;
while (1) {
+ Tcl_HashEntry* hashentry;
bi = cls_stack_bi[cls_stack_top];
cls = cls_stack[cls_stack_top];
if (bi != -1) {
@@ -364,7 +365,7 @@ SWIG_Tcl_MethodCommand(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_
}
cls_stack_bi[cls_stack_top]++;
- Tcl_HashEntry* hashentry = Tcl_FindHashEntry(&(cls->hashtable), method);
+ hashentry = Tcl_FindHashEntry(&(cls->hashtable), method);
if (hashentry) {
ClientData cd = Tcl_GetHashValue(hashentry);
swig_wrapper method_wrapper = (swig_wrapper)cd;
From f320ea1d4a83a58b3e0873824eaf693df62a9916 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Sat, 18 Jun 2011 04:33:00 +0000
Subject: [PATCH 010/147] Update supported Perl versions to more closely
reflect reality.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12745 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Doc/Manual/Perl5.html | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Doc/Manual/Perl5.html b/Doc/Manual/Perl5.html
index 5aae51888..72fe78be8 100644
--- a/Doc/Manual/Perl5.html
+++ b/Doc/Manual/Perl5.html
@@ -82,9 +82,9 @@
This chapter describes SWIG's support of Perl5. Although the Perl5
module is one of the earliest SWIG modules, it has continued to evolve
and has been improved greatly with the help of SWIG users. For the
-best results, it is recommended that SWIG be used with Perl5.003 or
-later. Earlier versions are problematic and SWIG generated extensions
-may not compile or run correctly.
+best results, it is recommended that SWIG be used with Perl 5.8 or
+later. We're no longer testing regularly with older versions, but
+Perl 5.6 seems to mostly work, while older versions don't.
30.1 Overview
From 4cf0f14cb9468d56636604de178150e8baa2e3c8 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 20 Jun 2011 17:38:02 +0000
Subject: [PATCH 011/147] Add function comment
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12746 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Source/CParse/parser.y | 1 +
1 file changed, 1 insertion(+)
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index e6c6e5143..6ea1777b5 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -214,6 +214,7 @@ Hash *Swig_cparse_features(void) {
return features_hash;
}
+/* Fully qualify any template parameters */
static String *feature_identifier_fix(String *s) {
String *tp = SwigType_istemplate_templateprefix(s);
if (tp) {
From d38e6bdf43625b6bbe207a424b153b8d36f420ae Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 20 Jun 2011 17:46:38 +0000
Subject: [PATCH 012/147] Fix incorrect typemaps being used for a symbol within
a templated type
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12747 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 4 ++++
Examples/test-suite/typemap_template.i | 10 ++++++++--
Source/Swig/swig.h | 1 +
Source/Swig/typemap.c | 4 ++--
Source/Swig/typeobj.c | 26 ++++++++++++++++++++++++++
5 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index 848dd25dd..e8f8f9a35 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.5 (in progress)
===========================
+2011-06-19: wsfulton
+ Fix incorrect typemaps being used for a symbol within a templated type, eg:
+ A::value_type would incorrectly use a typemap for type A.
+
2011-06-18: olly
[Tcl] Fix variable declarations in middle of blocks which isn't
permitted in C90 (issue probably introduced in 2.0.3 by patch #3224663).
diff --git a/Examples/test-suite/typemap_template.i b/Examples/test-suite/typemap_template.i
index ad35371cc..7ef77c79d 100644
--- a/Examples/test-suite/typemap_template.i
+++ b/Examples/test-suite/typemap_template.i
@@ -2,8 +2,8 @@
/* Test bug in 1.3.40 where the presence of a generic/unspecialized typemap caused the incorrect specialized typemap to be used */
-%typemap(in) SWIGTYPE "/*_this_will_not_compile_SWIGTYPE_ \"$type\" */ "
-%typemap(in) const SWIGTYPE & "/*_this_will_not_compile_const_SWIGTYPE_REF_\"$type\" */ "
+%typemap(in) SWIGTYPE "_this_will_not_compile_SWIGTYPE_ \"$type\" "
+%typemap(in) const SWIGTYPE & "_this_will_not_compile_const_SWIGTYPE_REF_\"$type\" "
%typemap(in) const TemplateTest1 & {$1 = (TemplateTest1 *)0; /* in typemap generic for $type */}
%typemap(in) const TemplateTest1< ZZ > & {$1 = (TemplateTest1 *)0; /* in typemap ZZ for $type */}
@@ -12,6 +12,7 @@
%inline %{
template struct TemplateTest1 {
void setT(const TemplateTest1& t) {}
+ typedef double Double;
};
%}
@@ -32,3 +33,8 @@ template struct TemplateTest1 {
{}
%}
+%typemap(in) TemplateTest1 "_this_will_not_compile_TemplateTest_ \"$type\" "
+
+%inline %{
+ void wasbug(TemplateTest1< int >::Double wbug) {}
+%}
diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h
index db6144ce6..c5b1a7ce3 100644
--- a/Source/Swig/swig.h
+++ b/Source/Swig/swig.h
@@ -166,6 +166,7 @@ extern "C" {
extern String *SwigType_templateprefix(const SwigType *t);
extern String *SwigType_templatesuffix(const SwigType *t);
extern String *SwigType_istemplate_templateprefix(const SwigType *t);
+ extern String *SwigType_istemplate_only_templateprefix(const SwigType *t);
extern String *SwigType_templateargs(const SwigType *t);
extern String *SwigType_prefix(const SwigType *t);
extern int SwigType_array_ndim(const SwigType *t);
diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c
index fe6a33641..412db3f93 100644
--- a/Source/Swig/typemap.c
+++ b/Source/Swig/typemap.c
@@ -728,8 +728,8 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
goto ret_result;
{
- /* Look for the type reduced to just the template prefix */
- SwigType *template_prefix = SwigType_istemplate_templateprefix(ctype);
+ /* Look for the type reduced to just the template prefix - for templated types without the template parameter list being specified */
+ SwigType *template_prefix = SwigType_istemplate_only_templateprefix(ctype);
if (template_prefix) {
tm = get_typemap(ts, template_prefix);
result = typemap_search_helper(debug_display, tm, tm_method, template_prefix, cqualifiedname, cname, &backup);
diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c
index dd8d901e0..b8ecf6e6a 100644
--- a/Source/Swig/typeobj.c
+++ b/Source/Swig/typeobj.c
@@ -927,6 +927,32 @@ String *SwigType_istemplate_templateprefix(const SwigType *t) {
return c ? NewStringWithSize(s, c - s) : 0;
}
+/* -----------------------------------------------------------------------------
+ * SwigType_istemplate_only_templateprefix()
+ *
+ * Similar to SwigType_istemplate_templateprefix() but only returns the template
+ * prefix if the type is just the template and not a subtype/symbol within the template.
+ * Returns NULL if not a template or is a template with a symbol within the template.
+ * For example:
+ *
+ * Foo<(p.int)> => Foo
+ * Foo<(p.int)>::bar => NULL
+ * r.q(const).Foo<(p.int)> => r.q(const).Foo
+ * r.q(const).Foo<(p.int)>::bar => NULL
+ * Foo => NULL
+ * ----------------------------------------------------------------------------- */
+
+String *SwigType_istemplate_only_templateprefix(const SwigType *t) {
+ int len = Len(t);
+ const char *s = Char(t);
+ if (len >= 4 && strcmp(s + len - 2, ")>") == 0) {
+ const char *c = strstr(s, "<(");
+ return c ? NewStringWithSize(s, c - s) : 0;
+ } else {
+ return 0;
+ }
+}
+
/* -----------------------------------------------------------------------------
* SwigType_templateargs()
*
From b8dcf31539b3ad4f6b06c339e47ea91f1c9f99bd Mon Sep 17 00:00:00 2001
From: Mikel Bancroft
Date: Tue, 21 Jun 2011 18:51:25 +0000
Subject: [PATCH 013/147] [allegrocl] Small set of bug fixes and typemap
tweaks.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12748 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 11 ++++
Lib/allegrocl/allegrocl.swg | 7 +++
Lib/allegrocl/longlongs.i | 36 +++++++++----
Source/Modules/allegrocl.cxx | 97 ++++++++++++++++++++++++++++++------
4 files changed, 125 insertions(+), 26 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index e8f8f9a35..09ac4a022 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -5,6 +5,17 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.5 (in progress)
===========================
+2011-06-21: mutandiz
+ [allegrocl]
+ - various small tweaks and bug fixes.
+ - Avoid name conflicts between smart pointer wrappers and the wrappers for
+ the actual class.
+ - Fix default typemaps for C bindings, which were incorrectly attempting to
+ call non-existent destructors on user-defined types.
+ - New feature, feature:aclmixins, for adding superclass to the foreign class
+ wrappers.
+ - Improve longlong typemaps.
+
2011-06-19: wsfulton
Fix incorrect typemaps being used for a symbol within a templated type, eg:
A::value_type would incorrectly use a typemap for type A.
diff --git a/Lib/allegrocl/allegrocl.swg b/Lib/allegrocl/allegrocl.swg
index 87e030ce4..f08f87c3c 100644
--- a/Lib/allegrocl/allegrocl.swg
+++ b/Lib/allegrocl/allegrocl.swg
@@ -16,6 +16,7 @@
float, double, long double, char *, void *,
enum SWIGTYPE "(cl::setq ACL_ffresult $body)";
%typemap(lout) void "$body";
+#ifdef __cplusplus
%typemap(lout) SWIGTYPE[ANY], SWIGTYPE *,
SWIGTYPE &
%{ (cl:let* ((address $body)
@@ -25,6 +26,12 @@
(cl:setq ACL_ffresult new-inst)) %}
%typemap(lout) SWIGTYPE "(cl::let* ((address $body)\n (new-inst (cl::make-instance '$lclass :foreign-address address)))\n (cl::unless (cl::zerop address)\n (excl:schedule-finalization new-inst #'$ldestructor))\n (cl::setq ACL_ffresult new-inst))";
+#else
+%typemap(lout) SWIGTYPE[ANY], SWIGTYPE *, SWIGTYPE &, SWIGTYPE
+%{ (cl:let* ((address $body)
+ (new-inst (cl:make-instance '$lclass :foreign-address address)))
+ (cl:setq ACL_ffresult new-inst)) %}
+#endif
%typemap(lisptype) bool, const bool "cl:boolean";
%typemap(lisptype) char, const char "cl:character";
diff --git a/Lib/allegrocl/longlongs.i b/Lib/allegrocl/longlongs.i
index 4aa54660b..a15adcdda 100644
--- a/Lib/allegrocl/longlongs.i
+++ b/Lib/allegrocl/longlongs.i
@@ -7,27 +7,43 @@
* functions have been defined.
* ----------------------------------------------------------------------------- */
-%typemap(in) long long, unsigned long long "$1 = $input;";
-%typemap(out) long long, unsigned long long "$result = &$1;";
+#ifdef Acl64Bit
+%typemap(ctype) long long, unsigned long long "$1_ltype";
+%typemap(out) long long, unsigned long long "$result = $1;";
+%typemap(ffitype) long long ":nat";
+%typemap(ffitype) unsigned long long ":unsigned-nat";
+
+%typemap(lout) long long, unsigned long long " #+64bit (cl::setq ACL_ffresult $body)";
+
+#else
+%typemap(out) long long, unsigned long long "$result = &$1;";
%typemap(ffitype) long long "(:struct (l1 :long) (l2 :long))";
-%typemap(ffitype) unsigned long long "(:struct (l1 :unsigned-long)
- (l2 :unsigned-long))";
+
+%typemap(ffitype) unsigned long long "(:struct (l1 :unsigned-long) (l2 :unsigned-long))";
%typemap(lout) long long
-" (make-instance #.(swig-insert-id \"longlong\" () :type :class)
- :foreign-address $body)";
+" (cl::setq ACL_ffresult (make-instance '#.(swig-insert-id \"longlong\" () :type :class)
+ :foreign-address $body))";
+
%typemap(lout) unsigned long long
-" (make-instance #.(swig-insert-id \"ulonglong\" () :type :class)
- :foreign-address $body)";
+" (cl:setq ACL_ffresult (make-instance '#.(swig-insert-id \"ulonglong\" () :type :class)
+ :foreign-address $body))";
+
+#endif
+
+%typemap(in) long long, unsigned long long "$1 = $input;";
+
%insert("lisphead") %{
+#-64bit
(swig-def-foreign-class "longlong"
(ff:foreign-pointer)
- (:struct (:struct (l1 :long) (l2 :long))))
+ (:struct (l1 :long) (l2 :long)))
+#-64bit
(swig-def-foreign-class "ulonglong"
(ff:foreign-pointer)
- (:struct (:struct (l1 :unsigned-long) (l2 :unsigned-long))))
+ (:struct (l1 :unsigned-long) (l2 :unsigned-long)))
%}
diff --git a/Source/Modules/allegrocl.cxx b/Source/Modules/allegrocl.cxx
index df0b3b3d1..70096a226 100644
--- a/Source/Modules/allegrocl.cxx
+++ b/Source/Modules/allegrocl.cxx
@@ -162,10 +162,27 @@ String *namespaced_name(Node *n, String *ns = current_namespace) {
// "Namespace::Nested::Class2::Baz" -> "Baz"
static String *strip_namespaces(String *str) {
- char *result = Char(str);
+ SwigType *new_type = Copy(str);
+ SwigType *leading_type = SwigType_pop(new_type);
+ char *result = Char(leading_type);
+
+ if(SwigType_istemplate(leading_type)) {
+ result = Char(SwigType_templateprefix(leading_type));
+ } else {
+ if (!SwigType_issimple(leading_type))
+ return NewString(str);
+ }
+
String *stripped_one;
while ((stripped_one = Strstr(result, "::")))
result = Char(stripped_one) + 2;
+
+ if(SwigType_istemplate(leading_type)) {
+ SwigType_push(new_type, NewStringf("%s%s%s", result, SwigType_templateargs(leading_type),
+ SwigType_templatesuffix(leading_type)));
+ return new_type;
+ }
+
return NewString(result);
}
@@ -644,8 +661,12 @@ void note_implicit_template_instantiation(SwigType *t) {
#ifdef ALLEGROCL_CLASS_DEBUG
Printf(stderr, "culling namespace of '%s' from '%s'\n", t, SwigType_templateprefix(t));
#endif
- String *implicit_ns = namespace_of(SwigType_templateprefix(t));
+ SwigType *type = Copy(t);
+ SwigType *tok = SwigType_pop(type);
+ String *implicit_ns = SwigType_istemplate(tok) ? namespace_of(SwigType_templateprefix(tok)) : 0;
add_defined_foreign_type(0, 0, t, t, implicit_ns ? implicit_ns : current_namespace);
+
+ Delete(type);
}
String *get_ffi_type(Node *n, SwigType *ty, const_String_or_char_ptr name) {
@@ -1099,6 +1120,7 @@ void emit_stub_class(Node *n) {
#ifdef ALLEGROCL_WRAP_DEBUG
Printf(stderr, "emit_stub_class: ENTER... '%s'(%x)\n", Getattr(n, "sym:name"), n);
+ Swig_print_node(n);
#endif
@@ -1221,7 +1243,8 @@ void emit_full_class(Node *n) {
Printf(supers, "ff:foreign-pointer");
}
- Printf(supers, ")");
+ // check for "feature:aclmixins" and add those as well.
+ Printf(supers, " %s)", Getattr(n,"feature:aclmixins"));
// Walk children to generate type definition.
String *slotdefs = NewString(" ");
@@ -2026,7 +2049,7 @@ int emit_num_lin_arguments(ParmList *parms) {
int nargs = 0;
while (p) {
- // Printf(stderr,"enla: '%s' lin='%x'\n", Getattr(p,"name"), Getattr(p,"tmap:lin"));
+ // Printf(stderr,"enla: '%s' lin='%x' numinputs='%s'\n", Getattr(p,"name"), Getattr(p,"tmap:lin"), Getattr(p,"tmap:lin:numinputs"));
if (Getattr(p, "tmap:lin")) {
nargs += GetInt(p, "tmap:lin:numinputs");
p = Getattr(p, "tmap:lin:next");
@@ -2197,15 +2220,23 @@ struct IDargs {
return result;
}
- String *noname_str() {
+ String *noname_str(bool include_class = true) {
String *result = NewString("");
Printf(result, " :type :%s", type);
- if (klass)
+ if (klass && include_class)
Printf(result, " :class \"%s\"", klass);
if (arity)
Printf(result, " :arity %s", arity);
return result;
}
+
+ String *noname_no_others_str(bool include_class = true) {
+ String *result = NewString("");
+ Printf(result, " :type :%s", type);
+ if (klass && include_class)
+ Printf(result, " :class \"%s\"", klass);
+ return result;
+ }
};
IDargs *id_converter_arguments(Node *n) {
IDargs *result = (IDargs *) GetVoid(n, "allegrocl:id-converter-args");
@@ -2241,8 +2272,9 @@ IDargs *id_converter_arguments(Node *n) {
// :class
if (Strstr(result->type, "member ")) {
Replaceall(result->type, "member ", "");
- if (!result->klass)
+ if (!result->klass) {
result->klass = Copy(Getattr(parent_node_skipping_extends(n), "sym:name"));
+ }
}
// :arity
if (Getattr(n, "sym:overloaded")) {
@@ -2329,8 +2361,16 @@ int ALLEGROCL::emit_dispatch_defun(Node *n) {
#endif
List *overloads = Swig_overload_rank(n, true);
- String *id_args = id_converter_arguments(n)->no_others_quoted_str();
- Printf(f_clwrap, "(swig-dispatcher (%s :arities (", id_args);
+ // Printf(stderr,"\ndispatch node=%x\n\n", n);
+ // Swig_print_node(n);
+
+ Node *overloaded_from = Getattr(n,"sym:overloaded");
+ bool include_class = Getattr(overloaded_from, "allegrocl:dispatcher:include-class") ? true : false;
+ String *id_args = id_converter_arguments(n)->noname_no_others_str(include_class);
+ Printf(f_clwrap, "(swig-dispatcher (\"%s\" %s :arities (", Getattr(overloaded_from, "allegrocl:dispatcher:name"), id_args);
+
+ Delattr(overloaded_from, "allegrocl:dispatcher:include-class");
+ Delattr(overloaded_from, "allegrocl:dispatcher:name");
int last_arity = -1;
for (Iterator i = First(overloads); i.item; i = Next(i)) {
@@ -2359,16 +2399,24 @@ int ALLEGROCL::emit_defun(Node *n, File *fcl) {
Printf(stderr, "emit_defun: ENTER... ");
#endif
+ // avoid name conflicts between smart pointer wrappers and the wrappers for the
+ // actual class.
+ bool smartmemberwrapper = (!Cmp(Getattr(n, "view"), "memberfunctionHandler") &&
+ Getattr(n,"allocate:smartpointeraccess"));
+
#ifdef ALLEGROCL_DEBUG
int auto_generated = Cmp(Getattr(n, "view"), "globalfunctionHandler");
Printf(stderr, "%s%sfunction %s%s%s\n", auto_generated ? "> " : "", Getattr(n, "sym:overloaded")
? "overloaded " : "", current_namespace, (current_namespace) > 0 ? "::" : "", Getattr(n, "sym:name"));
Printf(stderr, " (view: %s)\n", Getattr(n, "view"));
+ Swig_print_node(n);
#endif
+
String *funcname = Getattr(n, "allegrocl:old-sym:name");
- if (!funcname)
+ if (smartmemberwrapper || !funcname)
funcname = Getattr(n, "sym:name");
+
String *mangled_name = Getattr(n, "wrap:name");
ParmList *pl = parmlist_with_names(Getattr(n, "wrap:parms"));
@@ -2388,10 +2436,16 @@ int ALLEGROCL::emit_defun(Node *n, File *fcl) {
int largnum = 0, argnum = 0, first = 1;
// int varargs=0;
if (Generate_Wrapper) {
- String *extra_parms = id_converter_arguments(n)->noname_str();
- if (Getattr(n, "sym:overloaded"))
+ String *extra_parms = id_converter_arguments(n)->noname_str(smartmemberwrapper ? false : true);
+ Node *overloaded_from = Getattr(n,"sym:overloaded");
+ if (overloaded_from) {
+ if(!GetFlag(overloaded_from,"allegrocl:dispatcher:name")) {
+ Setattr(overloaded_from,"allegrocl:dispatcher:name",funcname);
+ Setattr(overloaded_from,"allegrocl:dispatcher:include-class", smartmemberwrapper ? 0 : "1");
+ // Printf(stderr, " set a:d:name='%s', a:d:i-c='%s'\n", Getattr(n,"allegrocl:dispatcher:name"), Getattr(n,"allegrocl:dispatcher:include-class"));
+ }
Printf(fcl, "(swig-defmethod (\"%s\" \"%s\"%s)\n", funcname, mangled_name, extra_parms);
- else
+ } else
Printf(fcl, "(swig-defun (\"%s\" \"%s\"%s)\n", funcname, mangled_name, extra_parms);
Delete(extra_parms);
}
@@ -2568,7 +2622,6 @@ int ALLEGROCL::emit_defun(Node *n, File *fcl) {
int ALLEGROCL::functionWrapper(Node *n) {
#ifdef ALLEGROCL_DEBUG
Printf(stderr, "functionWrapper %s\n", Getattr(n,"name"));
- Swig_print_node(n);
#endif
@@ -2616,7 +2669,7 @@ int ALLEGROCL::functionWrapper(Node *n) {
if (Getattr(n, "overload:ignore")) {
// if we're the last overload, make sure to force the emit
// of the rest of the overloads before we leave.
- Printf(stderr, "ignored overload %s(%x)\n", name, Getattr(n, "sym:nextSibling"));
+ // Printf(stderr, "ignored overload %s(%x)\n", name, Getattr(n, "sym:nextSibling"));
if (!Getattr(n, "sym:nextSibling")) {
update_package_if_needed(n);
emit_buffered_defuns(n);
@@ -2639,6 +2692,12 @@ int ALLEGROCL::functionWrapper(Node *n) {
Parm *p;
for (i = 0, p = parms; i < num_arguments; i++) {
+#ifdef ALLEGROCL_DEBUG
+ String *temp1 = Getattr(p,"tmap:in");
+ String *temp2 = Getattr(p,"tmap:in:numinputs");
+ Printf(stderr," parm %d: %s, tmap:in='%s', tmap:in:numinputs='%s'\n", i, Getattr(p,"name"), temp1 ? temp1 : "", temp2 ? temp2 : "");
+#endif
+
while (p && checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
}
@@ -2677,6 +2736,10 @@ int ALLEGROCL::functionWrapper(Node *n) {
}
Printf(name_and_parms, ")");
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, " arity = %d(%d)\n", emit_num_lin_arguments(parms), emit_num_lin_arguments(Getattr(n,"wrap:parms")));
+#endif
+
// Emit the function definition
String *signature = SwigType_str(return_type, name_and_parms);
Printf(f->def, "EXPORT %s {", signature);
@@ -2918,6 +2981,7 @@ int ALLEGROCL::variableWrapper(Node *n) {
int ALLEGROCL::memberfunctionHandler(Node *n) {
#ifdef ALLEGROCL_DEBUG
Printf(stderr, "memberfunctionHandler %s::%s\n", Getattr(parent_node_skipping_extends(n), "name"), Getattr(n, "name"));
+ Swig_print_node(n);
#endif
Setattr(n, "allegrocl:kind", "member function");
Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
@@ -3103,7 +3167,8 @@ int ALLEGROCL::cppClassHandler(Node *n) {
SwigType *childType = NewStringf("%s%s", Getattr(c, "decl"),
Getattr(c, "type"));
#ifdef ALLEGROCL_CLASS_DEBUG
- Printf(stderr, "looking at child '%x' of type '%s'\n", c, childType);
+ Printf(stderr, "looking at child '%x' of type '%s' '%d'\n", c, childType, SwigType_isfunction(childType));
+ // Swig_print_node(c);
#endif
if (!SwigType_isfunction(childType))
Delete(compose_foreign_type(n, childType));
From 688ea245600c0154aab7269e9de484776b8badde Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Thu, 23 Jun 2011 16:04:42 +0000
Subject: [PATCH 014/147] [PHP] Fix director code to work when PHP is built
with ZTS enabled, which is the standard configuration on Microsoft Windows.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12749 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 4 ++++
Lib/php/director.swg | 38 ++++++++++++++++++++++++--------------
Source/Modules/php.cxx | 37 +++++++++++++++++++++++++++++++++----
3 files changed, 61 insertions(+), 18 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index 09ac4a022..c152184f3 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.5 (in progress)
===========================
+2011-06-23: olly
+ [PHP] Fix director code to work when PHP is built with ZTS enabled,
+ which is the standard configuration on Microsoft Windows.
+
2011-06-21: mutandiz
[allegrocl]
- various small tweaks and bug fixes.
diff --git a/Lib/php/director.swg b/Lib/php/director.swg
index 218a84e3a..90f6a74a2 100644
--- a/Lib/php/director.swg
+++ b/Lib/php/director.swg
@@ -102,11 +102,17 @@ namespace Swig {
zval *swig_self;
typedef std::map swig_ownership_map;
mutable swig_ownership_map swig_owner;
+#ifdef ZTS
+ // Store the ZTS context so it's available when C++ calls back to PHP.
+ void *** swig_zts_ctx;
+#endif
public:
- Director(zval* self) : swig_self(self) {
+ Director(zval* self TSRMLS_DC) : swig_self(self) {
+ TSRMLS_SET_CTX(swig_zts_ctx);
}
bool swig_is_overridden_method(char *cname, char *lc_fname) {
+ TSRMLS_FETCH_FROM_CTX(swig_zts_ctx);
zend_class_entry **ce;
zend_function *mptr;
int name_len = strlen(lc_fname);
@@ -135,7 +141,7 @@ namespace Swig {
protected:
std::string swig_msg;
public:
- DirectorException(int code, const char *hdr, const char* msg)
+ DirectorException(int code, const char *hdr, const char* msg TSRMLS_DC)
: swig_msg(hdr)
{
if (strlen(msg)) {
@@ -146,9 +152,9 @@ namespace Swig {
SWIG_ErrorMsg() = swig_msg.c_str();
}
- static void raise(int code, const char *hdr, const char* msg)
+ static void raise(int code, const char *hdr, const char* msg TSRMLS_DC)
{
- throw DirectorException(code, hdr, msg);
+ throw DirectorException(code, hdr, msg TSRMLS_CC);
}
};
@@ -156,32 +162,36 @@ namespace Swig {
class DirectorPureVirtualException : public Swig::DirectorException
{
public:
- DirectorPureVirtualException(const char* msg)
- : DirectorException(E_ERROR, "SWIG director pure virtual method called", msg)
- {
+ DirectorPureVirtualException(const char* msg TSRMLS_DC)
+ : DirectorException(E_ERROR, "SWIG director pure virtual method called", msg TSRMLS_CC)
+ {
}
- static void raise(const char *msg)
+ static void raise(const char *msg TSRMLS_DC)
{
- throw DirectorPureVirtualException(msg);
+ throw DirectorPureVirtualException(msg TSRMLS_CC);
}
};
/* any php exception that occurs during a director method call */
class DirectorMethodException : public Swig::DirectorException
{
public:
- DirectorMethodException(const char* msg = "")
- : DirectorException(E_ERROR, "SWIG director method error", msg)
- {
+ DirectorMethodException(const char* msg TSRMLS_DC)
+ : DirectorException(E_ERROR, "SWIG director method error", msg TSRMLS_CC)
+ {
}
- static void raise(const char *msg)
+ static void raise(const char *msg TSRMLS_DC)
{
- throw DirectorMethodException(msg);
+ throw DirectorMethodException(msg TSRMLS_CC);
}
};
}
+// DirectorMethodException() is documented to be callable with no parameters
+// so use a macro to insert TSRMLS_CC so any ZTS context gets passed.
+#define DirectorMethodException() DirectorMethodException("" TSRMLS_CC)
+
#endif /* __cplusplus */
#endif
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index b4af248f5..f6b4d5436 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -182,6 +182,23 @@ static void SwigPHP_emit_resource_registrations() {
}
class PHP : public Language {
+ String *emit_action(Node *n) {
+ // Adjust wrap:action to add TSRMLS_CC.
+ String * action = Getattr(n, "wrap:action");
+ if (action) {
+ char * p = Strstr(action, "Swig::DirectorPureVirtualException::raise(\"");
+ if (p) {
+ p += strlen("Swig::DirectorPureVirtualException::raise(\"");
+ p = strchr(p, '"');
+ if (p) {
+ ++p;
+ Insert(action, p - Char(action), " TSRMLS_CC");
+ }
+ }
+ }
+ return ::emit_action(n);
+ }
+
public:
PHP() {
director_language = 1;
@@ -2237,8 +2254,8 @@ done:
if (i) {
Insert(args, 0, ", ");
}
- Printf(director_ctor_code, "} else {\n result = (%s *)new SwigDirector_%s(arg0%s);\n}\n", ctype, sname, args);
- Printf(director_prot_ctor_code, "} else {\n result = (%s *)new SwigDirector_%s(arg0%s);\n}\n", ctype, sname, args);
+ Printf(director_ctor_code, "} else {\n result = (%s *)new SwigDirector_%s(arg0%s TSRMLS_CC);\n}\n", ctype, sname, args);
+ Printf(director_prot_ctor_code, "} else {\n result = (%s *)new SwigDirector_%s(arg0%s TSRMLS_CC);\n}\n", ctype, sname, args);
Delete(args);
wrapperType = directorconstructor;
@@ -2359,8 +2376,13 @@ done:
String *call;
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+ if (((const char *)Char(target))[Len(target) - 2] == '(') {
+ Insert(target, Len(target) - 1, "TSRMLS_D");
+ } else {
+ Insert(target, Len(target) - 1, " TSRMLS_DC");
+ }
call = Swig_csuperclass_call(0, basetype, superparms);
- Printf(w->def, "%s::%s: %s, Swig::Director(self) {", classname, target, call);
+ Printf(w->def, "%s::%s: %s, Swig::Director(self TSRMLS_CC) {", classname, target, call);
Append(w->def, "}");
Delete(target);
Wrapper_print(w, f_directors);
@@ -2371,6 +2393,11 @@ done:
/* constructor header */
{
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+ if (((const char *)Char(target))[Len(target) - 2] == '(') {
+ Insert(target, Len(target) - 1, "TSRMLS_D");
+ } else {
+ Insert(target, Len(target) - 1, " TSRMLS_DC");
+ }
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
@@ -2474,6 +2501,8 @@ done:
Append(w->def, " {");
Append(declaration, ";\n");
+ Printf(w->code, "TSRMLS_FETCH_FROM_CTX(swig_zts_ctx);\n");
+
/* declare method return value
* if the return value is a reference or const reference, a specialized typemap must
* handle it, including declaration of c_result ($result).
@@ -2494,7 +2523,7 @@ done:
Printf(w->code, "%s;\n", super_call);
Delete(super_call);
} else {
- Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
+ Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\" TSRMLS_CC);\n", SwigType_namestr(c_classname),
SwigType_namestr(name));
}
} else {
From e3b5627ab57bce9df8910adaa550270e38605cb2 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Fri, 24 Jun 2011 17:18:43 +0000
Subject: [PATCH 015/147] Remove example of odd behaviour of PHP constants
which I can't reproduce. It seems highly likely it's been fixed in PHP now,
as the example dates from PHP4 days.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12750 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Doc/Manual/Php.html | 54 ---------------------------------------------
1 file changed, 54 deletions(-)
diff --git a/Doc/Manual/Php.html b/Doc/Manual/Php.html
index 797cb058e..6f00bef28 100644
--- a/Doc/Manual/Php.html
+++ b/Doc/Manual/Php.html
@@ -249,60 +249,6 @@ evaluates to true, rather than the value of the constant which would
be false. This is a feature!