[PHP] Add support for PHP7.

PHP5's C extension API has changed substantially so you need to use
-php7 to specify you want PHP7 compatible wrappers.
Fixes https://github.com/swig/swig/issues/571
This commit is contained in:
Olly Betts 2016-11-30 13:05:59 +13:00
commit 1169874f59
202 changed files with 11575 additions and 719 deletions

View file

@ -5,6 +5,11 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.11 (in progress)
============================
2016-11-30: olly
[PHP] Add support for PHP7. PHP5's C extension API has changed substantially
so you need to use -php7 to specify you want PHP7 compatible wrappers.
Fixes https://github.com/swig/swig/issues/571
2016-11-28: wsfulton
Fix %rename override of wildcard %rename for templates. For example:

View file

@ -49,19 +49,6 @@
<p>
SWIG supports generating wrappers for PHP5. Support for PHP4 was removed
in SWIG 1.3.37. The PHP developers are no longer making new PHP4 releases,
and won't even be patching critical security issues after 2008-08-08, so it
doesn't make much sense for SWIG to continue to support PHP4 now. If you
really need to continue to use PHP4, just stick with SWIG 1.3.36.
</p>
<p>
Currently any PHP5 release should work, but we don't regularly test with
PHP &lt; 5.3.
</p>
<p>
In this chapter, we discuss SWIG's support of PHP. The PHP module
was extensively rewritten in release 1.3.26, and support for generating
@ -70,7 +57,17 @@ of the features available in some of the other languages.
</p>
<p>
In order to use this module, you will need to have a copy of the PHP5
SWIG supports generating wrappers for PHP5 and PHP7. Support for PHP4 was removed
in SWIG 1.3.37.
</p>
<p>
Currently any PHP5 or PHP7 release should work, but we don't regularly test with
PHP &lt; 5.3.
</p>
<p>
In order to use this module, you will need to have a copy of the PHP
include files to compile the SWIG generated files. If you installed
PHP from a binary package, you may need to install a "php-dev" or "php-devel"
package for these to be installed. You can find out where these files are
@ -84,12 +81,13 @@ available.
<p>
To build a PHP extension, run swig using the <tt>-php</tt> option as
follows:
To build a PHP extension, run swig using the <tt>-php5</tt> or
<tt>-php7</tt> option as follows (<tt>-php</tt> is also supported
and currently is an alias for <tt>-php5</tt>):
</p>
<div class="code"><pre>
swig -php example.i
swig -php7 example.i
</pre></div>
<p>
@ -102,7 +100,7 @@ The third file,
<tt>example.php</tt> can be included by PHP scripts. It attempts to
dynamically load the extension and contains extra php code specified
in the interface file. If wrapping C++ code with PHP classes, it will
also contain PHP5 class wrappers.
also contain PHP class wrappers.
</p>
<p>
@ -611,7 +609,7 @@ struct Complex {
</pre></div>
<p>
Would be used in the following way from PHP5:
Would be used in the following way from PHP:
</p>
<div class="code"><pre>
@ -646,7 +644,7 @@ Member variables and methods are accessed using the <tt>-&gt;</tt> operator.
<p>
The <tt>-noproxy</tt> option flattens the object structure and
generates collections of named functions (these are the functions
which the PHP5 class wrappers call). The above example results
which the PHP class wrappers call). The above example results
in the following PHP functions:
</p>

View file

@ -125,7 +125,9 @@ SWIGMZSCHEME Defined when using Mzscheme
SWIGOCAML Defined when using Ocaml
SWIGOCTAVE Defined when using Octave
SWIGPERL Defined when using Perl
SWIGPHP Defined when using PHP
SWIGPHP Defined when using PHP5 or PHP7
SWIGPHP5 Defined when using PHP5
SWIGPHP7 Defined when using PHP7
SWIGPIKE Defined when using Pike
SWIGPYTHON Defined when using Python
SWIGR Defined when using R

View file

@ -131,7 +131,8 @@ can be obtained by typing <tt>swig -help</tt> or <tt>swig
-ocaml Generate Ocaml wrappers
-octave Generate Octave wrappers
-perl Generate Perl wrappers
-php Generate PHP wrappers
-php5 Generate PHP5 wrappers
-php7 Generate PHP7 wrappers
-pike Generate Pike wrappers
-python Generate Python wrappers
-r Generate R (aka GNU S) wrappers

View file

@ -1116,7 +1116,57 @@ ruby_clean:
rm -f *.@OBJEXT@ *$(RUBY_SO)
##################################################################
##### PHP ######
##### PHP5 ######
##################################################################
PHP5 = @PHP5@
PHP5_INCLUDE = @PHP5INC@
PHP5_SO = @PHP5_SO@
PHP5_SCRIPT = $(SRCDIR)$(RUNME).php
# -------------------------------------------------------------------
# Build a PHP5 dynamically loadable module (C)
# -------------------------------------------------------------------
php5: $(SRCDIR_SRCS)
$(SWIG) -php5 $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PHP5_INCLUDE)
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(PHP5_SO)
# --------------------------------------------------------------------
# Build a PHP5 dynamically loadable module (C++)
# --------------------------------------------------------------------
php5_cpp: $(SRCDIR_SRCS)
$(SWIG) -php5 -cppext cxx -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PHP5_INCLUDE)
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(PHP5_SO)
# -----------------------------------------------------------------
# Running a PHP5 example
# -----------------------------------------------------------------
php5_run:
$(RUNTOOL) $(PHP5) -n -q -d extension_dir=. -d safe_mode=Off $(PHP5_SCRIPT) $(RUNPIPE)
# -----------------------------------------------------------------
# Version display
# -----------------------------------------------------------------
php5_version:
$(PHP5) -v | head -n 1
# -----------------------------------------------------------------
# Cleaning the PHP5 examples
# -----------------------------------------------------------------
php5_clean:
rm -f *_wrap* *~ .~* example.php php_example.h
rm -f core @EXTRA_CLEAN@
rm -f *.@OBJEXT@ *$(PHP5_SO)
##################################################################
##### PHP7 ######
##################################################################
PHP = @PHP@
@ -1129,7 +1179,7 @@ PHP_SCRIPT = $(SRCDIR)$(RUNME).php
# -------------------------------------------------------------------
php: $(SRCDIR_SRCS)
$(SWIG) -php $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(SWIG) -php7 $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PHP_INCLUDE)
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO)
@ -1138,7 +1188,7 @@ php: $(SRCDIR_SRCS)
# --------------------------------------------------------------------
php_cpp: $(SRCDIR_SRCS)
$(SWIG) -php -cppext cxx -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(SWIG) -php7 -cppext cxx -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PHP_INCLUDE)
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO)

View file

@ -0,0 +1,19 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS = -lm
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' $(SWIGLIB) CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php5_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_clean

View file

@ -0,0 +1,4 @@
/* File : example.cxx */
#include "example.h"

View file

@ -0,0 +1,22 @@
/* File : example.h */
#include <iostream>
class Callback {
public:
virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; }
virtual void run() { std::cout << "Callback::run()" << std::endl; }
};
class Caller {
private:
Callback *_callback;
public:
Caller(): _callback(0) {}
~Caller() { delCallback(); }
void delCallback() { delete _callback; _callback = 0; }
void setCallback(Callback *cb) { delCallback(); _callback = cb; }
void call() { if (_callback) _callback->run(); }
};

View file

@ -0,0 +1,11 @@
/* File : example.i */
%module(directors="1") example
%{
#include "example.h"
%}
/* turn on director wrapping Callback */
%feature("director") Callback;
%include "example.h"

View file

@ -0,0 +1,19 @@
<html>
<head>
<title>SWIG:Examples:php5:callback</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/php5/callback/</tt>
<hr>
<H2>Implementing C++ callbacks in PHP5</H2>
<p>
This example illustrates how to use directors to implement C++ callbacks in PHP5.
<hr>
</body>
</html>

View file

@ -0,0 +1,47 @@
<?php
# This file illustrates the cross language polymorphism using directors.
require("example.php");
# Class, which overwrites Callback::run().
class PhpCallback extends Callback {
function run() {
print "PhpCallback.run()\n";
}
};
# Create an Caller instance
$caller = new Caller();
# Add a simple C++ callback (caller owns the callback, so
# we disown it first by clearing the .thisown flag).
print "Adding and calling a normal C++ callback\n";
print "----------------------------------------\n";
$callback = new Callback();
$callback->thisown = 0;
$caller->setCallback($callback);
$caller->call();
$caller->delCallback();
print "\n";
print "Adding and calling a PHP callback\n";
print "------------------------------------\n";
# Add a PHP callback.
$callback = new PhpCallback();
$callback->thisown = 0;
$caller->setCallback($callback);
$caller->call();
$caller->delCallback();
# All done.
print "php exit\n";
?>

19
Examples/php5/check.list Normal file
View file

@ -0,0 +1,19 @@
# see top-level Makefile.in
# (see also top-level configure.ac kludge)
callback
class
constants
cpointer
disown
enum
extend
funcptr
overloading
pointer
pragmas
proxy
reference
simple
sync
value
variables

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php5_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_clean

View file

@ -0,0 +1,28 @@
/* File : example.cxx */
#include "example.h"
#define M_PI 3.14159265358979323846
/* Move the shape to a new location */
void Shape::move(double dx, double dy) {
x += dx;
y += dy;
}
int Shape::nshapes = 0;
double Circle::area() {
return M_PI*radius*radius;
}
double Circle::perimeter() {
return 2*M_PI*radius;
}
double Square::area() {
return width*width;
}
double Square::perimeter() {
return 4*width;
}

View file

@ -0,0 +1,34 @@
/* File : example.h */
class Shape {
public:
Shape() {
nshapes++;
}
virtual ~Shape() {
nshapes--;
}
double x, y;
void move(double dx, double dy);
virtual double area() = 0;
virtual double perimeter() = 0;
static int nshapes;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) { }
virtual double area();
virtual double perimeter();
};
class Square : public Shape {
private:
double width;
public:
Square(double w) : width(w) { }
virtual double area();
virtual double perimeter();
};

View file

@ -0,0 +1,9 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Let's just grab the original header file here */
%include "example.h"

View file

@ -0,0 +1,60 @@
<?php
# This example illustrates how member variables are wrapped.
require("example.php");
# ----- Object creation -----
print "Creating some objects:\n";
$c = new Circle(10);
print " Created circle\n";
$s = new Square(10);
print " Created square\n";
# ----- Access a static member -----
print "\nA total of " . Shape::nshapes() . " shapes were created\n";
# ----- Member data access -----
# Set the location of the object.
# Note: methods in the base class Shape are used since
# x and y are defined there.
$c->x = 20;
$c->y = 30;
$s->x = -10;
$s->y = 5;
print "\nHere is their current position:\n";
print " Circle = ({$c->x},{$c->y})\n";
print " Square = ({$s->x},{$s->y})\n";
# ----- Call some methods -----
# Notice how the Shape_area() and Shape_perimeter() functions really
# invoke the appropriate virtual method on each object.
print "\nHere are some properties of the shapes:\n";
foreach (array($c,$s) as $o) {
print " ". get_class($o) . "\n";
print " area = {$o->area()}\n";
print " perimeter = {$o->perimeter()}\n";
}
# ----- Delete everything -----
print "\nGuess I'll clean up now\n";
# Note: this invokes the virtual destructor
$c = NULL;
$s = NULL;
# and don't forget the $o from the for loop above. It still refers to
# the square.
$o = NULL;
print Shape::nshapes() . " shapes remain\n";
print "Goodbye\n";
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS =
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,26 @@
/* File : example.i */
%module example
/* A few preprocessor macros */
#define ICONST 42
#define FCONST 2.1828
#define CCONST 'x'
#define CCONST2 '\n'
#define SCONST "Hello World"
#define SCONST2 "\"Hello World\""
/* This should work just fine */
#define EXPR ICONST + 3*(FCONST)
/* This shouldn't do anything */
#define EXTERN extern
/* Neither should this (BAR isn't defined) */
#define FOO (ICONST + BAR)
/* The following statements also produce constants */
%constant int iconst = 37;
%constant double fconst = 3.14;

View file

@ -0,0 +1,28 @@
<?php
require "example.php";
print "ICONST = " . ICONST . " (should be 42)\n";
print "FCONST = " . FCONST . " (should be 2.1828)\n";
print "CCONST = " . CCONST . " (should be 'x')\n";
print "CCONST2 = " . CCONST2 . " (this should be on a new line)\n";
print "SCONST = " . SCONST . " (should be 'Hello World')\n";
print "SCONST2 = " . SCONST2 . " (should be '\"Hello World\"')\n";
print "EXPR = " . EXPR . " (should be 48.5484)\n";
print "iconst = " . iconst . " (should be 37)\n";
print "fconst = " . fconst . " (should be 3.14)\n";
if (EXTERN!="EXTERN") {
print "EXTERN = " . EXTERN . " (Arg! This shouldn't print anything)\n";
} else {
print "EXTERN defaults to 'EXTERN', it probably isn't defined (good)\n";
}
if (FOO!="FOO") {
print "FOO = " . FOO . "(Arg! This shouldn't print anything)\n";
} else {
print "FOO defaults to 'FOO', it probably isn't defined (good)\n";
}
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS = example.c
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,16 @@
/* File : example.c */
void add(int *x, int *y, int *result) {
*result = *x + *y;
}
void sub(int *x, int *y, int *result) {
*result = *x - *y;
}
int divide(int n, int d, int *r) {
int q;
q = n/d;
*r = n - q*d;
return q;
}

View file

@ -0,0 +1,31 @@
/* File : example.i */
%module example
%{
extern void add(int *, int *, int *);
extern void sub(int *, int *, int *);
%}
/* This example illustrates a couple of different techniques
for manipulating C pointers */
/* First we'll use the pointer library */
extern void add(int *x, int *y, int *result);
%include cpointer.i
%pointer_functions(int, intp);
/* Next we'll use some typemaps */
%include typemaps.i
extern void sub(int *INPUT, int *INPUT, int *OUTPUT);
/* Next we'll use typemaps and the %apply directive */
//%apply int *OUTPUT { int *r };
//extern int divide(int n, int d, int *r);

View file

@ -0,0 +1,47 @@
<?php
require "example.php";
# First create some objects using the pointer library.
print "Testing the pointer library\n";
$a = example::new_intp();
$b = example::new_intp();
$c = example::new_intp();
example::intp_assign($a,37);
example::intp_assign($b,42);
print " a = $a\n";
print " b = $b\n";
print " c = $c\n";
# Call the add() function wuth some pointers
example::add($a,$b,$c);
# Now get the result
$r = example::intp_value($c);
print " 37 + 42 = $r\n";
# Clean up the pointers
example::delete_intp($a);
example::delete_intp($b);
example::delete_intp($c);
# Now try the typemap library
# This should be much easier. Now how it is no longer
# necessary to manufacture pointers.
print "Trying the typemap library\n";
$r = example::sub(37,42);
print " 37 - 42 = $r\n";
# Now try the version with multiple return values
# print "Testing multiple return values\n";
# $a = example::divide(42,37);
# $q = $a[0]
# $r = $a[1]
# print " 42/37 = $q remainder $r\n";
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,51 @@
/* File : example.c */
#include "example.h"
#include <math.h>
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
int Shape::get_nshapes() {
return nshapes;
}
/* Move the shape to a new location */
void Shape::move(double dx, double dy) {
x += dx;
y += dy;
}
int Shape::nshapes = 0;
void Circle::set_radius( double r ) {
radius = r;
}
double Circle::area(void) {
return M_PI*radius*radius;
}
double Circle::perimeter(void) {
return 2*M_PI*radius;
}
double Square::area(void) {
return width*width;
}
double Square::perimeter(void) {
return 4*width;
}
ShapeContainer::~ShapeContainer() {
iterator i=shapes.begin();
for( iterator i = shapes.begin(); i != shapes.end(); ++i ) {
delete *i;
}
}
void
ShapeContainer::addShape( Shape *s ) {
shapes.push_back( s );
}

View file

@ -0,0 +1,50 @@
/* File : example.h */
#include <vector>
class Shape {
public:
Shape() {
nshapes++;
}
virtual ~Shape() {
nshapes--;
}
double x, y;
void move(double dx, double dy);
virtual double area(void) = 0;
virtual double perimeter(void) = 0;
static int nshapes;
static int get_nshapes();
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) { }
~Circle() { }
void set_radius( double r );
virtual double area(void);
virtual double perimeter(void);
};
class Square : public Shape {
private:
double width;
public:
Square(double w) : width(w) { }
~Square() { }
virtual double area(void);
virtual double perimeter(void);
};
class ShapeContainer {
private:
typedef std::vector<Shape*>::iterator iterator;
std::vector<Shape*> shapes;
public:
ShapeContainer() : shapes() {}
~ShapeContainer();
void addShape( Shape *s );
};

View file

@ -0,0 +1,12 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
%apply SWIGTYPE *DISOWN {(Shape *s)};
/* Let's just grab the original header file here */
%include "example.h"

View file

@ -0,0 +1,49 @@
<?php
# This file illustrates the low-level C++ interface
# created by SWIG. In this case, all of our C++ classes
# get converted into function calls.
require("example.php");
# ----- Object creation -----
print "Creating some objects:\n";
$c = new Circle(10);
print " Created circle \$c\n";
$s = new Square(10);
print " Created square \$s\n";
# ----- Create the ShapeContainer ----
$container = new ShapeContainer();
$container->addShape($c);
$container->addShape($s);
# ----- Access a static member -----
print "\nA total of " . Shape::nshapes() . " shapes were created\n";
# ----- Delete by the old references -----
# This should not truely delete the shapes because they are now owned
# by the ShapeContainer.
print "Delete the old references.";
# Note: this invokes the virtual destructor
$c = NULL;
$s = NULL;
print "\nA total of " . Shape::nshapes() . " shapes remain\n";
# ----- Delete by the container -----
# This should truely delete the shapes
print "Delete the container.";
$container = NULL;
print "\nA total of " . Shape::nshapes() . " shapes remain\n";
print "Goodbye\n";
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT = -noproxy
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,37 @@
/* File : example.cxx */
#include "example.h"
#include <stdio.h>
void Foo::enum_test(speed s) {
if (s == IMPULSE) {
printf("IMPULSE speed\n");
} else if (s == WARP) {
printf("WARP speed\n");
} else if (s == LUDICROUS) {
printf("LUDICROUS speed\n");
} else {
printf("Unknown speed\n");
}
}
void enum_test(color c, Foo::speed s) {
if (c == RED) {
printf("color = RED, ");
} else if (c == BLUE) {
printf("color = BLUE, ");
} else if (c == GREEN) {
printf("color = GREEN, ");
} else {
printf("color = Unknown color!, ");
}
if (s == Foo::IMPULSE) {
printf("speed = IMPULSE speed\n");
} else if (s == Foo::WARP) {
printf("speed = WARP speed\n");
} else if (s == Foo::LUDICROUS) {
printf("speed = LUDICROUS speed\n");
} else {
printf("speed = Unknown speed!\n");
}
}

View file

@ -0,0 +1,13 @@
/* File : example.h */
enum color { RED, BLUE, GREEN };
class Foo {
public:
Foo() { }
enum speed { IMPULSE, WARP, LUDICROUS };
void enum_test(speed s);
};
void enum_test(color c, Foo::speed s);

View file

@ -0,0 +1,12 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Let's just grab the original header file here */
%include "example.h"

View file

@ -0,0 +1,32 @@
<?php
require "example.php";
# ----- Object creation -----
# Print out the value of some enums
print "*** color ***";
print " RED =" . RED;
print " BLUE =" . BLUE;
print " GREEN =" . GREEN;
print "\n*** Foo::speed ***";
print " Foo_IMPULSE =" . Foo_IMPULSE;
print " Foo_WARP =" . Foo_WARP;
print " Foo_LUDICROUS =" . Foo_LUDICROUS;
print "\nTesting use of enums with functions\n";
enum_test(RED, Foo_IMPULSE);
enum_test(BLUE, Foo_WARP);
enum_test(GREEN, Foo_LUDICROUS);
enum_test(1234,5678);
print "\nTesting use of enum with class method\n";
$f = new_Foo();
Foo_enum_test($f,Foo_IMPULSE);
Foo_enum_test($f,Foo_WARP);
Foo_enum_test($f,Foo_LUDICROUS);
?>

View file

@ -0,0 +1,19 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS = -lm
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' $(SWIGLIB) CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,4 @@
/* File : example.cxx */
#include "example.h"

View file

@ -0,0 +1,56 @@
/* File : example.h */
#include <cstdio>
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
class Employee {
private:
std::string name;
public:
Employee(const char* n): name(n) {}
virtual std::string getTitle() { return getPosition() + " " + getName(); }
virtual std::string getName() { return name; }
virtual std::string getPosition() const { return "Employee"; }
virtual ~Employee() { printf("~Employee() @ %p\n", (void *)this); }
};
class Manager: public Employee {
public:
Manager(const char* n): Employee(n) {}
virtual std::string getPosition() const { return "Manager"; }
};
class EmployeeList {
std::vector<Employee*> list;
public:
EmployeeList() {
list.push_back(new Employee("Bob"));
list.push_back(new Employee("Jane"));
list.push_back(new Manager("Ted"));
}
void addEmployee(Employee *p) {
list.push_back(p);
std::cout << "New employee added. Current employees are:" << std::endl;
std::vector<Employee*>::iterator i;
for (i=list.begin(); i!=list.end(); i++) {
std::cout << " " << (*i)->getTitle() << std::endl;
}
}
const Employee *get_item(int i) {
return list[i];
}
~EmployeeList() {
std::vector<Employee*>::iterator i;
std::cout << "~EmployeeList, deleting " << list.size() << " employees." << std::endl;
for (i=list.begin(); i!=list.end(); i++) {
delete *i;
}
std::cout << "~EmployeeList empty." << std::endl;
}
};

View file

@ -0,0 +1,15 @@
/* File : example.i */
%module(directors="1") example
%{
#include "example.h"
%}
%include "std_vector.i"
%include "std_string.i"
/* turn on director wrapping for Manager */
%feature("director") Employee;
%feature("director") Manager;
%include "example.h"

View file

@ -0,0 +1,19 @@
<html>
<head>
<title>SWIG:Examples:php:extend</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/php/extend/</tt>
<hr>
<H2>Extending a simple C++ class in PHP</H2>
<p>
This example illustrates the extending of a C++ class with cross language polymorphism.
<hr>
</body>
</html>

View file

@ -0,0 +1,76 @@
<?php
# This file illustrates the cross language polymorphism using directors.
require("example.php");
# CEO class, which overrides Employee::getPosition().
class CEO extends Manager {
function getPosition() {
return "CEO";
}
}
# Create an instance of our employee extension class, CEO. The calls to
# getName() and getPosition() are standard, the call to getTitle() uses
# the director wrappers to call CEO.getPosition.
$e = new CEO("Alice");
print $e->getName() . " is a " . $e->getPosition() . "\n";
printf("Just call her \"%s\"\n", $e->getTitle());
print "----------------------\n";
# Create a new EmployeeList instance. This class does not have a C++
# director wrapper, but can be used freely with other classes that do.
$list = new EmployeeList();
# EmployeeList owns its items, so we must surrender ownership of objects
# we add. This involves first clearing the ->disown member to tell the
# C++ director to start reference counting.
$e->thisown = 0;
$list->addEmployee($e);
print "----------------------\n";
# Now we access the first four items in list (three are C++ objects that
# EmployeeList's constructor adds, the last is our CEO). The virtual
# methods of all these instances are treated the same. For items 0, 1, and
# 2, both all methods resolve in C++. For item 3, our CEO, getTitle calls
# getPosition which resolves in PHP. The call to getPosition is
# slightly different, however, from the e.getPosition() call above, since
# now the object reference has been "laundered" by passing through
# EmployeeList as an Employee*. Previously, PHP resolved the call
# immediately in CEO, but now PHP thinks the object is an instance of
# class Employee (actually EmployeePtr). So the call passes through the
# Employee proxy class and on to the C wrappers and C++ director,
# eventually ending up back at the CEO implementation of getPosition().
# The call to getTitle() for item 3 runs the C++ Employee::getTitle()
# method, which in turn calls getPosition(). This virtual method call
# passes down through the C++ director class to the PHP implementation
# in CEO. All this routing takes place transparently.
print "(position, title) for items 0-3:\n";
printf(" %s, \"%s\"\n", $list->get_item(0)->getPosition(), $list->get_item(0)->getTitle());
printf(" %s, \"%s\"\n", $list->get_item(1)->getPosition(), $list->get_item(1)->getTitle());
printf(" %s, \"%s\"\n", $list->get_item(2)->getPosition(), $list->get_item(2)->getTitle());
printf(" %s, \"%s\"\n", $list->get_item(3)->getPosition(), $list->get_item(3)->getTitle());
print "----------------------\n";
# Time to delete the EmployeeList, which will delete all the Employee*
# items it contains. The last item is our CEO, which gets destroyed as its
# reference count goes to zero. The PHP destructor runs, and is still
# able to call the getName() method since the underlying C++ object still
# exists. After this destructor runs the remaining C++ destructors run as
# usual to destroy the object.
unset($list);
print "----------------------\n";
# All done.
print "php exit\n";
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS = example.c
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,17 @@
/* File : example.c */
int do_op(int a, int b, int (*op)(int,int)) {
return (*op)(a,b);
}
int add(int a, int b) {
return a+b;
}
int sub(int a, int b) {
return a-b;
}
int mul(int a, int b) {
return a*b;
}

View file

@ -0,0 +1,7 @@
/* file: example.h */
extern int do_op(int,int, int (*op)(int,int));
extern int add(int,int);
extern int sub(int,int);
extern int mul(int,int);

View file

@ -0,0 +1,15 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Wrap a function taking a pointer to a function */
extern int do_op(int a, int b, int (*op)(int, int));
/* Now install a bunch of "ops" as constants */
%constant int (*ADD)(int,int) = add;
%constant int (*SUB)(int,int) = sub;
%constant int (*MUL)(int,int) = mul;

View file

@ -0,0 +1,24 @@
<?php
require "example.php";
$a = 37;
$b = 42;
# Now call our C function with a bunch of callbacks
print "Trying some C callback functions\n";
print " a = $a\n";
print " b = $b\n";
print " ADD(a,b) = ". do_op($a,$b,ADD)."\n";
print " SUB(a,b) = ". do_op($a,$b,SUB)."\n";
print " MUL(a,b) = ". do_op($a,$b,MUL)."\n";
print "Here is what the C callback function objects look like in php\n";
print "Using swig style string pointers as we need them registered as constants\n";
print " ADD = " . ADD . "\n";
print " SUB = " . SUB . "\n";
print " MUL = " . MUL . "\n";
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,55 @@
/* File : example.c */
#include "example.h"
#include <math.h>
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
int Shape::get_nshapes() {
return nshapes;
}
/* Move the shape to a new location */
void Shape::move(double dx, double dy) {
x += dx;
y += dy;
}
int Shape::nshapes = 0;
double Circle::area(void) {
return M_PI*radius*radius;
}
double Circle::perimeter(void) {
return 2*M_PI*radius;
}
double Square::area(void) {
return width*width;
}
double Square::perimeter(void) {
return 4*width;
}
const char *overloaded(int i) {
return "Overloaded with int";
}
const char *overloaded(double d) {
return "Overloaded with double";
}
const char *overloaded(const char * str) {
return "Overloaded with char *";
}
const char *overloaded( const Circle& ) {
return "Overloaded with Circle";
}
const char *overloaded( const Shape& ) {
return "Overloaded with Shape";
}

View file

@ -0,0 +1,46 @@
/* File : example.h */
#include <stdio.h>
class Shape {
public:
Shape() {
nshapes++;
}
virtual ~Shape() {
nshapes--;
}
double x, y;
void move(double dx, double dy);
virtual double area(void) = 0;
virtual double perimeter(void) = 0;
static int nshapes;
static int get_nshapes();
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) { }
~Circle() { }
virtual double area(void);
virtual double perimeter(void);
};
class Square : public Shape {
private:
double width;
public:
Square(double w) : width(w) { }
~Square() { }
virtual double area(void);
virtual double perimeter(void);
};
const char *overloaded( int i );
const char *overloaded( double d );
const char *overloaded( const char * str );
const char *overloaded( const Circle& );
const char *overloaded( const Shape& );

View file

@ -0,0 +1,8 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
%include "example.h"

View file

@ -0,0 +1,58 @@
<?php
# This file illustrates the low-level C++ interface
# created by SWIG. In this case, all of our C++ classes
# get converted into function calls.
include("example.php");
# ----- Object creation -----
print "Creating some objects:\n";
$c = new Circle(10);
print " Created circle \$c\n";
$s = new Square(10);
print " Created square \$s\n";
# ----- Access a static member -----
print "\nA total of " . Shape::nshapes() . " shapes were created\n";
# ----- Member data access -----
# Set the location of the object.
# Note: methods in the base class Shape are used since
# x and y are defined there.
$c->x = 20;
$c->y = 30;
$s->x = -10;
$s->y = 5;
print "\nHere is their current position:\n";
print " Circle = (" . $c->x . "," . $c->y . ")\n";
print " Square = (" . $s->x . "," . $s->y . ")\n";
# ----- Call some methods -----
print "\nCall some overloaded methods:\n";
foreach (array(1, 2.1, "quick brown fox", $c, $s) as $o) {
print " overloaded = " . overloaded($o) . "\n";
}
# Need to unset($o) or else we hang on to a reference to the Square object.
unset($o);
# ----- Delete everything -----
print "\nGuess I'll clean up now\n";
# Note: this invokes the virtual destructor
unset($c);
$s = 42;
print Shape::nshapes() . " shapes remain\n";
print "Goodbye\n";
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS = example.c
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,16 @@
/* File : example.c */
void add(double *x, double *y, double *result) {
*result = *x + *y;
}
void sub(int *x, int *y, int *result) {
*result = *x - *y;
}
int divide(int n, int d, int *r) {
int q;
q = n/d;
*r = n - q*d;
return q;
}

View file

@ -0,0 +1,30 @@
/* File : example.i */
%module example
%{
extern void add(double *, double *, double *);
extern void sub(int *, int *, int *);
extern int divide(int, int, int *);
%}
/* This example illustrates a couple of different techniques
for manipulating C pointers */
%include phppointers.i
/* First we'll use the pointer library */
extern void add(double *REF, double *REF, double *REF);
/* Next we'll use some typemaps */
%include typemaps.i
extern void sub(int *INPUT, int *INPUT, int *OUTPUT);
/* Next we'll use typemaps and the %apply directive */
//%apply int *OUTPUT { int *r };
//extern int divide(int n, int d, int *r);

View file

@ -0,0 +1,35 @@
<?php
require "example.php";
# First create some objects using the pointer library.
print "Testing the pointer library\n";
$a = 37.145;
$b = 42.555;
$c = ""; // $c must be defined and not null.
print " a = $a\n";
print " b = $b\n";
print " c = $c\n";
# Call the add() function wuth some pointers
add($a,$b,$c);
print " $a + $b = $c\n";
# Now try the typemap library
# This should be much easier. Now how it is no longer
# necessary to manufacture pointers.
print "Trying the typemap library\n";
$r = sub(37,42);
print " 37 - 42 = $r\n";
# Now try the version with multiple return values
# print "Testing multiple return values\n";
# ($q,$r) = divide(42,37);
# print " 42/37 = $q remainder $r\n";
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS =
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,31 @@
/* File : example.i */
%module example
%init{
zend_printf("This was %%init\n");
}
%minit{
zend_printf("This was %%minit\n");
}
%mshutdown{
zend_printf("This was %%shutdown\n");
}
%rinit{
zend_printf("This was %%rinit\n");
}
%rshutdown{
zend_printf("This was %%rshutdown\n");
}
%pragma(php) include="include.php";
%pragma(php) code="
# This code is inserted into example.php
echo \"this was php code\\n\";
"
%pragma(php) phpinfo="php_info_print_table_start();"

View file

@ -0,0 +1,7 @@
<?php
# This code is inserted into example.php
echo "this is include.php\n";
?>

View file

@ -0,0 +1,5 @@
<?php
require "example.php";
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,43 @@
/* File : example.c */
#include "example.h"
#include <math.h>
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
int Shape::get_nshapes() {
return nshapes;
}
/* Move the shape to a new location */
void Shape::move(double dx, double dy) {
x += dx;
y += dy;
}
int Shape::nshapes = 0;
void Circle::set_radius( double r ) {
radius = r;
}
double Circle::area(void) {
return M_PI*radius*radius;
}
double Circle::perimeter(void) {
return 2*M_PI*radius;
}
double Square::area(void) {
return width*width;
}
double Square::perimeter(void) {
return 4*width;
}
Circle *CircleFactory( double r ) {
return new Circle(r);
}

View file

@ -0,0 +1,43 @@
/* File : example.h */
#include <stdio.h>
class Shape {
public:
Shape() {
nshapes++;
}
virtual ~Shape() {
nshapes--;
}
double x, y;
void move(double dx, double dy);
virtual double area(void) = 0;
virtual double perimeter(void) = 0;
static int nshapes;
static int get_nshapes();
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) { }
~Circle() { }
void set_radius( double r );
virtual double area(void);
virtual double perimeter(void);
};
class Square : public Shape {
private:
double width;
public:
Square(double w) : width(w) { }
~Square() { }
virtual double area(void);
virtual double perimeter(void);
};
Circle *CircleFactory( double r );

View file

@ -0,0 +1,12 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Let's just grab the original header file here */
%newobject CircleFactory;
%include "example.h"

View file

@ -0,0 +1,68 @@
<?php
# This file illustrates the low-level C++ interface
# created by SWIG. In this case, all of our C++ classes
# get converted into function calls.
include("example.php");
# ----- Object creation -----
print "Creating some objects:\n";
$c = example::CircleFactory(10);
print " Created circle \$c with area ". $c->area() ."\n";
$s = new Square(10);
print " Created square \$s\n";
# ----- Access a static member -----
print "\nA total of " . Shape::nshapes() . " shapes were created\n";
# ----- Member data access -----
# Set the location of the object.
# Note: methods in the base class Shape are used since
# x and y are defined there.
$c->x = 20;
$c->y = 30;
$s->x = -10;
$s->y = 5;
print "\nHere is their current position:\n";
print " Circle = (" . $c->x . "," . $c->y . ")\n";
print " Square = (" . $s->x . "," . $s->y . ")\n";
# ----- Call some methods -----
print "\nHere are some properties of the shapes:\n";
foreach (array($c,$s) as $o) {
print " ".get_class($o)." \$o\n";
print " x = " . $o->x . "\n";
print " y = " . $o->y . "\n";
print " area = " . $o->area() . "\n";
print " perimeter = " . $o->perimeter() . "\n";
}
# Need to unset($o) or else we hang on to a reference to the Square object.
unset($o);
# ----- Delete everything -----
print "\nGuess I'll clean up now\n";
# Note: this invokes the virtual destructor
unset($c);
$s = 42;
print Shape::nshapes() . " shapes remain\n";
print "Manually setting nshapes\n";
Shape::nshapes(42);
print Shape::get_nshapes() ." == 42\n";
print "Goodbye\n";
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,49 @@
/* File : example.cxx */
/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
# define _CRT_SECURE_NO_DEPRECATE
#endif
#include "example.h"
#include <stdio.h>
#include <stdlib.h>
Vector operator+(const Vector &a, const Vector &b) {
Vector r;
r.x = a.x + b.x;
r.y = a.y + b.y;
r.z = a.z + b.z;
return r;
}
char *Vector::as_string() {
static char temp[512];
sprintf(temp,"Vector %p (%g,%g,%g)", (void *)this, x,y,z);
return temp;
}
VectorArray::VectorArray(int size) {
items = new Vector[size];
maxsize = size;
printf("VectorArray new: self=%p\n", (void *)this);
}
VectorArray::~VectorArray() {
printf("VectorArray delete: self=%p\n", (void *)this);
delete [] items;
}
Vector &VectorArray::operator[](int index) {
printf("VectorArray: read[%d] self=%p\n", index, (void *)this);
if ((index < 0) || (index >= maxsize)) {
printf("Panic! Array index out of bounds.\n");
exit(1);
}
return items[index];
}
int VectorArray::size() {
printf("VectorArray: size %d self=%p\n", maxsize, (void *)this);
return maxsize;
}

View file

@ -0,0 +1,22 @@
/* File : example.h */
class Vector {
private:
double x,y,z;
public:
Vector() : x(0), y(0), z(0) { }
Vector(double x, double y, double z) : x(x), y(y), z(z) { }
friend Vector operator+(const Vector &a, const Vector &b);
char *as_string();
};
class VectorArray {
private:
Vector *items;
int maxsize;
public:
VectorArray(int maxsize);
~VectorArray();
Vector &operator[](int);
int size();
};

View file

@ -0,0 +1,43 @@
/* File : example.i */
/* This file has a few "typical" uses of C++ references. */
%module example
%{
#include "example.h"
%}
class Vector {
public:
Vector(double x, double y, double z);
~Vector();
char *as_string();
};
/* This helper function calls an overloaded operator */
%inline %{
Vector addv(Vector &a, Vector &b) {
return a+b;
}
%}
/* Wrapper around an array of vectors class */
class VectorArray {
public:
VectorArray(int maxsize);
~VectorArray();
int size();
/* This wrapper provides an alternative to the [] operator */
%extend {
Vector &get(int index) {
printf("VectorArray extended get: %p %d\n", (void *)$self, index);
return (*$self)[index];
}
void set(int index, Vector &a) {
(*$self)[index] = a;
}
}
};

View file

@ -0,0 +1,49 @@
<?php
# This file illustrates the manipulation of C++ references in PHP.
require "example.php";
# ----- Object creation -----
print "Creating some objects:\n";
$a = new Vector(3, 4, 5);
$b = new Vector(10, 11, 12);
print " Created a: {$a->as_string()}\n";
print " Created b: {$b->as_string()}\n";
# ----- Call an overloaded operator -----
# This calls the wrapper we placed around
#
# operator+(const Vector &a, const Vector &)
#
# It returns a new allocated object.
print "Adding a+b\n";
$c = example::addv($a, $b);
print " a+b ={$c->as_string()}\n";
# ----- Create a vector array -----
print "Creating an array of vectors\n";
$va = new VectorArray(10);
print " va: size={$va->size()}\n";
# ----- Set some values in the array -----
# These operators copy the value of $a and $b to the vector array
$va->set(0, $a);
$va->set(1, $b);
$va->set(2, addv($a, $b));
# Get some values from the array
print "Getting some array values\n";
for ($i = 0; $i < 5; $i++) {
print " va[$i] = {$va->get($i)->as_string()}\n";
}
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS = example.c
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,23 @@
/* File : example.c */
#include <stdio.h>
/* A global variable */
double Foo = 3.0;
void print_Foo() {
printf("In C, Foo = %f\n",Foo);
}
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}

View file

@ -0,0 +1,8 @@
/* File : example.i */
%module example
%inline %{
extern int gcd(int x, int y);
extern double Foo;
void print_Foo();
%}

View file

@ -0,0 +1,25 @@
<?php
require "example.php";
# Call our gcd() function
$x = "42 aaa";
$y = 105;
$g = gcd($x,$y);
print "The gcd of $x and $y is $g\n";
# Manipulate the Foo global variable
# Output its current value
print "Foo = " . Foo_get() . "\n";
# Change its value
Foo_set(3.1415926);
# See if the change took effect ( this isn't a good example for php, see
# manual for why. )
print "Foo = " . Foo_get() . "\n";
print_Foo();
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,13 @@
#include "example.h"
#include <stdio.h>
int x = 42;
char *s = (char *)"Test";
void Sync::printer(void) {
printf("The value of global s is %s\n", s);
printf("The value of global x is %d\n", x);
printf("The value of class s is %s\n", s);
printf("The value of class x is %d\n", x);
}

View file

@ -0,0 +1,9 @@
extern char *s;
extern int x;
class Sync {
public:
int x;
char *s;
void printer(void);
};

View file

@ -0,0 +1,7 @@
%module example
%{
#include "example.h"
%}
%include "example.h"

View file

@ -0,0 +1,15 @@
<?
// Load module and PHP classes.
include("example.php");
echo "Got new object\n";
echo "Got string $s and value $x \n";
$s = new Sync();
echo "Got new object\n";
$s->printer();
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS = example.c
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT = -noproxy
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,13 @@
/* File : example.c */
#include "example.h"
double dot_product(Vector a, Vector b) {
return (a.x*b.x + a.y*b.y + a.z*b.z);
}
void vector_add(Vector a, Vector b, Vector* result) {
result->x = a.x + b.x;
result->y = a.y + b.y;
result->z = a.z + b.z;
}

View file

@ -0,0 +1,8 @@
/* File : example.h */
typedef struct {
double x, y, z;
} Vector;
double dot_product(Vector a, Vector b);
void vector_add(Vector a, Vector b, Vector* result);

View file

@ -0,0 +1,17 @@
// Tests SWIG's handling of pass-by-value for complex datatypes
%module example
%{
#include "example.h"
%}
%include "example.h"
/* Some helper functions for our interface */
%inline %{
void vector_print(Vector *v) {
printf("Vector %p = (%g, %g, %g)\n", (void *)v, v->x, v->y, v->z);
}
%}

View file

@ -0,0 +1,43 @@
<?php
require "example.php";
$v = new_vector();
vector_x_set($v,1.0);
vector_y_set($v,2.0);
vector_z_set($v,3.0);
$w = new_vector();
vector_x_set($w,10.0);
vector_y_set($w,11.0);
vector_z_set($w,12.0);
echo "I just created the following vector\n";
vector_print($v);
vector_print($w);
echo "\nNow I'm going to compute the dot product\n";
$d = dot_product($v, $w);
echo "dot product = $d (should be 68)\n";
echo "\nNow I'm going to add the vectors together\n";
$r = new_vector();
vector_add($v, $w, $r);
vector_print($r);
echo "The value should be (11,13,15)\n";
echo "\nNow I'm going to clean up the return result\n";
# free($r);
echo "Good\n";
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS = example.c
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,95 @@
/* File : example.c */
/* I'm a file containing some C global variables */
/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
# define _CRT_SECURE_NO_DEPRECATE
#endif
#include <stdio.h>
#include <stdlib.h>
#include "example.h"
int ivar = 0;
short svar = 0;
long lvar = 0;
unsigned int uivar = 0;
unsigned short usvar = 0;
unsigned long ulvar = 0;
signed char scvar = 0;
unsigned char ucvar = 0;
char cvar = 0;
float fvar = 0;
double dvar = 0;
char *strvar = 0;
const char cstrvar[] = "Goodbye";
int *iptrvar = 0;
char name[5] = "Dave";
char path[256] = "/home/beazley";
/* Global variables involving a structure */
Point *ptptr = 0;
Point pt = { 10, 20 };
/* A variable that we will make read-only in the interface */
int status = 1;
/* A debugging function to print out their values */
void print_vars() {
printf("ivar = %d\n", ivar);
printf("svar = %d\n", svar);
printf("lvar = %ld\n", lvar);
printf("uivar = %u\n", uivar);
printf("usvar = %u\n", usvar);
printf("ulvar = %lu\n", ulvar);
printf("scvar = %d\n", scvar);
printf("ucvar = %u\n", ucvar);
printf("fvar = %g\n", fvar);
printf("dvar = %g\n", dvar);
printf("cvar = %c\n", cvar);
printf("strvar = %s\n", strvar ? strvar : "(null)");
printf("cstrvar = %s\n", cstrvar);
printf("iptrvar = %p\n", (void *)iptrvar);
printf("name = %c%c%c%c%c\n", name[0],name[1],name[2],name[3],name[4]);
printf("ptptr = %p %s\n", (void *)ptptr, Point_print( ptptr ) );
printf("pt = (%d, %d)\n", pt.x, pt.y);
printf("status = %d\n", status);
}
/* A function to create an integer (to test iptrvar) */
int *new_int(int value) {
int *ip = (int *) malloc(sizeof(int));
*ip = value;
return ip;
}
int value_int(int *value) {
return *value;
}
/* A function to create a point */
Point *new_Point(int x, int y) {
Point *p = (Point *) malloc(sizeof(Point));
p->x = x;
p->y = y;
return p;
}
char * Point_print(Point *p) {
static char buffer[256];
if (p) {
sprintf(buffer,"(%d,%d)", p->x,p->y);
} else {
sprintf(buffer,"null");
}
return buffer;
}
void pt_print() {
printf("(%d, %d)\n", pt.x, pt.y);
}

View file

@ -0,0 +1,34 @@
/* File: example.h */
typedef struct {
int x,y;
} Point;
/* Some global variable declarations */
extern int ivar;
extern short svar;
extern long lvar;
extern unsigned int uivar;
extern unsigned short usvar;
extern unsigned long ulvar;
extern signed char scvar;
extern unsigned char ucvar;
extern char cvar;
extern float fvar;
extern double dvar;
extern char *strvar;
extern const char cstrvar[];
extern int *iptrvar;
extern char name[5];
extern Point *ptptr;
extern Point pt;
extern int status;
extern char path[256];
extern void print_vars();
extern int *new_int(int value);
extern Point *new_Point(int x, int y);
extern char *Point_print(Point *p);
extern void pt_print();

View file

@ -0,0 +1,44 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Some global variable declarations */
extern int ivar;
extern short svar;
extern long lvar;
extern unsigned int uivar;
extern unsigned short usvar;
extern unsigned long ulvar;
extern signed char scvar;
extern unsigned char ucvar;
extern char cvar;
extern float fvar;
extern double dvar;
extern char *strvar;
extern const char cstrvar[];
extern int *iptrvar;
extern char name[5];
extern Point *ptptr;
extern Point pt;
/* Some read-only variables */
%immutable;
extern int status;
extern char path[256];
%mutable;
/* Some helper functions to make it easier to test */
extern void print_vars();
extern int *new_int(int value);
extern Point *new_Point(int x, int y);
extern char *Point_print(Point *p);
extern void pt_print();

View file

@ -0,0 +1,96 @@
<?php
require "example.php";
echo "\nVariables (values printed from C)\n";
print_vars();
echo "Variables (values printed from PHP)\n";
echo "ivar = ".ivar_get()."\n";
echo "svar = ".svar_get()."\n";
echo "lvar = ".lvar_get()."\n";
echo "uivar = ".uivar_get()."\n";
echo "usvar = ".usvar_get()."\n";
echo "ulvar = ".ulvar_get()."\n";
echo "scvar = ".scvar_get()."\n";
echo "ucvar = ".ucvar_get()."\n";
echo "cvar = ".cvar_get()."\n";
echo "fvar = ".fvar_get()."\n";
echo "dvar = ".dvar_get()."\n";
echo "strvar = ".strvar_get()."\n";
echo "cstrvar = ".cstrvar_get()."\n";
echo "iptrvar = ".iptrvar_get()."\n";
echo "name = \"".name_get()."\"\n";
echo "ptptr = ".ptptr_get() , point_print(ptptr_get()) , "\n";
echo "pt = ".pt_get(), point_print(pt_get()) , "\n";
/* Try to set the values of some global variables */
$a = "42.14";
ivar_set($a);
echo "a = $a\n";
svar_set(-31000);
lvar_set(65537);
uivar_set(123456);
usvar_set(61000);
ulvar_set(654321);
scvar_set(-13);
ucvar_set(251);
cvar_set("S");
fvar_set(3.14159);
dvar_set(2.1828);
strvar_set("Hello World");
iptrvar_set(new_int(37));
ptptr_set(new_point(37,42));
name_set("B");
echo "Variables (values printed from PHP)\n";
echo "ivar = ".ivar_get()."\n";
echo "svar = ".svar_get()."\n";
echo "lvar = ".lvar_get()."\n";
echo "uivar = ".uivar_get()."\n";
echo "usvar = ".usvar_get()."\n";
echo "ulvar = ".ulvar_get()."\n";
echo "scvar = ".scvar_get()."\n";
echo "ucvar = ".ucvar_get()."\n";
echo "cvar = ".cvar_get()."\n";
echo "fvar = ".fvar_get()."\n";
echo "dvar = ".dvar_get()."\n";
echo "strvar = ".strvar_get()."\n";
echo "cstrvar = ".cstrvar_get()."\n";
echo "iptrvar = ".iptrvar_get()."\n";
echo "name = ".name_get()."\n";
echo "ptptr = ".ptptr_get() , point_print(ptptr_get()) , "\n";
echo "pt = ".pt_get(), point_print(pt_get()) , "\n";
echo "\nVariables (values printed from C)\n";
print_vars();
echo "\nI'm going to try and update a structure variable.\n";
pt_set(ptptr_get());
echo "The new value is \n";
pt_print();
echo "You should see the value", point_print(ptptr_get()), "\n";
echo "\nNow I'm going to try and modify some read only variables\n";
echo "Trying to set 'path'\n";
//path_set("Whoa!");
echo "Path = ".path_get()."\n";
echo "Trying to set 'status'\n";
/* And this */
//status_set(0);
echo "Status = ".status_get()."\n";
?>

View file

@ -3,7 +3,8 @@
require "tests.php";
require "director_thread.php";
# Fails in a ZTS-build of PHP - see: https://github.com/swig/swig/pull/155
# Fails in a ZTS-build of PHP5 - see: https://github.com/swig/swig/pull/155
# FIXME: Does this still fail in a threaded build of PHP7?
exit(0);
// No new functions

View file

@ -0,0 +1,79 @@
#######################################################################
# Makefile for php5 test-suite
#######################################################################
LANGUAGE = php5
SCRIPTSUFFIX = _runme.php
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
CPP_TEST_CASES += \
callback \
php_iterator \
php_namewarn_rename \
include $(srcdir)/../common.mk
# Overridden variables here
TARGETPREFIX =# Should be php_ for Windows, empty otherwise
# Custom tests - tests with additional commandline options
prefix.cpptest: SWIGOPT += -prefix Project
# write out tests without a _runme.php
missingcpptests:
for test in $(CPP_TEST_CASES) ; do test -f $${test}_runme.php || echo $${test}; done
missingctests:
for test in $(C_TEST_CASES) ; do test -f $${test}_runme.php || echo $${test}; done
missingtests: missingcpptests missingctests
# Rules for the different types of tests
%.cpptest:
$(setup)
+$(swig_and_compile_cpp)
+$(run_testcase)
%.ctest:
$(setup)
+$(swig_and_compile_c)
+$(run_testcase)
%.multicpptest:
$(setup)
+$(swig_and_compile_multi_cpp)
+$(run_testcase)
# Smart target
%.test:
@echo ' $(C_TEST_CASES) '|grep -F -v ' $* ' >/dev/null ||\
$(MAKE) $*.ctest
@echo ' $(CPP_TEST_CASES) '|grep -F -v ' $* ' >/dev/null ||\
$(MAKE) $*.cpptest
@echo ' $(MULTI_CPP_TEST_CASES) '|grep -F -v ' $* ' >/dev/null ||\
$(MAKE) $*.multicpptest
# Runs the testcase. Tries to run testcase_runme.php, and if that's not
# found, runs testcase.php, except for multicpptests.
run_testcase = \
if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP5_SCRIPT=$(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) RUNTOOL='$(RUNTOOL)' php5_run; \
elif [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*.php -a ! -f $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list ]; then \
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP5_SCRIPT=$(SCRIPTDIR)/$(SCRIPTPREFIX)$*.php RUNTOOL='$(RUNTOOL)' php5_run; \
fi
# Clean: remove the generated .php file
%.clean:
@rm -f $*.php php_$*.h
clean:
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' php5_clean
rm -f clientdata_prop_a.php clientdata_prop_b.php php_clientdata_prop_a.h php_clientdata_prop_b.h
rm -f import_stl_a.php import_stl_b.php php_import_stl_a.h php_import_stl_b.h
rm -f imports_a.php imports_b.php php_imports_a.h php_imports_b.h
rm -f mod_a.php mod_b.php php_mod_a.h php_mod_b.h
rm -f multi_import_a.php multi_import_b.php php_multi_import_a.h php_multi_import_b.h
rm -f packageoption_a.php packageoption_b.php packageoption_c.php php_packageoption_a.h php_packageoption_b.h php_packageoption_c.h

