#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 { HashTable *tag; HashTable *smiley; zval flag; zend_object std; } bbcode_object; /* True global resources - no need for thread safety here */ zend_object_handlers bbcode_handlers; /* 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 inline bbcode_object *bbcode_object_from_zend_object(zend_object *obj) { return (bbcode_object *)((char*)(obj) - XtOffsetOf(bbcode_object, std)); }*/ static inline bbcode_object* bbcode_fetch(zend_object *obj) { return (bbcode_object *)((char *)obj - XtOffsetOf(bbcode_object, std)); } #define Z_BBCODE_P(zv) bbcode_fetch(Z_OBJ_P((zv))) 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); /* {{{ static void bbcode_destroy(bbcode_object *obj 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); } /* }}} */ /* {{{ static void bbcode_free(bbcode_object *obj TSRMLS_DC) { * 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) { * BBCode object clone call */ static zend_object *bbcode_clone(zval *obj) { zend_object *oldobj = Z_OBJ_P(obj); zend_object *newobj = bbcode_create(oldobj->ce); zend_objects_clone_members(newobj, oldobj); /*Retrieve from zend object old bbcode*/ bbcode_object *bboldobj = Z_BBCODE_P(obj); /*Retrieve from zend object new bbcode*/ bbcode_object *bbnewobj = bbcode_fetch(newobj); /*Restore object member values*/ /*TODO: deal with the other one*/ Z_LVAL(bbnewobj->flag) = Z_LVAL(bboldobj->flag); return newobj; } /* }}} */ /* {{{ static zend_object *bbcode_create(zend_class_entry *ce TSRMLS_DC) { * BBCode object create call */ static zend_object *bbcode_create(zend_class_entry *ce TSRMLS_DC) { bbcode_object *obj = (bbcode_object *)ecalloc(1, sizeof(bbcode_object) + zend_object_properties_size(ce));//emalloc(sizeof(bbcode_object)); zend_object_std_init(&obj->std, ce TSRMLS_CC); object_properties_init(&obj->std, ce TSRMLS_CC); memcpy(&bbcode_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); 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; obj->std.handlers = &bbcode_handlers; Z_LVAL(obj->flag) = 0; return &obj->std; } /* }}} */ /* {{{ ZEND_BEGIN_ARG_INFO_EX(bbcode_construct_arginfo) */ 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() /* }}} */ /* {{{ ZEND_BEGIN_ARG_INFO_EX(bbcode_parse_arginfo) */ ZEND_BEGIN_ARG_INFO_EX(bbcode_parse_arginfo, 0, 0, 1) ZEND_ARG_INFO(0, str) ZEND_END_ARG_INFO() /* }}} */ /* { { { PHP_METHOD(BBCode, __construct) { */ PHP_METHOD(BBCode, __construct) { HashTable *tag = NULL; HashTable *smiley = NULL; long flag = BBCODE_DEFAULT_FLAG; /*TODO: init tag with [ '' => [ ? ] ]*/ /* TODO: init smiley with default list * TODO: use prefix in an ini parameter ? ini_setable ? * TODO: make sure it's not really a global and per-app param ? * */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H|Hl", &tag, &smiley, &flag) == FAILURE) { return; } //bbcode_object *obj = bbcode_fetch(Z_OBJ_P(getThis())); bbcode_object *obj = Z_BBCODE_P(getThis()); assert(obj != NULL); //TODO: set tag and smiley if (flag) { Z_LVAL(obj->flag) = flag; } if (smiley) { obj->smiley = smiley; } obj->tag = tag; //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, parse) { */ PHP_METHOD(BBCode, parse) { zend_string *str = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &str) == FAILURE) { return; } //TODO: apply the parsing on string RETURN_STR(str); } /* }}} */ /* {{{ 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, parse, bbcode_parse_arginfo, 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 */