Merge branch 'master' into gsoc2017-php7-classes-via-c-api
This commit is contained in:
commit
2ba0f82720
16 changed files with 111 additions and 65 deletions
|
|
@ -7,6 +7,14 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
|||
Version 4.1.0 (in progress)
|
||||
===========================
|
||||
|
||||
2021-03-26: olly
|
||||
[PHP] Add PHP keywords 'fn' (added in 7.4) and 'match' (added in
|
||||
8.0) to the list SWIG knows to automatically rename.
|
||||
|
||||
2021-03-23: wsfulton
|
||||
#1942 [Python] Fix compilation error in wrappers when using -builtin
|
||||
and wrapping varargs in constructors.
|
||||
|
||||
2021-03-22: goto40
|
||||
#1977 Fix handling of template template parameters.
|
||||
|
||||
|
|
|
|||
|
|
@ -126,3 +126,21 @@ struct Extending2 {};
|
|||
struct ExtendingOptArgs1 {};
|
||||
struct ExtendingOptArgs2 {};
|
||||
%}
|
||||
|
||||
// Varargs
|
||||
%warnfilter(SWIGWARN_LANG_VARARGS_KEYWORD) VarargConstructor::VarargConstructor; // Can't wrap varargs with keyword arguments enabled
|
||||
%warnfilter(SWIGWARN_LANG_VARARGS_KEYWORD) VarargConstructor::vararg_method; // Can't wrap varargs with keyword arguments enabled
|
||||
%inline %{
|
||||
struct VarargConstructor {
|
||||
char *str;
|
||||
VarargConstructor(const char *fmt, ...) {
|
||||
str = new char[strlen(fmt) + 1];
|
||||
strcpy(str, fmt);
|
||||
}
|
||||
void vararg_method(const char *fmt, ...) {
|
||||
delete [] str;
|
||||
str = new char[strlen(fmt) + 1];
|
||||
strcpy(str, fmt);
|
||||
}
|
||||
};
|
||||
%}
|
||||
|
|
|
|||
|
|
@ -122,3 +122,18 @@ try:
|
|||
raise RuntimeError("missed exception")
|
||||
except TypeError as e:
|
||||
pass
|
||||
|
||||
# Varargs
|
||||
f = VarargConstructor(fmt="Ciao")
|
||||
f.vararg_method(fmt="Bonjour")
|
||||
try:
|
||||
f = VarargConstructor(nonexistent="Ciao")
|
||||
raise RuntimeError("missed exception")
|
||||
except TypeError as e:
|
||||
pass
|
||||
|
||||
try:
|
||||
f.vararg_method(nonexistent="Bonjour")
|
||||
raise RuntimeError("missed exception")
|
||||
except TypeError as e:
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@ import varargs
|
|||
if varargs.test("Hello") != "Hello":
|
||||
raise RuntimeError("Failed")
|
||||
|
||||
vc = varargs.VarargConstructor("Hey there")
|
||||
if vc.str != "Hey there":
|
||||
raise RuntimeError("Failed")
|
||||
|
||||
f = varargs.Foo("Greetings")
|
||||
if f.str != "Greetings":
|
||||
raise RuntimeError("Failed")
|
||||
|
|
|
|||
|
|
@ -1,17 +1,31 @@
|
|||
// Tests SWIG's *default* handling of varargs (function varargs, not preprocessor varargs).
|
||||
// Tests SWIG's handling of varargs (function varargs, not preprocessor varargs).
|
||||
// The default behavior is to simply ignore the varargs.
|
||||
%module varargs
|
||||
|
||||
// Default handling of varargs
|
||||
|
||||
%inline %{
|
||||
char *test(const char *fmt, ...) {
|
||||
return (char *) fmt;
|
||||
}
|
||||
|
||||
struct VarargConstructor {
|
||||
char *str;
|
||||
VarargConstructor(const char *fmt, ...) {
|
||||
str = new char[strlen(fmt) + 1];
|
||||
strcpy(str, fmt);
|
||||
}
|
||||
};
|
||||
%}
|
||||
|
||||
// %varargs support
|
||||
|
||||
%varargs(int mode = 0) test_def;
|
||||
%varargs(int mode = 0) Foo::Foo;
|
||||
%varargs(int mode = 0) Foo::statictest(const char*fmt, ...);
|
||||
%varargs(2, int mode = 0) test_plenty(const char*fmt, ...);
|
||||
|
||||
%inline %{
|
||||
char *test(const char *fmt, ...) {
|
||||
return (char *) fmt;
|
||||
}
|
||||
|
||||
const char *test_def(const char *fmt, ...) {
|
||||
return fmt;
|
||||
}
|
||||
|
|
@ -40,5 +54,4 @@ public:
|
|||
const char *test_plenty(const char *fmt, ...) {
|
||||
return fmt;
|
||||
}
|
||||
|
||||
%}
|
||||
|
|
|
|||
|
|
@ -3,41 +3,41 @@
|
|||
you have:
|
||||
|
||||
---- geometry.h --------
|
||||
struct Geometry {
|
||||
enum GeomType{
|
||||
POINT,
|
||||
CIRCLE
|
||||
};
|
||||
|
||||
virtual ~Geometry() {}
|
||||
struct Geometry {
|
||||
enum GeomType{
|
||||
POINT,
|
||||
CIRCLE
|
||||
};
|
||||
|
||||
virtual ~Geometry() {}
|
||||
virtual int draw() = 0;
|
||||
|
||||
|
||||
//
|
||||
// Factory method for all the Geometry objects
|
||||
//
|
||||
static Geometry *create(GeomType i);
|
||||
};
|
||||
|
||||
struct Point : Geometry {
|
||||
int draw() { return 1; }
|
||||
double width() { return 1.0; }
|
||||
};
|
||||
|
||||
struct Circle : Geometry {
|
||||
int draw() { return 2; }
|
||||
double radius() { return 1.5; }
|
||||
};
|
||||
|
||||
static Geometry *create(GeomType i);
|
||||
};
|
||||
|
||||
struct Point : Geometry {
|
||||
int draw() { return 1; }
|
||||
double width() { return 1.0; }
|
||||
};
|
||||
|
||||
struct Circle : Geometry {
|
||||
int draw() { return 2; }
|
||||
double radius() { return 1.5; }
|
||||
};
|
||||
|
||||
//
|
||||
// Factory method for all the Geometry objects
|
||||
//
|
||||
Geometry *Geometry::create(GeomType type) {
|
||||
switch (type) {
|
||||
case POINT: return new Point();
|
||||
case CIRCLE: return new Circle();
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
switch (type) {
|
||||
case POINT: return new Point();
|
||||
case CIRCLE: return new Circle();
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
---- geometry.h --------
|
||||
|
||||
|
||||
|
|
@ -57,16 +57,16 @@
|
|||
|
||||
NOTES: remember to fully qualify all the type names and don't
|
||||
use %factory inside a namespace declaration, ie, instead of
|
||||
|
||||
|
||||
namespace Foo {
|
||||
%factory(Geometry *Geometry::create, Point, Circle);
|
||||
}
|
||||
|
||||
use
|
||||
|
||||
%factory(Foo::Geometry *Foo::Geometry::create, Foo::Point, Foo::Circle);
|
||||
%factory(Foo::Geometry *Foo::Geometry::create, Foo::Point, Foo::Circle);
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/* for loop for macro with one argument */
|
||||
|
|
@ -90,14 +90,14 @@
|
|||
/* for loop for macro with two arguments */
|
||||
%define %formacro_2(macro,...)%_formacro_2(macro, __VA_ARGS__, __fordone__)%enddef
|
||||
|
||||
%define %_factory_dispatch(Type)
|
||||
%define %_factory_dispatch(Type)
|
||||
if (!dcast) {
|
||||
Type *dobj = dynamic_cast<Type *>($1);
|
||||
if (dobj) {
|
||||
dcast = 1;
|
||||
zend_object *std = $descriptor(Type)##_ce->create_object($descriptor(Type)##_ce);
|
||||
SWIG_SetZval(return_value, $needNewFlow, $owner, SWIG_as_voidptr(dobj), $descriptor(Type *), std);
|
||||
}
|
||||
}
|
||||
}%enddef
|
||||
|
||||
%define %factory(Method,Types...)
|
||||
|
|
|
|||
|
|
@ -176,7 +176,8 @@
|
|||
%{
|
||||
if (SWIG_ConvertPtr(&$input, (void **) &$1, 0, 0) < 0) {
|
||||
/* Allow NULL from php for void* */
|
||||
if (Z_ISNULL($input)) $1=0;
|
||||
if (Z_ISNULL($input))
|
||||
$1=0;
|
||||
else
|
||||
SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ PHPKW(endwhile);
|
|||
PHPKW(extends);
|
||||
PHPKW(final);
|
||||
PHPKW(finally);
|
||||
PHPKW(fn); // as of PHP 7.4
|
||||
PHPKW(for);
|
||||
PHPKW(foreach);
|
||||
PHPKW(function);
|
||||
|
|
@ -65,6 +66,7 @@ PHPKW(implements);
|
|||
PHPKW(instanceof);
|
||||
PHPKW(insteadof);
|
||||
PHPKW(interface);
|
||||
PHPKW(match); // as of PHP 8.0
|
||||
PHPKW(namespace);
|
||||
PHPKW(new);
|
||||
PHPKW(or);
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ SWIG_ConvertResourceData(void * p, const char *type_name, swig_type_info *ty) {
|
|||
return p;
|
||||
}
|
||||
|
||||
if (! type_name) {
|
||||
if (! type_name) {
|
||||
/* can't convert p to ptr type ty if we don't know what type p is */
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,3 @@
|
|||
%include <std/std_except.i>
|
||||
|
||||
%apply size_t { std::size_t };
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace std {
|
|||
|
||||
map();
|
||||
map(const map& other);
|
||||
|
||||
|
||||
unsigned int size() const;
|
||||
void clear();
|
||||
%extend {
|
||||
|
|
|
|||
|
|
@ -112,5 +112,3 @@ namespace std {
|
|||
%define specialize_std_vector(T)
|
||||
#warning "specialize_std_vector - specialization for type T no longer needed"
|
||||
%enddef
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,4 +7,3 @@
|
|||
%include <std_vector.i>
|
||||
%include <std_map.i>
|
||||
%include <std_pair.i>
|
||||
|
||||
|
|
|
|||
|
|
@ -24,17 +24,6 @@
|
|||
* value which is a compound C++ expression (i.e. as if we had a
|
||||
* method with two overloaded forms instead of a single method with
|
||||
* a default parameter value).
|
||||
*
|
||||
* Long term:
|
||||
*
|
||||
* Sort out locale-dependent behaviour of strtod() - it's harmless unless
|
||||
* SWIG ever sets the locale and DOH/base.c calls atof, so we're probably
|
||||
* OK currently at least.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO: Replace remaining stderr messages with Swig_error or Swig_warning
|
||||
* (may need to add more WARN_PHP_xxx codes...)
|
||||
*/
|
||||
|
||||
#include "swigmod.h"
|
||||
|
|
@ -1933,8 +1922,6 @@ public:
|
|||
|
||||
arg_names = (String **) malloc(max_num_of_arguments * sizeof(String *));
|
||||
if (!arg_names) {
|
||||
/* FIXME: How should this be handled? The rest of SWIG just seems
|
||||
* to not bother checking for malloc failing! */
|
||||
fprintf(stderr, "Malloc failed!\n");
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
|
@ -1945,8 +1932,6 @@ public:
|
|||
arg_values = (String **) malloc(max_num_of_arguments * sizeof(String *));
|
||||
byref = (unsigned char *) malloc(max_num_of_arguments);
|
||||
if (!arg_values || !byref) {
|
||||
/* FIXME: How should this be handled? The rest of SWIG just seems
|
||||
* to not bother checking for malloc failing! */
|
||||
fprintf(stderr, "Malloc failed!\n");
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
|
@ -2064,7 +2049,6 @@ public:
|
|||
case T_LONGDOUBLE: {
|
||||
char *p;
|
||||
errno = 0;
|
||||
/* FIXME: strtod is locale dependent... */
|
||||
double val = strtod(Char(value), &p);
|
||||
if (errno || *p) {
|
||||
Clear(value);
|
||||
|
|
|
|||
|
|
@ -2753,7 +2753,7 @@ public:
|
|||
if (!varargs) {
|
||||
Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
|
||||
} else {
|
||||
Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *", self_param, ", PyObject *args, PyObject *varargs) {", NIL);
|
||||
Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *", self_param, ", PyObject *args, PyObject *varargs", builtin_kwargs, ") {", NIL);
|
||||
}
|
||||
if (allow_kwargs) {
|
||||
Swig_warning(WARN_LANG_OVERLOAD_KEYWORD, input_file, line_number, "Can't use keyword arguments with overloaded functions (%s).\n", Swig_name_decl(n));
|
||||
|
|
@ -3253,10 +3253,10 @@ public:
|
|||
Printf(f->code, " Py_XINCREF(swig_obj[i + %d]);\n", num_fixed_arguments);
|
||||
Printf(f->code, "}\n");
|
||||
} else {
|
||||
Printf(f->code, "newargs = PyTuple_GetSlice(args,0,%d);\n", num_fixed_arguments);
|
||||
Printf(f->code, "varargs = PyTuple_GetSlice(args,%d,PyTuple_Size(args));\n", num_fixed_arguments);
|
||||
Printf(f->code, "newargs = PyTuple_GetSlice(args, 0, %d);\n", num_fixed_arguments);
|
||||
Printf(f->code, "varargs = PyTuple_GetSlice(args, %d, PyTuple_Size(args));\n", num_fixed_arguments);
|
||||
}
|
||||
Printf(f->code, "resultobj = %s__varargs__(%s,newargs,varargs);\n", wname, builtin ? "self" : "NULL");
|
||||
Printf(f->code, "resultobj = %s__varargs__(%s, newargs, varargs%s);\n", wname, builtin ? "self" : "NULL", strlen(builtin_kwargs) == 0 ? "" : ", kwargs");
|
||||
Append(f->code, "Py_XDECREF(newargs);\n");
|
||||
Append(f->code, "Py_XDECREF(varargs);\n");
|
||||
Append(f->code, "return resultobj;\n");
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ AM_PROG_CC_C_O # Needed for subdir-objects in AUTOMAKE_OPTIONS
|
|||
|
||||
AC_COMPILE_WARNINGS # Increase warning levels
|
||||
|
||||
AC_MSG_CHECKING([CFLAGS to compile SWIG executable])
|
||||
AC_MSG_RESULT([$CFLAGS])
|
||||
AC_MSG_CHECKING([CXXFLAGS to compile SWIG executable])
|
||||
AC_MSG_RESULT([$CXXFLAGS])
|
||||
|
||||
AC_DEFINE_UNQUOTED(SWIG_CXX, ["$CXX"], [Compiler that built SWIG])
|
||||
AC_DEFINE_UNQUOTED(SWIG_PLATFORM, ["$host"], [Platform that SWIG is built for])
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue