+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "Zend/zend_exceptions.h"
+#include "php_bbcode.h"
+
+/* If you declare any globals in php_bbcode.h uncomment this:
+ZEND_DECLARE_MODULE_GLOBALS(bbcode)
+*/
+
+typedef struct _bbcode_object {
+ /*zval *tag;
+ zval *smiley;
+ zval *flag;*/
+ zend_long flag;
+ zend_object_handlers bbcode_handlers;
+ zend_object std;
+} bbcode_object;
+
+/* True global resources - no need for thread safety here */
+/* BBCode object */
+zend_class_entry *bbcode_ce;
+
+/* BBCode exception object */
+zend_class_entry *bbcode_exception_ce;
+
+/* Define all constants */
+#define BBCODE_DEF(GEN) \
+ /* Types */ \
+ GEN(TYPE_ARG) /*BBCODE_TYPE_ARG*/\
+ GEN(TYPE_NOARG) /*BBCODE_TYPE_NOARG*/\
+ GEN(TYPE_SINGLE) /*BBCODE_TYPE_SINGLE*/\
+ GEN(TYPE_OPTARG) /*BBCODE_TYPE_OPTARG*/\
+ GEN(TYPE_ROOT) /*BBCODE_TYPE_ROOT*/\
+ \
+ /* Quotes */ \
+ GEN(QUOTE_DOUBLE) /*BBCODE_ARG_DOUBLE_QUOTE*/\
+ GEN(QUOTE_SIMPLE) /*BBCODE_ARG_SINGLE_QUOTE*/\
+ GEN(QUOTE_HTML) /*BBCODE_ARG_HTML_QUOTE*/\
+ GEN(QUOTE_ESCAPE) /*BBCODE_ARG_QUOTE_ESCAPING*/\
+ \
+ /* Corrections */ \
+ GEN(CORRECT_AUTO) /*BBCODE_AUTO_CORRECT*/\
+ GEN(CORRECT_REOPEN) /*BBCODE_CORRECT_REOPEN_TAGS*/\
+ GEN(CORRECT_NOTREE) /*BBCODE_DISABLE_TREE_BUILD*/\
+ \
+ /* Smileys */ \
+ GEN(SMILEY_ON) /*BBCODE_DEFAULT_SMILEYS_ON*/\
+ GEN(SMILEY_CI) /*BBCODE_SMILEYS_CASE_INSENSITIVE*/\
+ \
+ /* Flags */ \
+ GEN(CLOSE_AUTO) /*BBCODE_FLAGS_ONE_OPEN_PER_LEVEL*/\
+ GEN(REMOVE_EMPTY) /*BBCODE_FLAGS_REMOVE_IF_EMPTY*/\
+ GEN(REMOVE_CONTENT) /*BBCODE_FLAGS_CDATA_NOT_ALLOWED*/\
+ GEN(REMOVE_REOPEN) /*BBCODE_FLAGS_DENY_REOPEN_CHILD*/
+
+
+/* Generate enum version */
+#define BBCODE_GEN_ENUM(NAME) BBCODE_ ## NAME,
+
+/* Generate zend const version */
+#define BBCODE_GEN_CONST(NAME) zend_declare_class_constant_long(bbcode_ce, #NAME, sizeof(#NAME) - 1, BBCODE_ ## NAME TSRMLS_CC);
+
+/* All flags enum set */
+enum {
+ BBCODE_DEF(BBCODE_GEN_ENUM)
+};
+
+/* Set default flag
+ * TODO: Set it in an ini ? */
+#define BBCODE_DEFAULT_FLAG BBCODE_QUOTE_DOUBLE|BBCODE_QUOTE_SIMPLE|BBCODE_QUOTE_ESCAPE|BBCODE_CORRECT_AUTO|BBCODE_CORRECT_REOPEN|BBCODE_SMILEY_ON|BBCODE_CLOSE_AUTO|BBCODE_REMOVE_EMPTY
+
+static void bbcode_destroy(bbcode_object *obj TSRMLS_DC);
+static void bbcode_free(bbcode_object *obj TSRMLS_DC);
+static zend_object *bbcode_clone(zval *obj TSRMLS_DC);
+static zend_object *bbcode_create(zend_class_entry *ce TSRMLS_DC);
+
+/* BBCode object destroy call */
+static void bbcode_destroy(bbcode_object *obj TSRMLS_DC) {
+ //zend_objects_destroy_object(&obj->std);
+ zend_objects_destroy_object((zend_object *)obj);
+
+ //zend_object_std_dtor(&obj->std TSRMLS_CC);
+
+ /*if (obj->flag) {
+ efree(obj->flag);
+ }*/
+
+ //efree(obj);
+}
+
+/* BBCode object free call */
+static void bbcode_free(bbcode_object *obj TSRMLS_DC) {
+
+ /*if (obj->flag) {
+ efree(obj->flag);
+ }*/
+
+ //efree(obj);
+ zend_object_std_dtor((zend_object *)obj);
+}
+
+static zend_object *bbcode_clone(zval *obj TSRMLS_DC) {
+
+ bbcode_object *oldobj = (bbcode_object *)((char *)obj - XtOffsetOf(bbcode_object, std));
+
+ bbcode_object *newobj = ecalloc(1, sizeof(bbcode_object) + zend_object_properties_size(Z_OBJCE_P(obj)));
+
+ zend_object_std_init(&newobj->std, Z_OBJCE_P(obj) TSRMLS_CC);
+ object_properties_init(&newobj->std, Z_OBJCE_P(obj) TSRMLS_CC);
+
+ memcpy(&newobj->bbcode_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ newobj->bbcode_handlers.offset = XtOffsetOf(bbcode_object, std);
+ newobj->bbcode_handlers.dtor_obj = (zend_object_dtor_obj_t) bbcode_destroy;
+ newobj->bbcode_handlers.free_obj = (zend_object_free_obj_t) bbcode_free;
+ newobj->bbcode_handlers.clone_obj = (zend_object_clone_obj_t) bbcode_clone;
+
+ newobj->std.handlers = &(newobj->bbcode_handlers);
+
+ zend_objects_clone_members(&newobj->std, &oldobj->std);
+
+#if 0
+ bbcode_object *oldobj = (bbcode_object *)((char *)obj - XtOffsetOf(bbcode_object, std));
+ zend_object *newobj_val = bbcode_create(Z_OBJCE_P(obj) TSRMLS_CC);
+ bbcode_object *newobj = (bbcode_object *)((char *)newobj_val - XtOffsetOf(bbcode_object, std));
+
+ zend_objects_clone_members(&newobj->std, &oldobj->std);
+#endif
+
+ /*XXX: clone flag member*/
+ newobj->flag = oldobj->flag;
+
+ /* TODO: clone the members of bbcode_object
+ newobj->buffer = oldobj->buffer;
+ newobj->length = oldobj->length;
+
+ if (oldobj->flag) {
+ newobj->buffer = emalloc(oldobj->length);
+ memcpy(newobj->buffer, oldobj->buffer, oldobj->length);
+ }*/
+
+ return &newobj->std;
+}
+
+#if 0
+static zend_object_value bbcode_clone(zval *obj TSRMLS_DC)
+{
+ bbcode_object *oldobj = zend_object_store_get_object(obj TSRMLS_CC);
+ zend_object_value newobj_val = array_buffer_create_object(Z_OBJCE_P(obj) TSRMLS_CC);
+ bbcode_object *newobj = zend_object_store_get_object_by_handle(newobj_val.handle TSRMLS_CC);
+
+ zend_objects_clone_members(&newobj->std, &oldobj->std);
+
+ /* TODO: clone the members of bbcode_object
+ newobj->buffer = oldobj->buffer;
+ newobj->length = oldobj->length;
+
+ if (oldobj->flag) {
+ newobj->buffer = emalloc(oldobj->length);
+ memcpy(newobj->buffer, oldobj->buffer, oldobj->length);
+ }*/
+
+ return newobj_val;
+}
+#endif
+
+static zend_object *bbcode_create(zend_class_entry *ce TSRMLS_DC) {
+ bbcode_object *obj = ecalloc(1, sizeof(bbcode_object) + zend_object_properties_size(ce));//emalloc(sizeof(bbcode_object));
+ obj->flag = 0;
+ //memset(obj, 0, sizeof(bbcode_object));
+
+ zend_object_std_init(&obj->std, ce TSRMLS_CC);
+ object_properties_init(&obj->std, ce TSRMLS_CC);
+
+ /**/
+
+ memcpy(&obj->bbcode_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ obj->bbcode_handlers.offset = XtOffsetOf(bbcode_object, std);
+ obj->bbcode_handlers.dtor_obj = (zend_object_dtor_obj_t) bbcode_destroy;
+ obj->bbcode_handlers.free_obj = (zend_object_free_obj_t) bbcode_free;
+ obj->bbcode_handlers.clone_obj = (zend_object_clone_obj_t) bbcode_clone;
+ //bbcode_handlers.offset = XtOffsetOf(bbcode_object, std);
+ //bbcode_handlers.dtor_obj = (zend_object_dtor_obj_t) bbcode_destroy;
+ //bbcode_handlers.free_obj = (zend_object_free_obj_t) bbcode_free;
+ //bbcode_handlers.clone_obj = (zend_object_clone_obj_t) bbcode_clone;
+
+
+ /*retval.handle = zend_object_store_put(
+ obj,
+ (zend_objects_store_dtor_t) zend_objects_destroy_object,
+ (zend_objects_free_object_storage_t) bbcode_free,
+ NULL TSRMLS_CC
+ );
+ retval.handlers = &bbcode_handlers;
+
+ return retval;*/
+
+ obj->std.handlers = &(obj->bbcode_handlers);
+
+ return &obj->std;
+}
+
+static inline bbcode_object* bbcode_fetch(zend_object *obj) {
+ return (bbcode_object *)((char *)obj - XtOffsetOf(bbcode_object, std));
+}
+
+/* {{{ PHP_METHOD(BBCode::__construct) {
+ */
+ZEND_BEGIN_ARG_INFO_EX(bbcode_construct_arginfo, 0, 0, 1)
+ ZEND_ARG_ARRAY_INFO(0, tag, 1)
+ ZEND_ARG_ARRAY_INFO(0, smiley, 1)
+ ZEND_ARG_INFO(0, flag)
+ZEND_END_ARG_INFO()
+
+
+PHP_METHOD(BBCode, __construct) {
+ zend_array *tag;
+ zend_array *smiley;
+ zend_long flag = BBCODE_DEFAULT_FLAG;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|al", &tag, &smiley, &flag) == FAILURE) {
+ return;
+ }
+
+ bbcode_object *obj = bbcode_fetch(Z_OBJ_P(getThis()));
+ assert(obj != NULL);
+
+ if (flag) {
+ obj->flag = (zend_long) flag;
+ }
+
+ //obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+ //if (error) {
+ //ZVAL_NULL(this);
+ //}
+}
+/* }}} */
+
+/* {{{ PHP_METHOD(BBCode, __destruct) {
+ */
+PHP_METHOD(BBCode, __destruct) {
+}
+/* }}} */
+
+/* {{{ PHP_METHOD(BBCode, __toString) {
+ */
+PHP_METHOD(BBCode, __toString) {
+ //TODO:
+}
+/* }}} */
+
+/* {{{ bbcode_methods[]
+ *
+ * Every BBCode visible function must have an entry in bbcode_methods[].
+ */
+const zend_function_entry bbcode_methods[] = {
+ PHP_ME(BBCode, __construct, bbcode_construct_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(BBCode, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
+ PHP_ME(BBCode, __toString, NULL, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+/* }}} */
+
+/* {{{ PHP_MINIT_FUNCTION
+ */
+PHP_MINIT_FUNCTION(bbcode)
+{
+ /* If you have INI entries, uncomment these lines
+ REGISTER_INI_ENTRIES();
+ */
+
+ /* Tmp zend class entry*/
+ zend_class_entry tmp_ce;
+
+ /* Init BBCode class entry */
+ INIT_CLASS_ENTRY(tmp_ce, "BBCode", bbcode_methods);
+
+ /* Register BBCode class entry */
+ bbcode_ce = zend_register_internal_class(&tmp_ce TSRMLS_CC);
+ bbcode_ce->create_object = bbcode_create;
+
+ /* Generate const */
+ BBCODE_DEF(BBCODE_GEN_CONST)
+
+ /* Init BBCodeException class entry */
+ INIT_CLASS_ENTRY(tmp_ce, "BBCodeException", NULL);
+
+ /* Register BBCodeException class entry */
+ bbcode_exception_ce = zend_register_internal_class_ex(&tmp_ce, zend_exception_get_default(TSRMLS_C) TSRMLS_CC);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_MSHUTDOWN_FUNCTION
+ */
+PHP_MSHUTDOWN_FUNCTION(bbcode)
+{
+ /* uncomment this line if you have INI entries
+ UNREGISTER_INI_ENTRIES();
+ */
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_MINFO_FUNCTION
+ */
+PHP_MINFO_FUNCTION(bbcode)
+{
+ php_info_print_table_start();
+ php_info_print_table_header(2, PHP_BBCODE_NAME " support", "enabled");
+ php_info_print_table_row(2, "Extension version", PHP_BBCODE_VERSION);
+ php_info_print_table_end();
+
+ /* Remove comments if you have entries in php.ini
+ DISPLAY_INI_ENTRIES();
+ */
+}
+/* }}} */
+
+/* {{{ bbcode_module_entry
+ */
+zend_module_entry bbcode_module_entry = {
+ STANDARD_MODULE_HEADER,
+ PHP_BBCODE_NAME,
+ NULL, /*bbcode_functions,*/
+ PHP_MINIT(bbcode),
+ PHP_MSHUTDOWN(bbcode),
+ NULL,
+ NULL,
+ PHP_MINFO(bbcode),
+ PHP_BBCODE_VERSION,
+ STANDARD_MODULE_PROPERTIES
+};
+/* }}} */
+
+#ifdef COMPILE_DL_BBCODE
+#ifdef ZTS
+ZEND_TSRMLS_CACHE_DEFINE()
+#endif
+ZEND_GET_MODULE(bbcode)
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */