]> Raphaƫl G. Git Repositories - bbcode/blob - bbcode.c
Add unit tests
[bbcode] / bbcode.c
1
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5
6 #include "php.h"
7 #include "php_ini.h"
8 #include "ext/standard/info.h"
9 #include "Zend/zend_exceptions.h"
10 #include "php_bbcode.h"
11
12 /* If you declare any globals in php_bbcode.h uncomment this:
13 ZEND_DECLARE_MODULE_GLOBALS(bbcode)
14 */
15
16 typedef struct _bbcode_object {
17 HashTable *tag;
18 HashTable *smiley;
19 zval flag;
20 zend_object std;
21 } bbcode_object;
22
23 /* True global resources - no need for thread safety here */
24 zend_object_handlers bbcode_handlers;
25
26 /* BBCode object */
27 zend_class_entry *bbcode_ce;
28
29 /* BBCode exception object */
30 zend_class_entry *bbcode_exception_ce;
31
32 /* Define all constants */
33 #define BBCODE_DEF(GEN) \
34 /* Types */ \
35 GEN(TYPE_ARG) /*BBCODE_TYPE_ARG*/\
36 GEN(TYPE_NOARG) /*BBCODE_TYPE_NOARG*/\
37 GEN(TYPE_SINGLE) /*BBCODE_TYPE_SINGLE*/\
38 GEN(TYPE_OPTARG) /*BBCODE_TYPE_OPTARG*/\
39 GEN(TYPE_ROOT) /*BBCODE_TYPE_ROOT*/\
40 \
41 /* Quotes */ \
42 GEN(QUOTE_DOUBLE) /*BBCODE_ARG_DOUBLE_QUOTE*/\
43 GEN(QUOTE_SIMPLE) /*BBCODE_ARG_SINGLE_QUOTE*/\
44 GEN(QUOTE_HTML) /*BBCODE_ARG_HTML_QUOTE*/\
45 GEN(QUOTE_ESCAPE) /*BBCODE_ARG_QUOTE_ESCAPING*/\
46 \
47 /* Corrections */ \
48 GEN(CORRECT_AUTO) /*BBCODE_AUTO_CORRECT*/\
49 GEN(CORRECT_REOPEN) /*BBCODE_CORRECT_REOPEN_TAGS*/\
50 GEN(CORRECT_NOTREE) /*BBCODE_DISABLE_TREE_BUILD*/\
51 \
52 /* Smileys */ \
53 GEN(SMILEY_ON) /*BBCODE_DEFAULT_SMILEYS_ON*/\
54 GEN(SMILEY_CI) /*BBCODE_SMILEYS_CASE_INSENSITIVE*/\
55 \
56 /* Flags */ \
57 GEN(CLOSE_AUTO) /*BBCODE_FLAGS_ONE_OPEN_PER_LEVEL*/\
58 GEN(REMOVE_EMPTY) /*BBCODE_FLAGS_REMOVE_IF_EMPTY*/\
59 GEN(REMOVE_CONTENT) /*BBCODE_FLAGS_CDATA_NOT_ALLOWED*/\
60 GEN(REMOVE_REOPEN) /*BBCODE_FLAGS_DENY_REOPEN_CHILD*/
61
62
63 /* Generate enum version */
64 #define BBCODE_GEN_ENUM(NAME) BBCODE_ ## NAME,
65
66 /* Generate zend const version */
67 #define BBCODE_GEN_CONST(NAME) zend_declare_class_constant_long(bbcode_ce, #NAME, sizeof(#NAME) - 1, BBCODE_ ## NAME TSRMLS_CC);
68
69 /* All flags enum set */
70 enum {
71 BBCODE_DEF(BBCODE_GEN_ENUM)
72 };
73
74 /* Set default flag
75 * TODO: Set it in an ini ? */
76 #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
77
78 /*static inline bbcode_object *bbcode_object_from_zend_object(zend_object *obj) {
79 return (bbcode_object *)((char*)(obj) - XtOffsetOf(bbcode_object, std));
80 }*/
81
82 static inline bbcode_object* bbcode_fetch(zend_object *obj) {
83 return (bbcode_object *)((char *)obj - XtOffsetOf(bbcode_object, std));
84 }
85
86 #define Z_BBCODE_P(zv) bbcode_fetch(Z_OBJ_P((zv)))
87
88 static void bbcode_destroy(bbcode_object *obj TSRMLS_DC);
89 static void bbcode_free(bbcode_object *obj TSRMLS_DC);
90 static zend_object *bbcode_clone(zval *obj TSRMLS_DC);
91 static zend_object *bbcode_create(zend_class_entry *ce TSRMLS_DC);
92
93 /* {{{ static void bbcode_destroy(bbcode_object *obj TSRMLS_DC) {
94 * BBCode object destroy call */
95 static void bbcode_destroy(bbcode_object *obj TSRMLS_DC) {
96 //zend_objects_destroy_object(&obj->std);
97 zend_objects_destroy_object((zend_object *)obj);
98
99 //zend_object_std_dtor(&obj->std TSRMLS_CC);
100
101 /*if (obj->flag) {
102 efree(obj->flag);
103 }*/
104
105 //efree(obj);
106 }
107 /* }}} */
108
109 /* {{{ static void bbcode_free(bbcode_object *obj TSRMLS_DC) {
110 * BBCode object free call */
111 static void bbcode_free(bbcode_object *obj TSRMLS_DC) {
112
113 /*if (obj->flag) {
114 efree(obj->flag);
115 }*/
116
117 //efree(obj);
118 zend_object_std_dtor((zend_object *)obj);
119 }
120 /* }}} */
121
122 /* {{{ static zend_object *bbcode_clone(zval *obj) {
123 * BBCode object clone call */
124 static zend_object *bbcode_clone(zval *obj) {
125
126 zend_object *oldobj = Z_OBJ_P(obj);
127 zend_object *newobj = bbcode_create(oldobj->ce);
128
129 zend_objects_clone_members(newobj, oldobj);
130
131 /*Retrieve from zend object old bbcode*/
132 bbcode_object *bboldobj = Z_BBCODE_P(obj);
133 /*Retrieve from zend object new bbcode*/
134 bbcode_object *bbnewobj = bbcode_fetch(newobj);
135
136 /*Restore object member values*/
137 /*TODO: deal with the other one*/
138 Z_LVAL(bbnewobj->flag) = Z_LVAL(bboldobj->flag);
139
140 return newobj;
141 }
142 /* }}} */
143
144 /* {{{ static zend_object *bbcode_create(zend_class_entry *ce TSRMLS_DC) {
145 * BBCode object create call */
146 static zend_object *bbcode_create(zend_class_entry *ce TSRMLS_DC) {
147 bbcode_object *obj = (bbcode_object *)ecalloc(1, sizeof(bbcode_object) + zend_object_properties_size(ce));//emalloc(sizeof(bbcode_object));
148
149 zend_object_std_init(&obj->std, ce TSRMLS_CC);
150 object_properties_init(&obj->std, ce TSRMLS_CC);
151
152 memcpy(&bbcode_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
153 bbcode_handlers.offset = XtOffsetOf(bbcode_object, std);
154 bbcode_handlers.dtor_obj = (zend_object_dtor_obj_t) bbcode_destroy;
155 bbcode_handlers.free_obj = (zend_object_free_obj_t) bbcode_free;
156 bbcode_handlers.clone_obj = (zend_object_clone_obj_t) bbcode_clone;
157
158 obj->std.handlers = &bbcode_handlers;
159
160 Z_LVAL(obj->flag) = 0;
161
162 return &obj->std;
163 }
164 /* }}} */
165
166 /* {{{ ZEND_BEGIN_ARG_INFO_EX(bbcode_construct_arginfo) */
167 ZEND_BEGIN_ARG_INFO_EX(bbcode_construct_arginfo, 0, 0, 1)
168 ZEND_ARG_ARRAY_INFO(0, tag, 1)
169 ZEND_ARG_ARRAY_INFO(0, smiley, 1)
170 ZEND_ARG_INFO(0, flag)
171 ZEND_END_ARG_INFO()
172 /* }}} */
173
174 /* {{{ ZEND_BEGIN_ARG_INFO_EX(bbcode_parse_arginfo) */
175 ZEND_BEGIN_ARG_INFO_EX(bbcode_parse_arginfo, 0, 0, 1)
176 ZEND_ARG_INFO(0, str)
177 ZEND_END_ARG_INFO()
178 /* }}} */
179
180 /* { { { PHP_METHOD(BBCode, __construct) {
181 */
182 PHP_METHOD(BBCode, __construct) {
183 HashTable *tag = NULL;
184 HashTable *smiley = NULL;
185 long flag = BBCODE_DEFAULT_FLAG;
186
187 /*TODO: init tag with [
188 '' => [ ? ]
189 ]*/
190 /* TODO: init smiley with default list
191 * TODO: use prefix in an ini parameter ? ini_setable ?
192 * TODO: make sure it's not really a global and per-app param ?
193 * */
194
195 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H|Hl", &tag, &smiley, &flag) == FAILURE) {
196 return;
197 }
198
199 //bbcode_object *obj = bbcode_fetch(Z_OBJ_P(getThis()));
200 bbcode_object *obj = Z_BBCODE_P(getThis());
201 assert(obj != NULL);
202
203 //TODO: set tag and smiley
204
205 if (flag) {
206 Z_LVAL(obj->flag) = flag;
207 }
208
209 if (smiley) {
210 obj->smiley = smiley;
211 }
212
213 obj->tag = tag;
214
215 //obj = zend_object_store_get_object(getThis() TSRMLS_CC);
216 //if (error) {
217 //ZVAL_NULL(this);
218 //}
219 }
220 /* }}} */
221
222 /* {{{ PHP_METHOD(BBCode, __destruct) {
223 */
224 PHP_METHOD(BBCode, __destruct) {
225 }
226 /* }}} */
227
228 /* {{{ PHP_METHOD(BBCode, parse) {
229 */
230 PHP_METHOD(BBCode, parse) {
231 zend_string *str = NULL;
232
233 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &str) == FAILURE) {
234 return;
235 }
236
237 //TODO: apply the parsing on string
238
239 RETURN_STR(str);
240 }
241 /* }}} */
242
243 /* {{{ bbcode_methods[]
244 *
245 * Every BBCode visible function must have an entry in bbcode_methods[].
246 */
247 const zend_function_entry bbcode_methods[] = {
248 PHP_ME(BBCode, __construct, bbcode_construct_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
249 PHP_ME(BBCode, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
250 PHP_ME(BBCode, parse, bbcode_parse_arginfo, ZEND_ACC_PUBLIC)
251 PHP_FE_END
252 };
253 /* }}} */
254
255 /* {{{ PHP_MINIT_FUNCTION
256 */
257 PHP_MINIT_FUNCTION(bbcode)
258 {
259 /* If you have INI entries, uncomment these lines
260 REGISTER_INI_ENTRIES();
261 */
262
263 /* Tmp zend class entry*/
264 zend_class_entry tmp_ce;
265
266 /* Init BBCode class entry */
267 INIT_CLASS_ENTRY(tmp_ce, "BBCode", bbcode_methods);
268
269 /* Register BBCode class entry */
270 bbcode_ce = zend_register_internal_class(&tmp_ce TSRMLS_CC);
271 bbcode_ce->create_object = bbcode_create;
272
273 /* Generate const */
274 BBCODE_DEF(BBCODE_GEN_CONST)
275
276 /* Init BBCodeException class entry */
277 INIT_CLASS_ENTRY(tmp_ce, "BBCodeException", NULL);
278
279 /* Register BBCodeException class entry */
280 bbcode_exception_ce = zend_register_internal_class_ex(&tmp_ce, zend_exception_get_default(TSRMLS_C) TSRMLS_CC);
281
282 return SUCCESS;
283 }
284 /* }}} */
285
286 /* {{{ PHP_MSHUTDOWN_FUNCTION
287 */
288 PHP_MSHUTDOWN_FUNCTION(bbcode)
289 {
290 /* uncomment this line if you have INI entries
291 UNREGISTER_INI_ENTRIES();
292 */
293 return SUCCESS;
294 }
295 /* }}} */
296
297 /* {{{ PHP_MINFO_FUNCTION
298 */
299 PHP_MINFO_FUNCTION(bbcode)
300 {
301 php_info_print_table_start();
302 php_info_print_table_header(2, PHP_BBCODE_NAME " support", "enabled");
303 php_info_print_table_row(2, "Extension version", PHP_BBCODE_VERSION);
304 php_info_print_table_end();
305
306 /* Remove comments if you have entries in php.ini
307 DISPLAY_INI_ENTRIES();
308 */
309 }
310 /* }}} */
311
312 /* {{{ bbcode_module_entry
313 */
314 zend_module_entry bbcode_module_entry = {
315 STANDARD_MODULE_HEADER,
316 PHP_BBCODE_NAME,
317 NULL, /*bbcode_functions,*/
318 PHP_MINIT(bbcode),
319 PHP_MSHUTDOWN(bbcode),
320 NULL,
321 NULL,
322 PHP_MINFO(bbcode),
323 PHP_BBCODE_VERSION,
324 STANDARD_MODULE_PROPERTIES
325 };
326 /* }}} */
327
328 #ifdef COMPILE_DL_BBCODE
329 #ifdef ZTS
330 ZEND_TSRMLS_CACHE_DEFINE()
331 #endif
332 ZEND_GET_MODULE(bbcode)
333 #endif
334
335 /*
336 * Local variables:
337 * tab-width: 4
338 * c-basic-offset: 4
339 * End:
340 * vim600: noet sw=4 ts=4 fdm=marker
341 * vim<600: noet sw=4 ts=4
342 */