1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1998-2008 Zend Technologies Ltd. (http://www.zend.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 2.00 of the Zend license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.zend.com/license/2_00.txt. |
11 | If you did not receive a copy of the Zend license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@zend.com so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Andi Gutmans <andi@zend.com> |
16 | Zeev Suraski <zeev@zend.com> |
17 +----------------------------------------------------------------------+
18 */
19
20 /* $Id: zend_builtin_functions.c,v 1.384 2008/08/22 00:54:00 felipe Exp $ */
21
22 #include "zend.h"
23 #include "zend_API.h"
24 #include "zend_builtin_functions.h"
25 #include "zend_constants.h"
26 #include "zend_ini.h"
27 #include "zend_extensions.h"
28
29 #undef ZEND_TEST_EXCEPTIONS
30
31 /* {{{ protos */
32 static ZEND_FUNCTION(zend_version);
33 static ZEND_FUNCTION(func_num_args);
34 static ZEND_FUNCTION(func_get_arg);
35 static ZEND_FUNCTION(func_get_args);
36 static ZEND_NAMED_FUNCTION(zend_if_strlen);
37 static ZEND_FUNCTION(strcmp);
38 static ZEND_FUNCTION(strncmp);
39 static ZEND_FUNCTION(strcasecmp);
40 static ZEND_FUNCTION(strncasecmp);
41 static ZEND_FUNCTION(each);
42 static ZEND_FUNCTION(error_reporting);
43 static ZEND_FUNCTION(define);
44 static ZEND_FUNCTION(defined);
45 static ZEND_FUNCTION(get_class);
46 static ZEND_FUNCTION(get_called_class);
47 static ZEND_FUNCTION(get_parent_class);
48 static ZEND_FUNCTION(method_exists);
49 static ZEND_FUNCTION(property_exists);
50 static ZEND_FUNCTION(class_exists);
51 static ZEND_FUNCTION(interface_exists);
52 static ZEND_FUNCTION(function_exists);
53 static ZEND_FUNCTION(class_alias);
54 #if ZEND_DEBUG
55 static ZEND_FUNCTION(leak);
56 #ifdef ZEND_TEST_EXCEPTIONS
57 static ZEND_FUNCTION(crash);
58 #endif
59 #endif
60 static ZEND_FUNCTION(get_included_files);
61 static ZEND_FUNCTION(is_subclass_of);
62 static ZEND_FUNCTION(is_a);
63 static ZEND_FUNCTION(get_class_vars);
64 static ZEND_FUNCTION(get_object_vars);
65 static ZEND_FUNCTION(get_class_methods);
66 static ZEND_FUNCTION(trigger_error);
67 static ZEND_FUNCTION(set_error_handler);
68 static ZEND_FUNCTION(restore_error_handler);
69 static ZEND_FUNCTION(set_exception_handler);
70 static ZEND_FUNCTION(restore_exception_handler);
71 static ZEND_FUNCTION(get_declared_classes);
72 static ZEND_FUNCTION(get_declared_interfaces);
73 static ZEND_FUNCTION(get_defined_functions);
74 static ZEND_FUNCTION(get_defined_vars);
75 static ZEND_FUNCTION(create_function);
76 static ZEND_FUNCTION(get_resource_type);
77 static ZEND_FUNCTION(get_loaded_extensions);
78 static ZEND_FUNCTION(extension_loaded);
79 static ZEND_FUNCTION(get_extension_funcs);
80 static ZEND_FUNCTION(get_defined_constants);
81 static ZEND_FUNCTION(debug_backtrace);
82 static ZEND_FUNCTION(debug_print_backtrace);
83 #if ZEND_DEBUG
84 static ZEND_FUNCTION(zend_test_func);
85 #ifdef ZTS
86 static ZEND_FUNCTION(zend_thread_id);
87 #endif
88 #endif
89 static ZEND_FUNCTION(gc_collect_cycles);
90 static ZEND_FUNCTION(gc_enabled);
91 static ZEND_FUNCTION(gc_enable);
92 static ZEND_FUNCTION(gc_disable);
93 /* }}} */
94
95 /* {{{ arginfo */
96 static
97 ZEND_BEGIN_ARG_INFO(arginfo_zend_version, 0)
98 ZEND_END_ARG_INFO()
99
100 static
101 ZEND_BEGIN_ARG_INFO(arginfo_func_num_args, 0)
102 ZEND_END_ARG_INFO()
103
104 static
105 ZEND_BEGIN_ARG_INFO_EX(arginfo_func_get_arg, 0, 0, 1)
106 ZEND_ARG_INFO(0, arg_num)
107 ZEND_END_ARG_INFO()
108
109 static
110 ZEND_BEGIN_ARG_INFO(arginfo_func_get_args, 0)
111 ZEND_END_ARG_INFO()
112
113 static
114 ZEND_BEGIN_ARG_INFO_EX(arginfo_strlen, 0, 0, 1)
115 ZEND_ARG_INFO(0, str)
116 ZEND_END_ARG_INFO()
117
118 static
119 ZEND_BEGIN_ARG_INFO_EX(arginfo_strcmp, 0, 0, 2)
120 ZEND_ARG_INFO(0, str1)
121 ZEND_ARG_INFO(0, str2)
122 ZEND_END_ARG_INFO()
123
124 static
125 ZEND_BEGIN_ARG_INFO_EX(arginfo_strncmp, 0, 0, 3)
126 ZEND_ARG_INFO(0, str1)
127 ZEND_ARG_INFO(0, str2)
128 ZEND_ARG_INFO(0, len)
129 ZEND_END_ARG_INFO()
130
131 static
132 ZEND_BEGIN_ARG_INFO_EX(arginfo_strcasecmp, 0, 0, 2)
133 ZEND_ARG_INFO(0, str1)
134 ZEND_ARG_INFO(0, str2)
135 ZEND_END_ARG_INFO()
136
137 static
138 ZEND_BEGIN_ARG_INFO_EX(arginfo_strncasecmp, 0, 0, 3)
139 ZEND_ARG_INFO(0, str1)
140 ZEND_ARG_INFO(0, str2)
141 ZEND_ARG_INFO(0, len)
142 ZEND_END_ARG_INFO()
143
144 static
145 ZEND_BEGIN_ARG_INFO_EX(arginfo_each, 0, 0, 1)
146 ZEND_ARG_INFO(1, arr)
147 ZEND_END_ARG_INFO()
148
149 static
150 ZEND_BEGIN_ARG_INFO_EX(arginfo_error_reporting, 0, 0, 1)
151 ZEND_ARG_INFO(0, new_error_level)
152 ZEND_END_ARG_INFO()
153
154 static
155 ZEND_BEGIN_ARG_INFO_EX(arginfo_define, 0, 0, 3)
156 ZEND_ARG_INFO(0, constant_name)
157 ZEND_ARG_INFO(0, value)
158 ZEND_ARG_INFO(0, case_sensitive)
159 ZEND_END_ARG_INFO()
160
161 static
162 ZEND_BEGIN_ARG_INFO_EX(arginfo_defined, 0, 0, 1)
163 ZEND_ARG_INFO(0, constant_name)
164 ZEND_END_ARG_INFO()
165
166 static
167 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class, 0, 0, 0)
168 ZEND_ARG_INFO(0, object)
169 ZEND_END_ARG_INFO()
170
171 static
172 ZEND_BEGIN_ARG_INFO(arginfo_get_called_class, 0)
173 ZEND_END_ARG_INFO()
174
175 static
176 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_parent_class, 0, 0, 0)
177 ZEND_ARG_INFO(0, object)
178 ZEND_END_ARG_INFO()
179
180 static
181 ZEND_BEGIN_ARG_INFO_EX(arginfo_is_subclass_of, 0, 0, 2)
182 ZEND_ARG_INFO(0, object)
183 ZEND_ARG_INFO(0, class_name)
184 ZEND_END_ARG_INFO()
185
186 static
187 ZEND_BEGIN_ARG_INFO_EX(arginfo_is_a, 0, 0, 2)
188 ZEND_ARG_INFO(0, object)
189 ZEND_ARG_INFO(0, class_name)
190 ZEND_END_ARG_INFO()
191
192 static
193 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_vars, 0, 0, 1)
194 ZEND_ARG_INFO(0, class_name)
195 ZEND_END_ARG_INFO()
196
197 static
198 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_object_vars, 0, 0, 1)
199 ZEND_ARG_INFO(0, obj)
200 ZEND_END_ARG_INFO()
201
202 static
203 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_methods, 0, 0, 1)
204 ZEND_ARG_INFO(0, class)
205 ZEND_END_ARG_INFO()
206
207 static
208 ZEND_BEGIN_ARG_INFO_EX(arginfo_method_exists, 0, 0, 2)
209 ZEND_ARG_INFO(0, object)
210 ZEND_ARG_INFO(0, method)
211 ZEND_END_ARG_INFO()
212
213 static
214 ZEND_BEGIN_ARG_INFO_EX(arginfo_property_exists, 0, 0, 2)
215 ZEND_ARG_INFO(0, object_or_class)
216 ZEND_ARG_INFO(0, property_name)
217 ZEND_END_ARG_INFO()
218
219 static
220 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_exists, 0, 0, 1)
221 ZEND_ARG_INFO(0, classname)
222 ZEND_ARG_INFO(0, autoload)
223 ZEND_END_ARG_INFO()
224
225 static
226 ZEND_BEGIN_ARG_INFO_EX(arginfo_interface_exists, 0, 0, 1)
227 ZEND_ARG_INFO(0, classname)
228 ZEND_ARG_INFO(0, autoload)
229 ZEND_END_ARG_INFO()
230
231 static
232 ZEND_BEGIN_ARG_INFO_EX(arginfo_function_exists, 0, 0, 1)
233 ZEND_ARG_INFO(0, function_name)
234 ZEND_END_ARG_INFO()
235
236 static
237 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_alias, 0, 0, 2)
238 ZEND_ARG_INFO(0, user_class_name)
239 ZEND_ARG_INFO(0, alias_name)
240 ZEND_ARG_INFO(0, autoload)
241 ZEND_END_ARG_INFO()
242
243 static
244 ZEND_BEGIN_ARG_INFO(arginfo_get_included_files, 0)
245 ZEND_END_ARG_INFO()
246
247 static
248 ZEND_BEGIN_ARG_INFO_EX(arginfo_trigger_error, 0, 0, 1)
249 ZEND_ARG_INFO(0, messsage)
250 ZEND_ARG_INFO(0, error_type)
251 ZEND_END_ARG_INFO()
252
253 static
254 ZEND_BEGIN_ARG_INFO_EX(arginfo_set_error_handler, 0, 0, 1)
255 ZEND_ARG_INFO(0, error_handler)
256 ZEND_ARG_INFO(0, error_types)
257 ZEND_END_ARG_INFO()
258
259 static
260 ZEND_BEGIN_ARG_INFO(arginfo_restore_error_handler, 0)
261 ZEND_END_ARG_INFO()
262
263 static
264 ZEND_BEGIN_ARG_INFO_EX(arginfo_set_exception_handler, 0, 0, 1)
265 ZEND_ARG_INFO(0, exception_handler)
266 ZEND_END_ARG_INFO()
267
268 static
269 ZEND_BEGIN_ARG_INFO(arginfo_restore_exception_handler, 0)
270 ZEND_END_ARG_INFO()
271
272 static
273 ZEND_BEGIN_ARG_INFO(arginfo_get_declared_classes, 0)
274 ZEND_END_ARG_INFO()
275
276 static
277 ZEND_BEGIN_ARG_INFO(arginfo_get_declared_interfaces, 0)
278 ZEND_END_ARG_INFO()
279
280 static
281 ZEND_BEGIN_ARG_INFO(arginfo_get_defined_functions, 0)
282 ZEND_END_ARG_INFO()
283
284 static
285 ZEND_BEGIN_ARG_INFO(arginfo_get_defined_vars, 0)
286 ZEND_END_ARG_INFO()
287
288 static
289 ZEND_BEGIN_ARG_INFO_EX(arginfo_create_function, 0, 0, 2)
290 ZEND_ARG_INFO(0, args)
291 ZEND_ARG_INFO(0, code)
292 ZEND_END_ARG_INFO()
293
294 static
295 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_resource_type, 0, 0, 1)
296 ZEND_ARG_INFO(0, res)
297 ZEND_END_ARG_INFO()
298
299 static
300 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_loaded_extensions, 0, 0, 0)
301 ZEND_ARG_INFO(0, zend_extensions)
302 ZEND_END_ARG_INFO()
303
304 static
305 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_defined_constants, 0, 0, 0)
306 ZEND_ARG_INFO(0, categorize)
307 ZEND_END_ARG_INFO()
308
309 static
310 ZEND_BEGIN_ARG_INFO(arginfo_debug_print_backtrace, 0)
311 ZEND_END_ARG_INFO()
312
313 static
314 ZEND_BEGIN_ARG_INFO_EX(arginfo_debug_backtrace, 0, 0, 0)
315 ZEND_ARG_INFO(0, provide_object)
316 ZEND_END_ARG_INFO()
317
318 static
319 ZEND_BEGIN_ARG_INFO_EX(arginfo_extension_loaded, 0, 0, 1)
320 ZEND_ARG_INFO(0, extension_name)
321 ZEND_END_ARG_INFO()
322
323 static
324 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_extension_funcs, 0, 0, 1)
325 ZEND_ARG_INFO(0, extension_name)
326 ZEND_END_ARG_INFO()
327
328 static
329 ZEND_BEGIN_ARG_INFO(arginfo_gc_collect_cycles, 0)
330 ZEND_END_ARG_INFO()
331
332 static
333 ZEND_BEGIN_ARG_INFO(arginfo_gc_enabled, 0)
334 ZEND_END_ARG_INFO()
335
336 static
337 ZEND_BEGIN_ARG_INFO(arginfo_gc_enable, 0)
338 ZEND_END_ARG_INFO()
339
340 static
341 ZEND_BEGIN_ARG_INFO(arginfo_gc_disable, 0)
342 ZEND_END_ARG_INFO()
343 /* }}} */
344
345 static const zend_function_entry builtin_functions[] = { /* {{{ */
346 ZEND_FE(zend_version, arginfo_zend_version)
347 ZEND_FE(func_num_args, arginfo_func_num_args)
348 ZEND_FE(func_get_arg, arginfo_func_get_arg)
349 ZEND_FE(func_get_args, arginfo_func_get_args)
350 { "strlen", zend_if_strlen, arginfo_strlen },
351 ZEND_FE(strcmp, arginfo_strcmp)
352 ZEND_FE(strncmp, arginfo_strncmp)
353 ZEND_FE(strcasecmp, arginfo_strcasecmp)
354 ZEND_FE(strncasecmp, arginfo_strncasecmp)
355 ZEND_FE(each, arginfo_each)
356 ZEND_FE(error_reporting, arginfo_error_reporting)
357 ZEND_FE(define, arginfo_define)
358 ZEND_FE(defined, arginfo_defined)
359 ZEND_FE(get_class, arginfo_get_class)
360 ZEND_FE(get_called_class, arginfo_get_called_class)
361 ZEND_FE(get_parent_class, arginfo_get_parent_class)
362 ZEND_FE(method_exists, arginfo_method_exists)
363 ZEND_FE(property_exists, arginfo_property_exists)
364 ZEND_FE(class_exists, arginfo_class_exists)
365 ZEND_FE(interface_exists, arginfo_interface_exists)
366 ZEND_FE(function_exists, arginfo_function_exists)
367 ZEND_FE(class_alias, arginfo_class_alias)
368 #if ZEND_DEBUG
369 ZEND_FE(leak, NULL)
370 #ifdef ZEND_TEST_EXCEPTIONS
371 ZEND_FE(crash, NULL)
372 #endif
373 #endif
374 ZEND_FE(get_included_files, arginfo_get_included_files)
375 ZEND_FALIAS(get_required_files, get_included_files, arginfo_get_included_files)
376 ZEND_FE(is_subclass_of, arginfo_is_subclass_of)
377 ZEND_FE(is_a, arginfo_is_a)
378 ZEND_FE(get_class_vars, arginfo_get_class_vars)
379 ZEND_FE(get_object_vars, arginfo_get_object_vars)
380 ZEND_FE(get_class_methods, arginfo_get_class_methods)
381 ZEND_FE(trigger_error, arginfo_trigger_error)
382 ZEND_FALIAS(user_error, trigger_error, arginfo_trigger_error)
383 ZEND_FE(set_error_handler, arginfo_set_error_handler)
384 ZEND_FE(restore_error_handler, arginfo_restore_error_handler)
385 ZEND_FE(set_exception_handler, arginfo_set_exception_handler)
386 ZEND_FE(restore_exception_handler, arginfo_restore_exception_handler)
387 ZEND_FE(get_declared_classes, arginfo_get_declared_classes)
388 ZEND_FE(get_declared_interfaces, arginfo_get_declared_interfaces)
389 ZEND_FE(get_defined_functions, arginfo_get_defined_functions)
390 ZEND_FE(get_defined_vars, arginfo_get_defined_vars)
391 ZEND_FE(create_function, arginfo_create_function)
392 ZEND_FE(get_resource_type, arginfo_get_resource_type)
393 ZEND_FE(get_loaded_extensions, arginfo_get_loaded_extensions)
394 ZEND_FE(extension_loaded, arginfo_extension_loaded)
395 ZEND_FE(get_extension_funcs, arginfo_get_extension_funcs)
396 ZEND_FE(get_defined_constants, arginfo_get_defined_constants)
397 ZEND_FE(debug_backtrace, arginfo_debug_backtrace)
398 ZEND_FE(debug_print_backtrace, arginfo_debug_print_backtrace)
399 #if ZEND_DEBUG
400 ZEND_FE(zend_test_func, NULL)
401 #ifdef ZTS
402 ZEND_FE(zend_thread_id, NULL)
403 #endif
404 #endif
405 ZEND_FE(gc_collect_cycles, arginfo_gc_collect_cycles)
406 ZEND_FE(gc_enabled, arginfo_gc_enabled)
407 ZEND_FE(gc_enable, arginfo_gc_enable)
408 ZEND_FE(gc_disable, arginfo_gc_disable)
409 { NULL, NULL, NULL }
410 };
411 /* }}} */
412
413 int zend_startup_builtin_functions(TSRMLS_D) /* {{{ */
414 {
415 return zend_register_functions(NULL, builtin_functions, NULL, MODULE_PERSISTENT TSRMLS_CC);
416 }
417 /* }}} */
418
419 void zend_shutdown_builtin_functions(TSRMLS_D) /* {{{ */
420 {
421 zend_unregister_functions(builtin_functions, -1, NULL TSRMLS_CC);
422 }
423 /* }}} */
424
425 /* {{{ proto string zend_version(void) U
426 Get the version of the Zend Engine */
427 ZEND_FUNCTION(zend_version)
428 {
429 RETURN_ASCII_STRINGL(ZEND_VERSION, sizeof(ZEND_VERSION)-1, 1);
430 }
431 /* }}} */
432
433 /* {{{ proto int func_num_args(void) U
434 Get the number of arguments that were passed to the function */
435 ZEND_FUNCTION(func_num_args)
436 {
437 zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
438
439 if (ex && ex->function_state.arguments) {
440 RETURN_LONG((long)(zend_uintptr_t)*(ex->function_state.arguments));
441 } else {
442 zend_error(E_WARNING, "func_num_args(): Called from the global scope - no function context");
443 RETURN_LONG(-1);
444 }
445 }
446 /* }}} */
447
448 /* {{{ proto mixed func_get_arg(int arg_num) U
449 Get the $arg_num'th argument that was passed to the function */
450 ZEND_FUNCTION(func_get_arg)
451 {
452 void **p;
453 int arg_count;
454 zval *arg;
455 long requested_offset;
456 zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
457
458 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &requested_offset) == FAILURE) {
459 return;
460 }
461
462 if (requested_offset < 0) {
463 zend_error(E_WARNING, "func_get_arg(): The argument number should be >= 0");
464 RETURN_FALSE;
465 }
466
467 if (!ex || !ex->function_state.arguments) {
468 zend_error(E_WARNING, "func_get_arg(): Called from the global scope - no function context");
469 RETURN_FALSE;
470 }
471
472 p = ex->function_state.arguments;
473 arg_count = (int)(zend_uintptr_t) *p; /* this is the amount of arguments passed to func_get_arg(); */
474
475 if (requested_offset >= arg_count) {
476 zend_error(E_WARNING, "func_get_arg(): Argument %ld not passed to function", requested_offset);
477 RETURN_FALSE;
478 }
479
480 arg = *(p-(arg_count-requested_offset));
481 *return_value = *arg;
482 zval_copy_ctor(return_value);
483 INIT_PZVAL(return_value);
484 }
485 /* }}} */
486
487 /* {{{ proto array func_get_args() U
488 Get an array of the arguments that were passed to the function */
489 ZEND_FUNCTION(func_get_args)
490 {
491 void **p;
492 int arg_count;
493 int i;
494 zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
495
496 if (!ex || !ex->function_state.arguments) {
497 zend_error(E_WARNING, "func_get_args(): Called from the global scope - no function context");
498 RETURN_FALSE;
499 }
500
501 p = ex->function_state.arguments;
502 arg_count = (int)(zend_uintptr_t) *p; /* this is the amount of arguments passed to func_get_args(); */
503
504 array_init_size(return_value, arg_count);
505 for (i=0; i<arg_count; i++) {
506 zval *element;
507
508 ALLOC_ZVAL(element);
509 *element = **((zval **) (p-(arg_count-i)));
510 zval_copy_ctor(element);
511 INIT_PZVAL(element);
512 zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &element, sizeof(zval *), NULL);
513 }
514 }
515 /* }}} */
516
517 /* {{{ proto int strlen(string str) U
518 Get string length */
519 ZEND_NAMED_FUNCTION(zend_if_strlen)
520 {
521 zstr s1;
522 int s1_len;
523 zend_uchar s1_type;
524
525 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &s1, &s1_len, &s1_type) == FAILURE) {
526 return;
527 }
528
529 if(s1_type == IS_STRING) {
530 RETVAL_LONG(s1_len);
531 } else {
532 RETVAL_LONG(u_countChar32(s1.u, s1_len));
533 }
534 }
535 /* }}} */
536
537 /* {{{ proto int strcmp(string str1, string str2) U
538 Binary safe string comparison */
539 ZEND_FUNCTION(strcmp)
540 {
541 void *s1, *s2;
542 int s1_len, s2_len;
543 zend_uchar s1_type, s2_type;
544
545 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "TT", &s1, &s1_len,
546 &s1_type, &s2, &s2_len, &s2_type) == FAILURE) {
547 return;
548 }
549 if (s1_type == IS_UNICODE) {
550 RETURN_LONG(zend_u_binary_strcmp(s1, s1_len, s2, s2_len));
551 } else {
552 RETURN_LONG(zend_binary_strcmp(s1, s1_len, s2, s2_len));
553 }
554 }
555 /* }}} */
556
557 /* {{{ proto int strncmp(string str1, string str2, int len) U
558 Binary safe string comparison */
559 ZEND_FUNCTION(strncmp)
560 {
561 void *s1, *s2;
562 int s1_len, s2_len;
563 long count;
564 zend_uchar s1_type, s2_type;
565
566 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "TTl", &s1, &s1_len,
567 &s1_type, &s2, &s2_len, &s2_type, &count) == FAILURE) {
568 return;
569 }
570
571 if (count < 0) {
572 zend_error(E_WARNING, "Length must be greater than or equal to 0");
573 RETURN_FALSE;
574 }
575
576 if (s1_type == IS_UNICODE) {
577 RETURN_LONG(zend_u_binary_strncmp(s1, s1_len, s2, s2_len, count));
578 } else {
579 RETURN_LONG(zend_binary_strncmp(s1, s1_len, s2, s2_len, count));
580 }
581 }
582 /* }}} */
583
584 /* {{{ proto int strcasecmp(string str1, string str2) U
585 Binary safe case-insensitive string comparison */
586 ZEND_FUNCTION(strcasecmp)
587 {
588 void *s1, *s2;
589 int s1_len, s2_len;
590 zend_uchar s1_type, s2_type;
591
592 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "TT", &s1, &s1_len,
593 &s1_type, &s2, &s2_len, &s2_type) == FAILURE) {
594 return;
595 }
596 if (s1_type == IS_UNICODE) {
597 RETURN_LONG(zend_u_binary_strcasecmp(s1, s1_len, s2, s2_len));
598 } else {
599 RETURN_LONG(zend_binary_strcasecmp(s1, s1_len, s2, s2_len));
600 }
601 }
602 /* }}} */
603
604 /* {{{ proto int strncasecmp(string str1, string str2, int len) U
605 Binary safe string comparison */
606 ZEND_FUNCTION(strncasecmp)
607 {
608 void *s1, *s2;
609 int s1_len, s2_len;
610 zend_uchar s1_type, s2_type;
611 long len;
612
613 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "TTl", &s1, &s1_len,
614 &s1_type, &s2, &s2_len, &s2_type, &len) == FAILURE) {
615 return;
616 }
617
618 if (len < 0) {
619 zend_error(E_WARNING, "Length must be greater than or equal to 0");
620 RETURN_FALSE;
621 }
622
623 if (s1_type == IS_UNICODE) {
624 RETURN_LONG(zend_u_binary_strncasecmp(s1, s1_len, s2, s2_len, len));
625 } else {
626 RETURN_LONG(zend_binary_strcasecmp(s1, MIN(s1_len, len), s2, MIN(s2_len, len)));
627 }
628 }
629 /* }}} */
630
631 /* {{{ proto array each(array arr) U
632 Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element */
633 ZEND_FUNCTION(each)
634 {
635 zval *array, *entry, **entry_ptr, *tmp;
636 zstr string_key;
637 uint string_key_len;
638 ulong num_key;
639 zval **inserted_pointer;
640 HashTable *target_hash;
641
642 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &array) == FAILURE) {
643 return;
644 }
645
646 target_hash = HASH_OF(array);
647 if (!target_hash) {
648 zend_error(E_WARNING,"Variable passed to each() is not an array or object");
649 return;
650 }
651 if (zend_hash_get_current_data(target_hash, (void **) &entry_ptr)==FAILURE) {
652 RETURN_FALSE;
653 }
654 array_init(return_value);
655 entry = *entry_ptr;
656
657 /* add value elements */
658 if (Z_ISREF_P(entry)) {
659 ALLOC_ZVAL(tmp);
660 *tmp = *entry;
661 zval_copy_ctor(tmp);
662 Z_UNSET_ISREF_P(tmp);
663 Z_SET_REFCOUNT_P(tmp, 0);
664 entry=tmp;
665 }
666 zend_hash_index_update(Z_ARRVAL_P(return_value), 1, &entry, sizeof(zval *), NULL);
667 Z_ADDREF_P(entry);
668 zend_ascii_hash_update(Z_ARRVAL_P(return_value), "value", sizeof("value"), &entry, sizeof(zval *), NULL);
669 Z_ADDREF_P(entry);
670
671 /* add the key elements */
672 switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 1, NULL)) {
673 case HASH_KEY_IS_STRING:
674 add_get_index_stringl(return_value, 0, string_key.s, string_key_len-1, (void **) &inserted_pointer, 0);
675 break;
676 case HASH_KEY_IS_UNICODE:
677 add_get_index_unicodel(return_value, 0, string_key.u, string_key_len-1, (void **) &inserted_pointer, 0);
678 break;
679 case HASH_KEY_IS_LONG:
680 add_get_index_long(return_value, 0, num_key, (void **) &inserted_pointer);
681 break;
682 }
683 zend_ascii_hash_update(Z_ARRVAL_P(return_value), "key", sizeof("key"), inserted_pointer, sizeof(zval *), NULL);
684 Z_ADDREF_PP(inserted_pointer);
685 zend_hash_move_forward(target_hash);
686 }
687 /* }}} */
688
689 /* {{{ proto int error_reporting(int new_error_level=null) U
690 Return the current error_reporting level, and if an argument was passed - change to the new level */
691 ZEND_FUNCTION(error_reporting)
692 {
693 char *err;
694 int err_len;
695 int old_error_reporting;
696
697 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &err, &err_len) == FAILURE) {
698 return;
699 }
700
701 old_error_reporting = EG(error_reporting);
702 if(ZEND_NUM_ARGS() != 0) {
703 zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), err, err_len, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
704 }
705
706 RETVAL_LONG(old_error_reporting);
707 }
708 /* }}} */
709
710 /* {{{ proto bool define(string constant_name, mixed value, boolean case_sensitive=true) U
711 Define a new constant */
712 ZEND_FUNCTION(define)
713 {
714 zstr name;
715 int name_len;
716 zend_uchar name_type;
717 zval *val, *val_free = NULL;
718 zend_bool non_cs = 0;
719 int case_sensitive = CONST_CS;
720 zend_constant c;
721
722 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "tz|b", &name, &name_len, &name_type, &val, &non_cs) == FAILURE) {
723 return;
724 }
725
726 if(non_cs) {
727 case_sensitive = 0;
728 }
729
730 repeat:
731 switch (Z_TYPE_P(val)) {
732 case IS_LONG:
733 case IS_DOUBLE:
734 case IS_STRING:
735 case IS_UNICODE:
736 case IS_BOOL:
737 case IS_RESOURCE:
738 case IS_NULL:
739 break;
740 case IS_OBJECT:
741 if (!val_free) {
742 if (Z_OBJ_HT_P(val)->get) {
743 val_free = val = Z_OBJ_HT_P(val)->get(val TSRMLS_CC);
744 goto repeat;
745 } else if (Z_OBJ_HT_P(val)->cast_object) {
746 ALLOC_INIT_ZVAL(val_free);
747 if (Z_OBJ_HT_P(val)->cast_object(val, val_free, UG(unicode)?IS_UNICODE:IS_STRING, NULL TSRMLS_CC) == SUCCESS) {
748 val = val_free;
749 break;
750 }
751 }
752 }
753 /* no break */
754 default:
755 zend_error(E_WARNING,"Constants may only evaluate to scalar values");
756 if (val_free) {
757 zval_ptr_dtor(&val_free);
758 }
759 RETURN_FALSE;
760 }
761
762 c.value = *val;
763 zval_copy_ctor(&c.value);
764 if (val_free) {
765 zval_ptr_dtor(&val_free);
766 }
767 c.flags = case_sensitive; /* non persistent */
768 if (name_type == IS_UNICODE) {
769 c.name.u = zend_ustrndup(name.u, name_len);
770 } else {
771 c.name.s = zend_strndup(name.s, name_len);
772 }
773 c.name_len = name_len+1;
774 c.module_number = PHP_USER_CONSTANT;
775 if (zend_u_register_constant(name_type, &c TSRMLS_CC) == SUCCESS) {
776 RETURN_TRUE;
777 } else {
778 RETURN_FALSE;
779 }
780 }
781 /* }}} */
782
783 /* {{{ proto bool defined(string constant_name) U
784 Check whether a constant exists */
785 ZEND_FUNCTION(defined)
786 {
787 zstr name;
788 int name_len;
789 zend_uchar name_type;
790 zval c;
791
792 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &name, &name_len, &name_type) == FAILURE) {
793 return;
794 }
795
796 if (zend_u_get_constant_ex(name_type, name, name_len, &c, NULL, ZEND_FETCH_CLASS_SILENT TSRMLS_CC)) {
797 zval_dtor(&c);
798 RETURN_TRUE;
799 } else {
800 RETURN_FALSE;
801 }
802 }
803 /* }}} */
804
805 /* {{{ proto string get_class([object object]) U
806 Retrieves the class name */
807 ZEND_FUNCTION(get_class)
808 {
809 zval *obj = NULL;
810 zstr name = EMPTY_ZSTR;
811 zend_uint name_len = 0;
812 int dup;
813
814 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|o", &obj) == FAILURE) {
815 return;
816 }
817
818 if (!obj) {
819 if (EG(scope)) {
820 RETURN_TEXTL(EG(scope)->name, EG(scope)->name_length, 1);
821 } else {
822 zend_error(E_WARNING, "get_class() called without object from outside a class");
823 RETURN_FALSE;
824 }
825 }
826
827 dup = zend_get_object_classname(obj, &name, &name_len TSRMLS_CC);
828
829 RETURN_TEXTL(name, name_len, dup);
830 }
831 /* }}} */
832
833 /* {{{ proto string get_called_class() U
834 Retrieves the class name */
835 ZEND_FUNCTION(get_called_class)
836 {
837 if (zend_parse_parameters_none() == FAILURE) {
838 return;
839 }
840
841 if (EG(called_scope)) {
842 RETURN_TEXTL(EG(called_scope)->name, EG(called_scope)->name_length, 1);
843 } else {
844 zend_error(E_WARNING, "get_called_class() called from outside a class");
845 RETURN_FALSE;
846 }
847 }
848 /* }}} */
849
850
851 /* {{{ proto string get_parent_class([mixed object]) U
852 Retrieves the parent class name for object or class or current scope. */
853 ZEND_FUNCTION(get_parent_class)
854 {
855 zval *arg;
856 zend_class_entry *ce = NULL;
857 zstr name;
858 zend_uint name_length;
859
860 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &arg) == FAILURE) {
861 return;
862 }
863
864 if (!ZEND_NUM_ARGS()) {
865 ce = EG(scope);
866 if (ce && ce->parent) {
867 RETURN_TEXTL(ce->parent->name, ce->parent->name_length, 1);
868 } else {
869 RETURN_FALSE;
870 }
871 }
872
873 if (Z_TYPE_P(arg) == IS_OBJECT) {
874 if (Z_OBJ_HT_P(arg)->get_class_name
875 && Z_OBJ_HT_P(arg)->get_class_name(arg, &name, &name_length, 1 TSRMLS_CC) == SUCCESS) {
876 RETURN_TEXTL(name, name_length, 0);
877 } else {
878 ce = zend_get_class_entry(arg TSRMLS_CC);
879 }
880 } else if (Z_TYPE_P(arg) == (UG(unicode)?IS_UNICODE:IS_STRING)) {
881 zend_class_entry **pce;
882
883 if (zend_u_lookup_class(Z_TYPE_P(arg), Z_UNIVAL_P(arg), Z_UNILEN_P(arg), &pce TSRMLS_CC) == SUCCESS) {
884 ce = *pce;
885 }
886 }
887
888 if (ce && ce->parent) {
889 RETURN_TEXTL(ce->parent->name, ce->parent->name_length, 1);
890 } else {
891 RETURN_FALSE;
892 }
893 }
894 /* }}} */
895
896 static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass) /* {{{ */
897 {
898 zval *obj;
899 zstr class_name;
900 int class_name_len;
901 zend_uchar class_name_type;
902 zend_class_entry *instance_ce;
903 zend_class_entry **ce;
904 zend_bool retval;
905
906 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zt", &obj, &