View file

@ -0,0 +1,12 @@
<?php
require "tests.php";
require "abstract_inherit_ok.php";
check::classes(array(Foo,Spam));
$spam=new Spam();
check::equal(0,$spam->blah(),"spam object method");
check::done();
?>

View file

@ -0,0 +1,14 @@
<?php
require "tests.php";
require "abstract_inherit.php";
check::classes(array(Foo,Bar,Spam,NRFilter_i,NRRCFilter_i,NRRCFilterpro_i,NRRCFilterpri_i));
// This constructor attempt should fail as there isn't one
//$spam=new Spam();
//check::equal(0,$spam->blah(),"spam object method");
//check::equal(0,Spam::blah($spam),"spam class method");
check::done();
?>

View file

@ -0,0 +1,22 @@
<?php
require "tests.php";
require "add_link.php";
// No new functions, except the flat functions
check::functions(array(new_foo,foo_blah));
check::classes(array(Foo));
$foo=new foo();
check::is_a($foo,foo);
$foo_blah=$foo->blah();
check::is_a($foo_blah,foo);
//fails, can't be called as a class method, should allow and make it nil?
//$class_foo_blah=foo::blah();
//check::is_a($class_foo_blah,foo);
check::done();
?>

View file

@ -0,0 +1,38 @@
<?php
require "tests.php";
require "argout.php";
check::functions(array(incp,incr,inctr,new_intp,copy_intp,delete_intp,intp_assign,intp_value,voidhandle,handle));
$ip=copy_intp(42);
check::equal(42,incp($ip),"42==incp($ip)");
check::equal(43,intp_value($ip),"43=$ip");
$p=copy_intp(2);
check::equal(2,incp($p),"2==incp($p)");
check::equal(3,intp_value($p),"3==$p");
$r=copy_intp(7);
check::equal(7,incr($r),"7==incr($r)");
check::equal(8,intp_value($r),"8==$r");
$tr=copy_intp(4);
check::equal(4,inctr($tr),"4==incr($tr)");
check::equal(5,intp_value($tr),"5==$tr");
# Check the voidhandle call, first with null
unset($handle);
# FIXME: Call-time pass-by-reference has been deprecated for ages, and was
# removed in PHP 5.4. We need to rework
#voidhandle(&$handle);
#check::resource($handle,"_p_void",'$handle is not _p_void');
#$handledata=handle($handle);
#check::equal($handledata,"Here it is","\$handledata != \"Here it is\"");
unset($handle);
voidhandle($handle);
check::isnull($handle,'$handle not null');
check::done();
?>

View file

@ -0,0 +1,14 @@
<?php
require "tests.php";
require "arrayptr.php";
// No new functions
check::functions(array(foo));
// No new classes
check::classes(array());
// now new vars
check::globals(array());
check::done();
?>

View file

@ -0,0 +1,19 @@
<?php
require "tests.php";
require "arrays_global.php";
check::functions(array(test_a,test_b,new_simplestruct,new_material));
check::classes(array(arrays_global,SimpleStruct,Material));
check::globals(array(array_c,array_sc,array_uc,array_s,array_us,array_i,array_ui,array_l,array_ul,array_ll,array_f,array_d,array_struct,array_structpointers,array_ipointers,array_enum,array_enumpointers,array_const_i,beginstring_fix44a,beginstring_fix44b,beginstring_fix44c,beginstring_fix44d,beginstring_fix44e,beginstring_fix44f,chitmat,hitmat_val,hitmat,simplestruct_double_field));
// The size of array_c is 2, but the last byte is \0, so we can only store a
// single byte string in it.
check::set(array_c,"Z");
check::equal("Z",check::get(array_c),"set array_c");
check::set(array_c,"xy");
check::equal("x",check::get(array_c),"set array_c");
check::set(array_c,"h");
check::equal("h",check::get(array_c),"set array_c");
check::done();
?>

View file

@ -0,0 +1,22 @@
<?php
require "tests.php";
require "arrays_global_twodim.php";
check::functions(array(fn_taking_arrays,get_2d_array,new_simplestruct,new_material));
check::classes(array(arrays_global_twodim,SimpleStruct,Material));
check::globals(array(array_c,array_sc,array_uc,array_s,array_us,array_i,array_ui,array_l,array_ul,array_ll,array_f,array_d,array_struct,array_structpointers,array_ipointers,array_enum,array_enumpointers,array_const_i,chitmat,hitmat_val,hitmat,simplestruct_double_field));
$a1=array(10,11,12,13);
$a2=array(14,15,16,17);
$a=array($a1,$a2);
$_a=check::get(array_const_i);
for($x=0;$x<count($a1);$x++) {
for($y=0;$y<2;$y++) {
check::equal($a[$y][$x],get_2d_array($_a,$y,$x),"check array $x,$y");
}
}
check::done();
?>

View file

@ -0,0 +1,18 @@
<?php
require "tests.php";
require "arrays.php";
check::functions(array(fn_taking_arrays,newintpointer,setintfrompointer,getintfrompointer,array_pointer_func));
check::classes(array(arrays,SimpleStruct,ArrayStruct,CartPoseData_t));
check::globals(array(simplestruct_double_field,arraystruct_array_c,arraystruct_array_sc,arraystruct_array_uc,arraystruct_array_s,arraystruct_array_us,arraystruct_array_i,arraystruct_array_ui,arraystruct_array_l,arraystruct_array_ul,arraystruct_array_ll,arraystruct_array_f,arraystruct_array_d,arraystruct_array_struct,arraystruct_array_structpointers,arraystruct_array_ipointers,arraystruct_array_enum,arraystruct_array_enumpointers,arraystruct_array_const_i,cartposedata_t_p));
$ss=new simplestruct();
check::classname(simplestruct,$ss);
$as=new arraystruct();
$as->array_c="abc";
check::equal($as->array_c,"a",'$as->array_c=="a"');
check::equal(isset($as->array_const_i),TRUE,'isset($as->array_const_i)');
check::done();
?>

View file

@ -0,0 +1,16 @@
<?php
require "tests.php";
require "arrays_scope.php";
// New functions
check::functions(array(new_bar,bar_blah));
// New classes
check::classes(array(arrays_scope,Bar));
// New vars
check::globals(array(bar_adata,bar_bdata,bar_cdata));
$bar=new bar();
check::done();
?>

View file

@ -0,0 +1,9 @@
<?php
require "tests.php";
require "callback.php";
// In 2.0.6 and earlier, the constant was misnamed.
if (gettype(callback::FOO_I_Cb_Ptr) !== 'resource') die("callback::FOO_I_Cb_Ptr not a resource\n");
check::done();
?>

View file

@ -0,0 +1,18 @@
<?php
require "tests.php";
require "casts.php";
// No new functions
check::functions(array(new_a,a_hello,new_b));
// No new classes
check::classes(array(A,B));
// now new vars
check::globals(array());
# Make sure $b inherites hello() from class A
$b=new B();
$b->hello();
check::done();
?>

Some files were not shown because too many files have changed in this diff Show more