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