summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/argument.h125
-rw-r--r--include/extension.h22
-rw-r--r--include/function.h132
-rw-r--r--include/type.h38
-rw-r--r--include/variable.h134
-rw-r--r--phpcpp.h11
-rw-r--r--src/Makefile2
-rw-r--r--src/arginfo.h97
-rw-r--r--src/argument.cpp60
-rw-r--r--src/callable.cpp87
-rw-r--r--src/callable.h146
-rw-r--r--src/config.m44
-rw-r--r--src/extension.cpp11
-rw-r--r--src/function.cpp49
-rw-r--r--src/functions.h80
-rw-r--r--src/includes.h17
-rw-r--r--tests/simple/Makefile2
-rw-r--r--tests/simple/simple.cpp8
18 files changed, 1014 insertions, 11 deletions
diff --git a/include/argument.h b/include/argument.h
new file mode 100644
index 0000000..862b677
--- /dev/null
+++ b/include/argument.h
@@ -0,0 +1,125 @@
+/**
+ * Argument.h
+ *
+ * Class holds information about an argument that is passed to a function.
+ * You'll need this class when you're defining your own functions.
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace PhpCpp {
+
+/**
+ * Forward definitions
+ */
+class ArgInfo;
+
+/**
+ * Class definition
+ */
+class Argument
+{
+public:
+ /**
+ * Constructor if this argument should be an instance of a certain class
+ * @param name Name of the argument
+ * @param classname If a specific class is required, the class type
+ * @param null Are NULL values allowed in stead of an instance?
+ * @param ref Is this a pass-by-reference argument?
+ */
+ Argument(const std::string &name, const std::string &classname, bool null = true, bool ref = false);
+
+ /**
+ * Constructor if the argument can be anything
+ * @param name Name of the argument
+ * @param type Type hint
+ * @param ref Is this a pass-by-reference argument?
+ */
+ Argument(const std::string &name, Type type = nullType, bool ref = false);
+
+ /**
+ * Copy constructor
+ * @param argument The argument to copy
+ */
+ Argument(const Argument &argument)
+ {
+ // copy members
+ _refcount = argument._refcount;
+ _info = argument._info;
+
+ // increase references
+ (*_refcount)++;
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~Argument()
+ {
+ // cleanup current object
+ cleanup();
+ }
+
+ /**
+ * Copy operator
+ * @param argument The argument to copy
+ * @return Argument
+ */
+ Argument &operator=(const Argument &argument)
+ {
+ // skip self assignment
+ if (this == &argument) return *this;
+
+ // clean up current object
+ cleanup();
+
+ // copy members
+ _refcount = argument._refcount;
+ _info = argument._info;
+
+ // increase references
+ (*_refcount)++;
+
+ // done
+ return *this;
+ }
+
+ /**
+ * Retrieve argument info
+ * @return ArgInfo
+ * @internal
+ */
+ ArgInfo *internal() const
+ {
+ return _info;
+ }
+
+private:
+ /**
+ * Number of references
+ * @var int
+ */
+ int *_refcount;
+
+ /**
+ * Pointer to the implementation
+ * @var ArgInfo
+ */
+ ArgInfo *_info;
+
+ /**
+ * Remove one reference from the object
+ */
+ void cleanup();
+
+};
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/include/extension.h b/include/extension.h
index eb7eb4c..701da86 100644
--- a/include/extension.h
+++ b/include/extension.h
@@ -26,17 +26,23 @@ struct _zend_module_entry;
namespace PhpCpp {
/**
+ * Forward definitions
+ */
+class Functions;
+
+/**
* Class definition
*/
class Extension
{
public:
/**
- * Constructor
+ * Extension that defines a number of functions right away
* @param name Extension name
- * @param version EXtension version
+ * @param version Extension version string
+ * @param functions The functions that are defined
*/
- Extension(const char *name, const char *version);
+ Extension(const char *name, const char *version, const std::initializer_list<Function> &functions = {});
/**
* Destructor
@@ -151,18 +157,24 @@ private:
* @var char*
*/
const char *_version;
+
+ /**
+ * The functions that are defined
+ * @var vector
+ */
+ Functions *_functions;
/**
* The information that is passed to the Zend engine
* @var zend_module_entry
*/
- _zend_module_entry *_entry;
+ _zend_module_entry *_entry = NULL;
/**
* The current request being processed
* @var Request
*/
- Request *_request;
+ Request *_request = NULL;
};
diff --git a/include/function.h b/include/function.h
new file mode 100644
index 0000000..1a35671
--- /dev/null
+++ b/include/function.h
@@ -0,0 +1,132 @@
+/**
+ * Function.h
+ *
+ * Object represents a callable function that is defined with the CPP API.
+ * After you've instantiated the extension, you can add function objects to
+ * it.
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace PhpCpp {
+
+/**
+ * Forward definitions
+ */
+class Callable;
+
+/**
+ * Class definition
+ */
+class Function
+{
+public:
+ /**
+ * Constructor
+ * @param name Name of the function
+ * @param arguments The arguments that can be passed to the function
+ */
+ Function(const std::string &name, const std::initializer_list<Argument> &arguments);
+
+ /**
+ * Constructor
+ * @param name Name of the function
+ */
+ Function(const char *name) : Function(name, {}) {}
+
+ /**
+ * Copy constructor
+ * @param function The other function
+ */
+ Function(const Function &function)
+ {
+ // copy other object
+ _refcount = function._refcount;
+ _callable = function._callable;
+
+ // increate number of references
+ (*_refcount)++;
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~Function()
+ {
+ // cleanup the object
+ cleanup();
+ }
+
+ /**
+ * Assignment operator
+ * @param function The other function
+ * @return Function
+ */
+ Function &operator=(const Function &function)
+ {
+ // skip self assignment
+ if (&function == this) return *this;
+
+ // cleanup the object
+ cleanup();
+
+ // copy other object
+ _refcount = function._refcount;
+ _callable = function._callable;
+
+ // increate number of references
+ (*_refcount)++;
+
+ // done
+ return *this;
+ }
+
+ /**
+ * Method that gets called every time the function is executed
+ * @param request The request during which the call was made
+ * @param arguments The actual arguments that were passed
+ * @return Variable Return value
+ */
+ virtual Variable invoke(const Request *request, const std::initializer_list<Variable> &arguments)
+ {
+ }
+
+ /**
+ * Get access to the internal object
+ * @return Callable
+ * @internal
+ */
+ Callable *internal() const
+ {
+ return _callable;
+ }
+
+protected:
+ /**
+ * Pointer to the callable object
+ * @var smart_ptr
+ */
+ Callable *_callable;
+
+ /**
+ * Counter with the number of references
+ * @var integer
+ */
+ int *_refcount;
+
+
+ /**
+ * Remove one reference
+ */
+ void cleanup();
+};
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/include/type.h b/include/type.h
new file mode 100644
index 0000000..f3e357f
--- /dev/null
+++ b/include/type.h
@@ -0,0 +1,38 @@
+/**
+ * Type.h
+ *
+ * In this file an enumeration type is defined with all supporteded variable
+ * types.
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace PhpCpp {
+
+/**
+ * Supported types for variables
+ * The values are the same as the ones used internally in Zend
+ */
+typedef enum _Type {
+ nullType = 0,
+ intType = 1,
+ decimalType = 2,
+ boolType = 3,
+ arrayType = 4,
+ objectType = 5,
+ stringType = 6,
+ resourceType = 7,
+ constantType = 8,
+ constantArrayType = 9,
+ callableType = 10
+} Type;
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/include/variable.h b/include/variable.h
new file mode 100644
index 0000000..393239f
--- /dev/null
+++ b/include/variable.h
@@ -0,0 +1,134 @@
+/**
+ * Variable.h
+ *
+ * Base class for variables that are stored in the Zend engine.
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace PhpCpp {
+
+/**
+ * Class definition
+ */
+class Variable
+{
+public:
+ /**
+ * Empty constructor (value = NULL)
+ */
+ Variable();
+
+ /**
+ * Constructor based on integer value
+ * @param value
+ */
+ Variable(int value);
+
+ /**
+ * Constructor based on boolean value
+ * @param value
+ */
+ Variable(bool value);
+
+ /**
+ * Constructor based on string value
+ * @param value
+ */
+ Variable(const std::string &value);
+
+ /**
+ * Constructor based on decimal value
+ * @param value
+ */
+ Variable(double value);
+
+ /**
+ * Copy constructor
+ * @param value
+ */
+ Variable(const Variable &that);
+
+ /**
+ * Destructor
+ */
+ virtual ~Variable();
+
+ /**
+ * Assignment operator
+ * @param value
+ * @return Variable
+ */
+ virtual Variable &operator=(const Variable &value);
+
+ /**
+ * Is this an integer value?
+ * @return bool
+ */
+ virtual bool isInt();
+
+ /**
+ * Is this a boolean value?
+ * @return bool
+ */
+ virtual bool isBool();
+
+ /**
+ * Is this a string value?
+ * @return bool
+ */
+ virtual bool isString();
+
+ /**
+ * Is this a decimal value?
+ * @return bool
+ */
+ virtual bool isDecimal();
+
+ /**
+ * Is this an object value?
+ * @return bool
+ */
+ virtual bool isObject();
+
+ /**
+ * Is this an array value?
+ * @return bool
+ */
+ virtual bool isArray();
+
+ /**
+ * Retrieve the value as integer
+ * @return int
+ */
+ virtual int intValue();
+
+ /**
+ * Retrieve the value as boolean
+ * @return bool
+ */
+ virtual bool boolValue();
+
+ /**
+ * Retrieve the value as string
+ * @return string
+ */
+ std::string stringValue();
+
+ /**
+ * Retrieve the value as decimal
+ * @return double
+ */
+ virtual double decimalValue();
+};
+
+/**
+ * End of namespace
+ */
+}
+
+
diff --git a/phpcpp.h b/phpcpp.h
index 104818d..6d85589 100644
--- a/phpcpp.h
+++ b/phpcpp.h
@@ -8,9 +8,20 @@
*/
/**
+ * Other C and C++ libraries that PhpCpp depends on
+ */
+#include <string>
+#include <initializer_list>
+#include <vector>
+
+/**
* Include all headers files that are related to this library
*/
+#include <phpcpp/type.h>
#include <phpcpp/request.h>
+#include <phpcpp/argument.h>
+#include <phpcpp/variable.h>
+#include <phpcpp/function.h>
#include <phpcpp/extension.h>
/**
diff --git a/src/Makefile b/src/Makefile
index 162e7ee..069024d 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,7 +1,7 @@
CPP = g++
RM = rm -f
PHP_DIR = /usr/include/php5
-CPP_FLAGS = -c -I. -I${PHP_DIR} -I${PHP_DIR}/main -I${PHP_DIR}/ext -I${PHP_DIR}/Zend -I${PHP_DIR}/TSRM -O2
+CPP_FLAGS = -c -I. -I${PHP_DIR} -I${PHP_DIR}/main -I${PHP_DIR}/ext -I${PHP_DIR}/Zend -I${PHP_DIR}/TSRM -O2 -std=c++11
LD = g++
LD_FLAGS = -Wall -shared -O2
diff --git a/src/arginfo.h b/src/arginfo.h
new file mode 100644
index 0000000..8ed00c8
--- /dev/null
+++ b/src/arginfo.h
@@ -0,0 +1,97 @@
+/**
+ * ArgInfo.h
+ *
+ * Internal class that wraps the Zend information about an argument
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace PhpCpp {
+
+/**
+ * Class definition
+ */
+class ArgInfo
+{
+public:
+ /**
+ * Constructor if this argument should be an instance of a certain class
+ * @param name Name of the argument
+ * @param classname If a specific class is required, the class type
+ * @param null Are NULL values allowed in stead of an instance?
+ * @param ref Is this a pass-by-reference argument?
+ */
+ ArgInfo(const std::string &name, const std::string &classname, bool null = true, bool ref = false) :
+ _name(name), _classname(name), _type(objectType), _null(null), _ref(ref) {}
+
+ /**
+ * Constructor if this argument can be anything
+ * @param name Name of the argument
+ * @param type Type hint
+ * @param ref Is this a pass-by-reference argument?
+ */
+ ArgInfo(const std::string &name, Type type = nullType, bool ref = false) :
+ _name(name), _type(type), _null(false), _ref(ref) {}
+
+ /**
+ * Destructor
+ */
+ virtual ~ArgInfo() {}
+
+ /**
+ * Fill a zend_arg_info structure
+ * @param info
+ */
+ void fill(zend_arg_info *info)
+ {
+ // fill all members
+ info->name = _name.c_str();
+ info->name_len = _name.size();
+ info->class_name = _classname.size() ? _classname.c_str() : NULL;
+ info->class_name_len = _classname.size();
+ info->type_hint = _type;
+ info->allow_null = _null;
+ info->pass_by_reference = _ref;
+ }
+
+private:
+ /**
+ * The argument name
+ * @var string
+ */
+ std::string _name;
+
+ /**
+ * The class name
+ * @var string
+ */
+ std::string _classname;
+
+ /**
+ * Type of the argument
+ * @var Type
+ */
+ Type _type;
+
+ /**
+ * Can this argument be set to NULL?
+ * @var bool
+ */
+ bool _null;
+
+ /**
+ * Is this a pass-by-reference argument?
+ * @var bool
+ */
+ bool _ref;
+};
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/src/argument.cpp b/src/argument.cpp
new file mode 100644
index 0000000..153da9c
--- /dev/null
+++ b/src/argument.cpp
@@ -0,0 +1,60 @@
+/**
+ * Argument.cpp
+ *
+ * Implementation for the Argument class
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+#include "includes.h"
+
+/**
+ * Set up namespace
+ */
+namespace PhpCpp {
+
+/**
+ * Constructor if this argument should be an instance of a certain class
+ * @param name Name of the argument
+ * @param classname If a specific class is required, the class type
+ * @param null Are NULL values allowed in stead of an instance?
+ * @param ref Is this a pass-by-reference argument?
+ */
+Argument::Argument(const std::string &name, const std::string &classname, bool null, bool ref)
+{
+ _refcount = new int[1];
+ _info = new ArgInfo(name, classname, null, ref);
+}
+
+/**
+ * Constructor if the argument can be anything
+ * @param name Name of the argument
+ * @param type Type hint
+ * @param ref Is this a pass-by-reference argument?
+ */
+Argument::Argument(const std::string &name, Type type, bool ref)
+{
+ _refcount = new int[1];
+ _info = new ArgInfo(name, type, ref);
+}
+
+/**
+ * Clean up the object
+ */
+void Argument::cleanup()
+{
+ // one reference less
+ (*_refcount)--;
+
+ // leap out if still in use
+ if (*_refcount > 0) return;
+
+ // release memory
+ delete _refcount;
+ delete _info;
+}
+
+/**
+ * End of namespace
+ */
+}
diff --git a/src/callable.cpp b/src/callable.cpp
new file mode 100644
index 0000000..1ad4ed2
--- /dev/null
+++ b/src/callable.cpp
@@ -0,0 +1,87 @@
+/**
+ * Callable.cpp
+ *
+ * Implementation for the Callable class
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+#include "includes.h"
+
+/**
+ * Namespace
+ */
+namespace PhpCpp {
+
+/**
+ * Function that is called by the Zend engine every time that a function gets called
+ * @param mixed
+ */
+void invoke_callable(INTERNAL_FUNCTION_PARAMETERS)
+{
+ std::cout << "invoke_callable" << std::endl;
+
+}
+
+/**
+ * Fill a function entry
+ * @param entry
+ */
+void Callable::fill(zend_function_entry *entry)
+{
+ // fill the members of the entity
+ entry->fname = _function.c_str();
+ entry->handler = invoke_callable;
+ entry->arg_info = _argv;
+ entry->num_args = _argc;
+ entry->flags = _flags;
+}
+
+/**
+ * Another attempt to fill internal function info
+ * @param entry
+ */
+void Callable::fill(zend_internal_function_info *info)
+{
+ // fill in all the members, not that the returning by reference is not used
+ info->_name = _function.c_str();
+ info->_name_len = _function.size();
+ info->_class_name = _classname.size() ? _classname.c_str() : NULL;
+ info->required_num_args = _required;
+ info->_type_hint = _type;
+ info->return_reference = false;
+ info->pass_rest_by_reference = false;
+}
+
+/**
+ * Process the arguments
+ * @param arguments
+ */
+void Callable::process(const std::initializer_list<Argument> &arguments)
+{
+ // store counters
+ _argc = arguments.size();
+ _required = arguments.size();
+
+ // allocate memory for the arguments, with one extra record to hold information
+ _argv = new zend_arg_info[_argc + 1];
+
+ // fill the info
+ fill((zend_internal_function_info *)_argv);
+
+ // iteration counter
+ int i = 0;
+
+ // loop through the arguments
+ for (auto it = begin(arguments); it != arguments.end(); it++)
+ {
+ // fill the argument structure
+ it->internal()->fill(&_argv[++i]);
+ }
+}
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/src/callable.h b/src/callable.h
new file mode 100644
index 0000000..3903ac7
--- /dev/null
+++ b/src/callable.h
@@ -0,0 +1,146 @@
+/**
+ * Callable.h
+ *
+ * This is an internal class that is used internally by the Function and Method
+ * classes, and that wraps the Zend function entry into a CPP object.
+ *
+ * This is an internal class, that is not supposed to be used or called from
+ * outside the PhpCpp library.
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace PhpCpp {
+
+/**
+ * Class definition
+ */
+class Callable
+{
+public:
+ /**
+ * Constructor
+ * @param classname Name of the class
+ * @param function Name of the function or method
+ * @param type Hint for the return type
+ * @param arguments The arguments that are passed to the function
+ * @param flags Optional flags to be passed to the function
+ */
+ Callable(const std::string &classname, const std::string &function, Type type = nullType, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
+ _classname(classname), _function(function), _type(type), _flags(flags)
+ {
+ // process the arguments
+ process(arguments);
+ }
+
+ /**
+ * Constructor
+ * @param classname Name of the class
+ * @param function Name of the function or method
+ * @param type Hint for the return type
+ * @param arguments The arguments that are passed to the function
+ * @param flags Optional flags to be passed to the function
+ */
+ Callable(const std::string &classname, const std::string &function, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
+ Callable(classname, function, nullType, arguments, flags) {}
+
+ /**
+ * Constructor
+ * @param function Name of the function or method
+ * @param type Hint for the return type
+ * @param arguments The arguments that are passed to the function
+ * @param flags Optional flags to be passed to the function
+ */
+ Callable(const std::string &function, Type type = nullType, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
+ Callable("", function, type, arguments, flags) {}
+
+ /**
+ * Constructor
+ * @param function Name of the function or method
+ * @param type Hint for the return type
+ * @param arguments The arguments that are passed to the function
+ * @param flags Optional flags to be passed to the function
+ */
+ Callable(const std::string &function, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
+ Callable("", function, nullType, arguments, flags) {}
+
+ /**
+ * Destructor
+ */
+ virtual ~Callable()
+ {
+ delete[] _argv;
+ }
+
+ /**
+ * Fill a function entry
+ * @param entry
+ */
+ void fill(zend_function_entry *entry);
+
+
+private:
+ /**
+ * Classname
+ * @var string
+ */
+ std::string _classname;
+
+ /**
+ * Function name
+ * @var string
+ */
+ std::string _function;
+
+ /**
+ * The return type
+ * @var Type
+ */
+ Type _type;
+
+ /**
+ * Function flags (like deprecated, abstract, private, etc)
+ * @var int
+ */
+ int _flags;
+
+ /**
+ * The number of arguments
+ * @var int
+ */
+ int _argc;
+
+ /**
+ * The number of required arguments
+ * @var int
+ */
+ int _required;
+
+ /**
+ * The arguments
+ * @var zend_arg_info[]
+ */
+ zend_arg_info *_argv;
+
+ /**
+ * Another attempt to fill internal function info
+ * @param entry
+ */
+ void fill(zend_internal_function_info *info);
+
+ /**
+ * Process the arguments
+ * @param arguments
+ */
+ void process(const std::initializer_list<Argument> &arguments);
+};
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/src/config.m4 b/src/config.m4
index e69de29..a81d11d 100644
--- a/src/config.m4
+++ b/src/config.m4
@@ -0,0 +1,4 @@
+dnl PHP_REQUIRE_CXX()
+dnl PHP_ADD_LIBRARY(stdc++, 1, PHP5CPP_SHARED_LIBADD)
+PHP_NEW_EXTENSION(phpcpp, extension.cpp, $ext_shared,,"","yes")
+
diff --git a/src/extension.cpp b/src/extension.cpp
index 94543ef..94b5082 100644
--- a/src/extension.cpp
+++ b/src/extension.cpp
@@ -22,8 +22,11 @@ static Extension *extension;
* @param name Name of the extension
* @param version Version number
*/
-Extension::Extension(const char *name, const char *version) : _name(name), _version(version), _entry(NULL), _request(NULL)
+Extension::Extension(const char *name, const char *version, const std::initializer_list<Function> &functions) : _name(name), _version(version)
{
+ // allocate functions
+ _functions = new Functions(functions);
+
// store pointer to the one and only extension
extension = this;
}
@@ -33,6 +36,9 @@ Extension::Extension(const char *name, const char *version) : _name(name), _vers
*/
Extension::~Extension()
{
+ // deallocate functions
+ delete _functions;
+
// deallocate entry
if (_entry) delete _entry;
}
@@ -105,7 +111,7 @@ zend_module_entry *Extension::entry()
_entry->ini_entry = NULL; // the php.ini record
_entry->deps = NULL; // dependencies on other modules
_entry->name = _name; // extension name
- _entry->functions = NULL; // functions supported by this module
+ _entry->functions = _functions->internal(); // functions supported by this module
_entry->module_startup_func = extension_startup; // startup function for the whole extension
_entry->module_shutdown_func = extension_shutdown; // shutdown function for the whole extension
_entry->request_startup_func = request_startup; // startup function per request
@@ -132,4 +138,3 @@ zend_module_entry *Extension::entry()
*/
}
-
diff --git a/src/function.cpp b/src/function.cpp
new file mode 100644
index 0000000..54f0717
--- /dev/null
+++ b/src/function.cpp
@@ -0,0 +1,49 @@
+/**
+ * Function.cpp
+ *
+ * Implementation for the function class
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+#include "includes.h"
+
+/**
+ * Set up namespace
+ */
+namespace PhpCpp {
+
+/**
+ * Constructor
+ * @param name Name of the function
+ * @param arguments The arguments that can be passed to the function
+ */
+Function::Function(const std::string &name, const std::initializer_list<Argument> &arguments)
+{
+ // one reference to the callable
+ _refcount = new int(1);
+ _callable = new Callable(name, arguments);
+}
+
+/**
+ * Remove one reference
+ */
+void Function::cleanup()
+{
+ // decrease number of references
+ (*_refcount)--;
+
+ // leap out if there are still other references
+ if (*_refcount > 0) return;
+
+ // release memory
+ delete _refcount;
+ delete _callable;
+}
+
+/**
+ * End of namespace
+ */
+}
+
+
diff --git a/src/functions.h b/src/functions.h
new file mode 100644
index 0000000..9b28ca2
--- /dev/null
+++ b/src/functions.h
@@ -0,0 +1,80 @@
+/**
+ * Functions.h
+ *
+ * Internal helper class that parses the functions initializer list, and
+ * that converts it into a zend_function_entry array.
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace PhpCpp {
+
+/**
+ * Class definition
+ */
+class Functions
+{
+public:
+ /**
+ * Constructor
+ * @param functions The functions to parse
+ */
+ Functions(const std::initializer_list<Function> &functions)
+ {
+ // allocate the function entries
+ _entries = new zend_function_entry[functions.size() + 1];
+
+ // keep iterator counter
+ int i = 0;
+
+ // loop through the functions
+ for (auto it = begin(functions); it != functions.end(); it++)
+ {
+ // let the callable fill the array
+ it->internal()->fill(&_entries[i++]);
+ }
+
+ // last entry should be set to all zeros
+ zend_function_entry *last = &_entries[i];
+
+ // all should be set to zero
+ memset(last, 0, sizeof(zend_function_entry));
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~Functions()
+ {
+ delete[] _entries;
+ }
+
+ /**
+ * Retrieve the internal data
+ * @return zend_function_entry*
+ */
+ zend_function_entry *internal()
+ {
+ return _entries;
+ }
+
+
+private:
+ /**
+ * The internal entries
+ * @var zend_function_entry*
+ */
+ zend_function_entry *_entries;
+};
+
+/**
+ * End of namespace
+ */
+}
+
+
+ \ No newline at end of file
diff --git a/src/includes.h b/src/includes.h
index 1decef0..0666dc4 100644
--- a/src/includes.h
+++ b/src/includes.h
@@ -11,6 +11,12 @@
* Include standard C and C++ libraries
*/
#include <stdlib.h>
+#include <string>
+#include <initializer_list>
+#include <vector>
+
+// for debugging
+#include <iostream>
/**
* PHP includes
@@ -25,6 +31,17 @@
/**
* Include other files from this library
*/
+#include "../include/type.h"
#include "../include/request.h"
+#include "../include/argument.h"
+#include "../include/variable.h"
+#include "../include/function.h"
#include "../include/extension.h"
+/**
+ * Interface files for internal use only
+ */
+#include "callable.h"
+#include "arginfo.h"
+#include "functions.h"
+
diff --git a/tests/simple/Makefile b/tests/simple/Makefile
index e3bd7c7..e60be3a 100644
--- a/tests/simple/Makefile
+++ b/tests/simple/Makefile
@@ -1,6 +1,6 @@
CPP = g++
RM = rm -f
-CPP_FLAGS = -Wall -c -I. -O2
+CPP_FLAGS = -Wall -c -I. -O2 -std=c++11
LD = g++
LD_FLAGS = -Wall -shared -O2
diff --git a/tests/simple/simple.cpp b/tests/simple/simple.cpp
index 34a12ce..ec39770 100644
--- a/tests/simple/simple.cpp
+++ b/tests/simple/simple.cpp
@@ -6,6 +6,7 @@
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2013 Copernica BV
*/
+#include <string>
#include <phpcpp.h>
#include <iostream>
@@ -46,7 +47,9 @@ public:
/**
* Constructor
*/
- SimpleExtension() : Extension("simple", "1.0")
+ SimpleExtension() : Extension("simple", "1.0", {
+ PhpCpp::Function("hallo")
+ })
{
}
@@ -68,5 +71,8 @@ public:
}
};
+
+
+
// create the object for the PHP extension
PHP_CPP_EXTENSION(SimpleExtension);