Annotation of embedaddon/php/Zend/zend_builtin_functions.c, revision 1.1.1.5

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | Zend Engine                                                          |
                      4:    +----------------------------------------------------------------------+
1.1.1.5 ! misho       5:    | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
1.1       misho       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: 
1.1.1.2   misho      20: /* $Id$ */
1.1       misho      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_exceptions.h"
                     28: #include "zend_extensions.h"
                     29: #include "zend_closures.h"
                     30: 
                     31: #undef ZEND_TEST_EXCEPTIONS
                     32: 
                     33: static ZEND_FUNCTION(zend_version);
                     34: static ZEND_FUNCTION(func_num_args);
                     35: static ZEND_FUNCTION(func_get_arg);
                     36: static ZEND_FUNCTION(func_get_args);
                     37: static ZEND_FUNCTION(strlen);
                     38: static ZEND_FUNCTION(strcmp);
                     39: static ZEND_FUNCTION(strncmp);
                     40: static ZEND_FUNCTION(strcasecmp);
                     41: static ZEND_FUNCTION(strncasecmp);
                     42: static ZEND_FUNCTION(each);
                     43: static ZEND_FUNCTION(error_reporting);
                     44: static ZEND_FUNCTION(define);
                     45: static ZEND_FUNCTION(defined);
                     46: static ZEND_FUNCTION(get_class);
                     47: static ZEND_FUNCTION(get_called_class);
                     48: static ZEND_FUNCTION(get_parent_class);
                     49: static ZEND_FUNCTION(method_exists);
                     50: static ZEND_FUNCTION(property_exists);
                     51: static ZEND_FUNCTION(class_exists);
                     52: static ZEND_FUNCTION(interface_exists);
1.1.1.2   misho      53: static ZEND_FUNCTION(trait_exists);
1.1       misho      54: static ZEND_FUNCTION(function_exists);
                     55: static ZEND_FUNCTION(class_alias);
                     56: #if ZEND_DEBUG
                     57: static ZEND_FUNCTION(leak);
1.1.1.2   misho      58: static ZEND_FUNCTION(leak_variable);
1.1       misho      59: #ifdef ZEND_TEST_EXCEPTIONS
                     60: static ZEND_FUNCTION(crash);
                     61: #endif
                     62: #endif
                     63: static ZEND_FUNCTION(get_included_files);
                     64: static ZEND_FUNCTION(is_subclass_of);
                     65: static ZEND_FUNCTION(is_a);
                     66: static ZEND_FUNCTION(get_class_vars);
                     67: static ZEND_FUNCTION(get_object_vars);
                     68: static ZEND_FUNCTION(get_class_methods);
                     69: static ZEND_FUNCTION(trigger_error);
                     70: static ZEND_FUNCTION(set_error_handler);
                     71: static ZEND_FUNCTION(restore_error_handler);
                     72: static ZEND_FUNCTION(set_exception_handler);
                     73: static ZEND_FUNCTION(restore_exception_handler);
                     74: static ZEND_FUNCTION(get_declared_classes);
1.1.1.2   misho      75: static ZEND_FUNCTION(get_declared_traits);
1.1       misho      76: static ZEND_FUNCTION(get_declared_interfaces);
                     77: static ZEND_FUNCTION(get_defined_functions);
                     78: static ZEND_FUNCTION(get_defined_vars);
                     79: static ZEND_FUNCTION(create_function);
                     80: static ZEND_FUNCTION(get_resource_type);
                     81: static ZEND_FUNCTION(get_loaded_extensions);
                     82: static ZEND_FUNCTION(extension_loaded);
                     83: static ZEND_FUNCTION(get_extension_funcs);
                     84: static ZEND_FUNCTION(get_defined_constants);
                     85: static ZEND_FUNCTION(debug_backtrace);
                     86: static ZEND_FUNCTION(debug_print_backtrace);
                     87: #if ZEND_DEBUG
                     88: static ZEND_FUNCTION(zend_test_func);
                     89: #ifdef ZTS
                     90: static ZEND_FUNCTION(zend_thread_id);
                     91: #endif
                     92: #endif
                     93: static ZEND_FUNCTION(gc_collect_cycles);
                     94: static ZEND_FUNCTION(gc_enabled);
                     95: static ZEND_FUNCTION(gc_enable);
                     96: static ZEND_FUNCTION(gc_disable);
                     97: 
                     98: /* {{{ arginfo */
                     99: ZEND_BEGIN_ARG_INFO(arginfo_zend__void, 0)
                    100: ZEND_END_ARG_INFO()
                    101: 
                    102: ZEND_BEGIN_ARG_INFO_EX(arginfo_func_get_arg, 0, 0, 1)
                    103:        ZEND_ARG_INFO(0, arg_num)
                    104: ZEND_END_ARG_INFO()
                    105: 
                    106: ZEND_BEGIN_ARG_INFO_EX(arginfo_strlen, 0, 0, 1)
                    107:        ZEND_ARG_INFO(0, str)
                    108: ZEND_END_ARG_INFO()
                    109: 
                    110: ZEND_BEGIN_ARG_INFO_EX(arginfo_strcmp, 0, 0, 2)
                    111:        ZEND_ARG_INFO(0, str1)
                    112:        ZEND_ARG_INFO(0, str2)
                    113: ZEND_END_ARG_INFO()
                    114: 
                    115: ZEND_BEGIN_ARG_INFO_EX(arginfo_strncmp, 0, 0, 3)
                    116:        ZEND_ARG_INFO(0, str1)
                    117:        ZEND_ARG_INFO(0, str2)
                    118:        ZEND_ARG_INFO(0, len)
                    119: ZEND_END_ARG_INFO()
                    120: 
                    121: ZEND_BEGIN_ARG_INFO_EX(arginfo_each, 0, 0, 1)
                    122:        ZEND_ARG_INFO(1, arr)
                    123: ZEND_END_ARG_INFO()
                    124: 
                    125: ZEND_BEGIN_ARG_INFO_EX(arginfo_error_reporting, 0, 0, 0)
                    126:        ZEND_ARG_INFO(0, new_error_level)
                    127: ZEND_END_ARG_INFO()
                    128: 
                    129: ZEND_BEGIN_ARG_INFO_EX(arginfo_define, 0, 0, 3)
                    130:        ZEND_ARG_INFO(0, constant_name)
                    131:        ZEND_ARG_INFO(0, value)
                    132:        ZEND_ARG_INFO(0, case_insensitive)
                    133: ZEND_END_ARG_INFO()
                    134: 
                    135: ZEND_BEGIN_ARG_INFO_EX(arginfo_defined, 0, 0, 1)
                    136:        ZEND_ARG_INFO(0, constant_name)
                    137: ZEND_END_ARG_INFO()
                    138: 
                    139: ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class, 0, 0, 0)
                    140:        ZEND_ARG_INFO(0, object)
                    141: ZEND_END_ARG_INFO()
                    142: 
                    143: ZEND_BEGIN_ARG_INFO_EX(arginfo_is_subclass_of, 0, 0, 2)
                    144:        ZEND_ARG_INFO(0, object)
                    145:        ZEND_ARG_INFO(0, class_name)
1.1.1.2   misho     146:        ZEND_ARG_INFO(0, allow_string)
1.1       misho     147: ZEND_END_ARG_INFO()
                    148: 
                    149: ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_vars, 0, 0, 1)
                    150:        ZEND_ARG_INFO(0, class_name)
                    151: ZEND_END_ARG_INFO()
                    152: 
                    153: ZEND_BEGIN_ARG_INFO_EX(arginfo_get_object_vars, 0, 0, 1)
                    154:        ZEND_ARG_INFO(0, obj)
                    155: ZEND_END_ARG_INFO()
                    156: 
                    157: ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_methods, 0, 0, 1)
                    158:        ZEND_ARG_INFO(0, class)
                    159: ZEND_END_ARG_INFO()
                    160: 
                    161: ZEND_BEGIN_ARG_INFO_EX(arginfo_method_exists, 0, 0, 2)
                    162:        ZEND_ARG_INFO(0, object)
                    163:        ZEND_ARG_INFO(0, method)
                    164: ZEND_END_ARG_INFO()
                    165: 
                    166: ZEND_BEGIN_ARG_INFO_EX(arginfo_property_exists, 0, 0, 2)
                    167:        ZEND_ARG_INFO(0, object_or_class)
                    168:        ZEND_ARG_INFO(0, property_name)
                    169: ZEND_END_ARG_INFO()
                    170: 
                    171: ZEND_BEGIN_ARG_INFO_EX(arginfo_class_exists, 0, 0, 1)
                    172:        ZEND_ARG_INFO(0, classname)
                    173:        ZEND_ARG_INFO(0, autoload)
                    174: ZEND_END_ARG_INFO()
                    175: 
1.1.1.2   misho     176: ZEND_BEGIN_ARG_INFO_EX(arginfo_trait_exists, 0, 0, 1)
                    177:        ZEND_ARG_INFO(0, traitname)
                    178:        ZEND_ARG_INFO(0, autoload)
                    179: ZEND_END_ARG_INFO()
                    180: 
1.1       misho     181: ZEND_BEGIN_ARG_INFO_EX(arginfo_function_exists, 0, 0, 1)
                    182:        ZEND_ARG_INFO(0, function_name)
                    183: ZEND_END_ARG_INFO()
                    184: 
                    185: ZEND_BEGIN_ARG_INFO_EX(arginfo_class_alias, 0, 0, 2)
                    186:        ZEND_ARG_INFO(0, user_class_name)
                    187:        ZEND_ARG_INFO(0, alias_name)
                    188:        ZEND_ARG_INFO(0, autoload)
                    189: ZEND_END_ARG_INFO()
                    190: 
1.1.1.2   misho     191: #if ZEND_DEBUG
                    192: ZEND_BEGIN_ARG_INFO_EX(arginfo_leak_variable, 0, 0, 1)
                    193:        ZEND_ARG_INFO(0, variable)
                    194:        ZEND_ARG_INFO(0, leak_data)
                    195: ZEND_END_ARG_INFO()
                    196: #endif
                    197: 
1.1       misho     198: ZEND_BEGIN_ARG_INFO_EX(arginfo_trigger_error, 0, 0, 1)
                    199:        ZEND_ARG_INFO(0, message)
                    200:        ZEND_ARG_INFO(0, error_type)
                    201: ZEND_END_ARG_INFO()
                    202: 
                    203: ZEND_BEGIN_ARG_INFO_EX(arginfo_set_error_handler, 0, 0, 1)
                    204:        ZEND_ARG_INFO(0, error_handler)
                    205:        ZEND_ARG_INFO(0, error_types)
                    206: ZEND_END_ARG_INFO()
                    207: 
                    208: ZEND_BEGIN_ARG_INFO_EX(arginfo_set_exception_handler, 0, 0, 1)
                    209:        ZEND_ARG_INFO(0, exception_handler)
                    210: ZEND_END_ARG_INFO()
                    211: 
                    212: ZEND_BEGIN_ARG_INFO_EX(arginfo_create_function, 0, 0, 2)
                    213:        ZEND_ARG_INFO(0, args)
                    214:        ZEND_ARG_INFO(0, code)
                    215: ZEND_END_ARG_INFO()
                    216: 
                    217: ZEND_BEGIN_ARG_INFO_EX(arginfo_get_resource_type, 0, 0, 1)
                    218:        ZEND_ARG_INFO(0, res)
                    219: ZEND_END_ARG_INFO()
                    220: 
                    221: ZEND_BEGIN_ARG_INFO_EX(arginfo_get_loaded_extensions, 0, 0, 0)
                    222:        ZEND_ARG_INFO(0, zend_extensions)
                    223: ZEND_END_ARG_INFO()
                    224: 
                    225: ZEND_BEGIN_ARG_INFO_EX(arginfo_get_defined_constants, 0, 0, 0)
                    226:        ZEND_ARG_INFO(0, categorize)
                    227: ZEND_END_ARG_INFO()
                    228: 
                    229: ZEND_BEGIN_ARG_INFO_EX(arginfo_debug_backtrace, 0, 0, 0)
                    230:        ZEND_ARG_INFO(0, options)
1.1.1.2   misho     231:        ZEND_ARG_INFO(0, limit)
                    232: ZEND_END_ARG_INFO()
                    233: 
                    234: ZEND_BEGIN_ARG_INFO_EX(arginfo_debug_print_backtrace, 0, 0, 0)
                    235:        ZEND_ARG_INFO(0, options)
1.1       misho     236: ZEND_END_ARG_INFO()
                    237: 
                    238: ZEND_BEGIN_ARG_INFO_EX(arginfo_extension_loaded, 0, 0, 1)
                    239:        ZEND_ARG_INFO(0, extension_name)
                    240: ZEND_END_ARG_INFO()
                    241: /* }}} */
                    242: 
                    243: static const zend_function_entry builtin_functions[] = { /* {{{ */
                    244:        ZEND_FE(zend_version,           arginfo_zend__void)
                    245:        ZEND_FE(func_num_args,          arginfo_zend__void)
                    246:        ZEND_FE(func_get_arg,           arginfo_func_get_arg)
                    247:        ZEND_FE(func_get_args,          arginfo_zend__void)
                    248:        ZEND_FE(strlen,                         arginfo_strlen)
                    249:        ZEND_FE(strcmp,                         arginfo_strcmp)
                    250:        ZEND_FE(strncmp,                        arginfo_strncmp)
                    251:        ZEND_FE(strcasecmp,                     arginfo_strcmp)
                    252:        ZEND_FE(strncasecmp,            arginfo_strncmp)
                    253:        ZEND_FE(each,                           arginfo_each)
                    254:        ZEND_FE(error_reporting,        arginfo_error_reporting)
                    255:        ZEND_FE(define,                         arginfo_define)
                    256:        ZEND_FE(defined,                        arginfo_defined)
                    257:        ZEND_FE(get_class,                      arginfo_get_class)
                    258:        ZEND_FE(get_called_class,       arginfo_zend__void)
                    259:        ZEND_FE(get_parent_class,       arginfo_get_class)
                    260:        ZEND_FE(method_exists,          arginfo_method_exists)
                    261:        ZEND_FE(property_exists,        arginfo_property_exists)
                    262:        ZEND_FE(class_exists,           arginfo_class_exists)
                    263:        ZEND_FE(interface_exists,       arginfo_class_exists)
1.1.1.2   misho     264:        ZEND_FE(trait_exists,           arginfo_trait_exists)
1.1       misho     265:        ZEND_FE(function_exists,        arginfo_function_exists)
                    266:        ZEND_FE(class_alias,            arginfo_class_alias)
                    267: #if ZEND_DEBUG
                    268:        ZEND_FE(leak,                           NULL)
1.1.1.2   misho     269:        ZEND_FE(leak_variable,          arginfo_leak_variable)
1.1       misho     270: #ifdef ZEND_TEST_EXCEPTIONS
                    271:        ZEND_FE(crash,                          NULL)
                    272: #endif
                    273: #endif
                    274:        ZEND_FE(get_included_files,     arginfo_zend__void)
                    275:        ZEND_FALIAS(get_required_files, get_included_files,             arginfo_zend__void)
                    276:        ZEND_FE(is_subclass_of,         arginfo_is_subclass_of)
                    277:        ZEND_FE(is_a,                           arginfo_is_subclass_of)
                    278:        ZEND_FE(get_class_vars,         arginfo_get_class_vars)
                    279:        ZEND_FE(get_object_vars,        arginfo_get_object_vars)
                    280:        ZEND_FE(get_class_methods,      arginfo_get_class_methods)
                    281:        ZEND_FE(trigger_error,          arginfo_trigger_error)
                    282:        ZEND_FALIAS(user_error,         trigger_error,          arginfo_trigger_error)
                    283:        ZEND_FE(set_error_handler,                      arginfo_set_error_handler)
                    284:        ZEND_FE(restore_error_handler,          arginfo_zend__void)
                    285:        ZEND_FE(set_exception_handler,          arginfo_set_exception_handler)
                    286:        ZEND_FE(restore_exception_handler,      arginfo_zend__void)
                    287:        ZEND_FE(get_declared_classes,           arginfo_zend__void)
1.1.1.2   misho     288:        ZEND_FE(get_declared_traits,            arginfo_zend__void)
1.1       misho     289:        ZEND_FE(get_declared_interfaces,        arginfo_zend__void)
                    290:        ZEND_FE(get_defined_functions,          arginfo_zend__void)
                    291:        ZEND_FE(get_defined_vars,                       arginfo_zend__void)
                    292:        ZEND_FE(create_function,                        arginfo_create_function)
                    293:        ZEND_FE(get_resource_type,                      arginfo_get_resource_type)
                    294:        ZEND_FE(get_loaded_extensions,          arginfo_get_loaded_extensions)
                    295:        ZEND_FE(extension_loaded,                       arginfo_extension_loaded)
                    296:        ZEND_FE(get_extension_funcs,            arginfo_extension_loaded)
                    297:        ZEND_FE(get_defined_constants,          arginfo_get_defined_constants)
                    298:        ZEND_FE(debug_backtrace,                        arginfo_debug_backtrace)
1.1.1.2   misho     299:        ZEND_FE(debug_print_backtrace,          arginfo_debug_print_backtrace)
1.1       misho     300: #if ZEND_DEBUG
                    301:        ZEND_FE(zend_test_func,         NULL)
                    302: #ifdef ZTS
                    303:        ZEND_FE(zend_thread_id,         NULL)
                    304: #endif
                    305: #endif
                    306:        ZEND_FE(gc_collect_cycles,      arginfo_zend__void)
                    307:        ZEND_FE(gc_enabled,             arginfo_zend__void)
                    308:        ZEND_FE(gc_enable,                      arginfo_zend__void)
                    309:        ZEND_FE(gc_disable,             arginfo_zend__void)
                    310:        ZEND_FE_END
                    311: };
                    312: /* }}} */
                    313: 
                    314: ZEND_MINIT_FUNCTION(core) { /* {{{ */
                    315:        zend_class_entry class_entry;
                    316: 
                    317:        INIT_CLASS_ENTRY(class_entry, "stdClass", NULL);
                    318:        zend_standard_class_def = zend_register_internal_class(&class_entry TSRMLS_CC);
                    319: 
                    320:        zend_register_default_classes(TSRMLS_C);
                    321: 
                    322:        return SUCCESS;
                    323: }
                    324: /* }}} */
                    325: 
                    326: zend_module_entry zend_builtin_module = { /* {{{ */
                    327:     STANDARD_MODULE_HEADER,
                    328:        "Core",
                    329:        builtin_functions,
                    330:        ZEND_MINIT(core),
                    331:        NULL,
                    332:        NULL,
                    333:        NULL,
                    334:        NULL,
                    335:        ZEND_VERSION,
                    336:        STANDARD_MODULE_PROPERTIES
                    337: };
                    338: /* }}} */
                    339: 
                    340: int zend_startup_builtin_functions(TSRMLS_D) /* {{{ */
                    341: {
                    342:        zend_builtin_module.module_number = 0;
                    343:        zend_builtin_module.type = MODULE_PERSISTENT;
                    344:        return (EG(current_module) = zend_register_module_ex(&zend_builtin_module TSRMLS_CC)) == NULL ? FAILURE : SUCCESS;
                    345: }
                    346: /* }}} */
                    347: 
                    348: /* {{{ proto string zend_version(void)
                    349:    Get the version of the Zend Engine */
                    350: ZEND_FUNCTION(zend_version)
                    351: {
                    352:        RETURN_STRINGL(ZEND_VERSION, sizeof(ZEND_VERSION)-1, 1);
                    353: }
                    354: /* }}} */
                    355: 
                    356: /* {{{ proto int gc_collect_cycles(void)
                    357:    Forces collection of any existing garbage cycles.
                    358:    Returns number of freed zvals */
                    359: ZEND_FUNCTION(gc_collect_cycles)
                    360: {
                    361:        RETURN_LONG(gc_collect_cycles(TSRMLS_C));
                    362: }
                    363: /* }}} */
                    364: 
                    365: /* {{{ proto void gc_enabled(void)
                    366:    Returns status of the circular reference collector */
                    367: ZEND_FUNCTION(gc_enabled)
                    368: {
                    369:        RETURN_BOOL(GC_G(gc_enabled));
                    370: }
                    371: /* }}} */
                    372: 
                    373: /* {{{ proto void gc_enable(void)
                    374:    Activates the circular reference collector */
                    375: ZEND_FUNCTION(gc_enable)
                    376: {
                    377:        zend_alter_ini_entry("zend.enable_gc", sizeof("zend.enable_gc"), "1", sizeof("1")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
                    378: }
                    379: /* }}} */
                    380: 
                    381: /* {{{ proto void gc_disable(void)
                    382:    Deactivates the circular reference collector */
                    383: ZEND_FUNCTION(gc_disable)
                    384: {
                    385:        zend_alter_ini_entry("zend.enable_gc", sizeof("zend.enable_gc"), "0", sizeof("0")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
                    386: }
                    387: /* }}} */
                    388: 
                    389: /* {{{ proto int func_num_args(void)
                    390:    Get the number of arguments that were passed to the function */
                    391: ZEND_FUNCTION(func_num_args)
                    392: {
                    393:        zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
                    394: 
                    395:        if (ex && ex->function_state.arguments) {
                    396:                RETURN_LONG((long)(zend_uintptr_t)*(ex->function_state.arguments));
                    397:        } else {
                    398:                zend_error(E_WARNING, "func_num_args():  Called from the global scope - no function context");
                    399:                RETURN_LONG(-1);
                    400:        }
                    401: }
                    402: /* }}} */
                    403: 
                    404: 
                    405: /* {{{ proto mixed func_get_arg(int arg_num)
                    406:    Get the $arg_num'th argument that was passed to the function */
                    407: ZEND_FUNCTION(func_get_arg)
                    408: {
                    409:        void **p;
                    410:        int arg_count;
                    411:        zval *arg;
                    412:        long requested_offset;
                    413:        zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
                    414: 
                    415:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &requested_offset) == FAILURE) {
                    416:                return;
                    417:        }
                    418: 
                    419:        if (requested_offset < 0) {
                    420:                zend_error(E_WARNING, "func_get_arg():  The argument number should be >= 0");
                    421:                RETURN_FALSE;
                    422:        }
                    423: 
                    424:        if (!ex || !ex->function_state.arguments) {
                    425:                zend_error(E_WARNING, "func_get_arg():  Called from the global scope - no function context");
                    426:                RETURN_FALSE;
                    427:        }
                    428: 
                    429:        p = ex->function_state.arguments;
                    430:        arg_count = (int)(zend_uintptr_t) *p;           /* this is the amount of arguments passed to func_get_arg(); */
                    431: 
                    432:        if (requested_offset >= arg_count) {
                    433:                zend_error(E_WARNING, "func_get_arg():  Argument %ld not passed to function", requested_offset);
                    434:                RETURN_FALSE;
                    435:        }
                    436: 
                    437:        arg = *(p-(arg_count-requested_offset));
                    438:        *return_value = *arg;
                    439:        zval_copy_ctor(return_value);
                    440:        INIT_PZVAL(return_value);
                    441: }
                    442: /* }}} */
                    443: 
                    444: 
                    445: /* {{{ proto array func_get_args()
                    446:    Get an array of the arguments that were passed to the function */
                    447: ZEND_FUNCTION(func_get_args)
                    448: {
                    449:        void **p;
                    450:        int arg_count;
                    451:        int i;
                    452:        zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
                    453: 
                    454:        if (!ex || !ex->function_state.arguments) {
                    455:                zend_error(E_WARNING, "func_get_args():  Called from the global scope - no function context");
                    456:                RETURN_FALSE;
                    457:        }
                    458: 
                    459:        p = ex->function_state.arguments;
                    460:        arg_count = (int)(zend_uintptr_t) *p;           /* this is the amount of arguments passed to func_get_args(); */
                    461: 
                    462:        array_init_size(return_value, arg_count);
                    463:        for (i=0; i<arg_count; i++) {
                    464:                zval *element;
                    465: 
                    466:                ALLOC_ZVAL(element);
                    467:                *element = **((zval **) (p-(arg_count-i)));
                    468:                zval_copy_ctor(element);
                    469:                INIT_PZVAL(element);
                    470:                zend_hash_next_index_insert(return_value->value.ht, &element, sizeof(zval *), NULL);
                    471:        }
                    472: }
                    473: /* }}} */
                    474: 
                    475: 
                    476: /* {{{ proto int strlen(string str)
                    477:    Get string length */
                    478: ZEND_FUNCTION(strlen)
                    479: {
                    480:        char *s1;
                    481:        int s1_len;
                    482: 
                    483:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s1, &s1_len) == FAILURE) {
                    484:                return;
                    485:        }
                    486: 
                    487:        RETVAL_LONG(s1_len);
                    488: }
                    489: /* }}} */
                    490: 
                    491: 
                    492: /* {{{ proto int strcmp(string str1, string str2)
                    493:    Binary safe string comparison */
                    494: ZEND_FUNCTION(strcmp)
                    495: {
                    496:        char *s1, *s2;
                    497:        int s1_len, s2_len;
                    498:        
                    499:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &s1, &s1_len, &s2, &s2_len) == FAILURE) {
                    500:                return;
                    501:        }
                    502: 
                    503:        RETURN_LONG(zend_binary_strcmp(s1, s1_len, s2, s2_len));
                    504: }
                    505: /* }}} */
                    506: 
                    507: 
                    508: /* {{{ proto int strncmp(string str1, string str2, int len)
                    509:    Binary safe string comparison */
                    510: ZEND_FUNCTION(strncmp)
                    511: {
                    512:        char *s1, *s2;
                    513:        int s1_len, s2_len;
                    514:        long len;
                    515: 
                    516:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &s1, &s1_len, &s2, &s2_len, &len) == FAILURE) {
                    517:                return;
                    518:        }
                    519: 
                    520:        if (len < 0) {
                    521:                zend_error(E_WARNING, "Length must be greater than or equal to 0");
                    522:                RETURN_FALSE;
                    523:        }
                    524: 
                    525:        RETURN_LONG(zend_binary_strncmp(s1, s1_len, s2, s2_len, len));
                    526: }
                    527: /* }}} */
                    528: 
                    529: 
                    530: /* {{{ proto int strcasecmp(string str1, string str2)
                    531:    Binary safe case-insensitive string comparison */
                    532: ZEND_FUNCTION(strcasecmp)
                    533: {
                    534:        char *s1, *s2;
                    535:        int s1_len, s2_len;
                    536:        
                    537:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &s1, &s1_len, &s2, &s2_len) == FAILURE) {
                    538:                return;
                    539:        }
                    540: 
                    541:        RETURN_LONG(zend_binary_strcasecmp(s1, s1_len, s2, s2_len));
                    542: }
                    543: /* }}} */
                    544: 
                    545: 
                    546: /* {{{ proto int strncasecmp(string str1, string str2, int len)
                    547:    Binary safe string comparison */
                    548: ZEND_FUNCTION(strncasecmp)
                    549: {
                    550:        char *s1, *s2;
                    551:        int s1_len, s2_len;
                    552:        long len;
                    553: 
                    554:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &s1, &s1_len, &s2, &s2_len, &len) == FAILURE) {
                    555:                return;
                    556:        }
                    557: 
                    558:        if (len < 0) {
                    559:                zend_error(E_WARNING, "Length must be greater than or equal to 0");
                    560:                RETURN_FALSE;
                    561:        }
                    562: 
                    563:        RETURN_LONG(zend_binary_strncasecmp(s1, s1_len, s2, s2_len, len));
                    564: }
                    565: /* }}} */
                    566: 
                    567: 
                    568: /* {{{ proto array each(array arr)
                    569:    Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element */
                    570: ZEND_FUNCTION(each)
                    571: {
                    572:        zval *array, *entry, **entry_ptr, *tmp;
                    573:        char *string_key;
                    574:        uint string_key_len;
                    575:        ulong num_key;
                    576:        zval **inserted_pointer;
                    577:        HashTable *target_hash;
                    578: 
                    579:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &array) == FAILURE) {
                    580:                return;
                    581:        }
                    582: 
                    583:        target_hash = HASH_OF(array);
                    584:        if (!target_hash) {
                    585:                zend_error(E_WARNING,"Variable passed to each() is not an array or object");
                    586:                return;
                    587:        }
                    588:        if (zend_hash_get_current_data(target_hash, (void **) &entry_ptr)==FAILURE) {
                    589:                RETURN_FALSE;
                    590:        }
                    591:        array_init(return_value);
                    592:        entry = *entry_ptr;
                    593: 
                    594:        /* add value elements */
                    595:        if (Z_ISREF_P(entry)) {
                    596:                ALLOC_ZVAL(tmp);
                    597:                *tmp = *entry;
                    598:                zval_copy_ctor(tmp);
                    599:                Z_UNSET_ISREF_P(tmp);
                    600:                Z_SET_REFCOUNT_P(tmp, 0);
                    601:                entry=tmp;
                    602:        }
                    603:        zend_hash_index_update(return_value->value.ht, 1, &entry, sizeof(zval *), NULL);
                    604:        Z_ADDREF_P(entry);
                    605:        zend_hash_update(return_value->value.ht, "value", sizeof("value"), &entry, sizeof(zval *), NULL);
                    606:        Z_ADDREF_P(entry);
                    607: 
                    608:        /* add the key elements */
                    609:        switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 1, NULL)) {
                    610:                case HASH_KEY_IS_STRING:
                    611:                        add_get_index_stringl(return_value, 0, string_key, string_key_len-1, (void **) &inserted_pointer, 0);
                    612:                        break;
                    613:                case HASH_KEY_IS_LONG:
                    614:                        add_get_index_long(return_value, 0, num_key, (void **) &inserted_pointer);
                    615:                        break;
                    616:        }
                    617:        zend_hash_update(return_value->value.ht, "key", sizeof("key"), inserted_pointer, sizeof(zval *), NULL);
                    618:        Z_ADDREF_PP(inserted_pointer);
                    619:        zend_hash_move_forward(target_hash);
                    620: }
                    621: /* }}} */
                    622: 
                    623: 
                    624: /* {{{ proto int error_reporting([int new_error_level])
                    625:    Return the current error_reporting level, and if an argument was passed - change to the new level */
                    626: ZEND_FUNCTION(error_reporting)
                    627: {
                    628:        char *err;
                    629:        int err_len;
                    630:        int old_error_reporting;
                    631: 
                    632:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &err, &err_len) == FAILURE) {
                    633:                return;
                    634:        }
                    635: 
                    636:        old_error_reporting = EG(error_reporting);
                    637:        if(ZEND_NUM_ARGS() != 0) {
                    638:                zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), err, err_len, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
                    639:        }
                    640: 
                    641:        RETVAL_LONG(old_error_reporting);
                    642: }
                    643: /* }}} */
                    644: 
                    645: 
                    646: /* {{{ proto bool define(string constant_name, mixed value, boolean case_insensitive=false)
                    647:    Define a new constant */
                    648: ZEND_FUNCTION(define)
                    649: {
                    650:        char *name;
                    651:        int name_len;
                    652:        zval *val;
                    653:        zval *val_free = NULL;
                    654:        zend_bool non_cs = 0;
                    655:        int case_sensitive = CONST_CS;
                    656:        zend_constant c;
                    657: 
                    658:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &name, &name_len, &val, &non_cs) == FAILURE) {
                    659:                return;
                    660:        }
                    661: 
                    662:        if(non_cs) {
                    663:                case_sensitive = 0;
                    664:        }
                    665: 
                    666:        /* class constant, check if there is name and make sure class is valid & exists */
                    667:        if (zend_memnstr(name, "::", sizeof("::") - 1, name + name_len)) {
                    668:                zend_error(E_WARNING, "Class constants cannot be defined or redefined");
                    669:                RETURN_FALSE;
                    670:        }
                    671: 
                    672: repeat:
                    673:        switch (Z_TYPE_P(val)) {
                    674:                case IS_LONG:
                    675:                case IS_DOUBLE:
                    676:                case IS_STRING:
                    677:                case IS_BOOL:
                    678:                case IS_RESOURCE:
                    679:                case IS_NULL:
                    680:                        break;
                    681:                case IS_OBJECT:
                    682:                        if (!val_free) {
                    683:                                if (Z_OBJ_HT_P(val)->get) {
                    684:                                        val_free = val = Z_OBJ_HT_P(val)->get(val TSRMLS_CC);
                    685:                                        goto repeat;
                    686:                                } else if (Z_OBJ_HT_P(val)->cast_object) {
                    687:                                        ALLOC_INIT_ZVAL(val_free);
                    688:                                        if (Z_OBJ_HT_P(val)->cast_object(val, val_free, IS_STRING TSRMLS_CC) == SUCCESS) {
                    689:                                                val = val_free;
                    690:                                                break;
                    691:                                        }
                    692:                                }
                    693:                        }
                    694:                        /* no break */
                    695:                default:
                    696:                        zend_error(E_WARNING,"Constants may only evaluate to scalar values");
                    697:                        if (val_free) {
                    698:                                zval_ptr_dtor(&val_free);
                    699:                        }
                    700:                        RETURN_FALSE;
                    701:        }
                    702:        
                    703:        c.value = *val;
                    704:        zval_copy_ctor(&c.value);
                    705:        if (val_free) {
                    706:                zval_ptr_dtor(&val_free);
                    707:        }
                    708:        c.flags = case_sensitive; /* non persistent */
1.1.1.2   misho     709:        c.name = IS_INTERNED(name) ? name : zend_strndup(name, name_len);
                    710:        if(c.name == NULL) {
                    711:                RETURN_FALSE;
                    712:        }
1.1       misho     713:        c.name_len = name_len+1;
                    714:        c.module_number = PHP_USER_CONSTANT;
                    715:        if (zend_register_constant(&c TSRMLS_CC) == SUCCESS) {
                    716:                RETURN_TRUE;
                    717:        } else {
                    718:                RETURN_FALSE;
                    719:        }
                    720: }
                    721: /* }}} */
                    722: 
                    723: 
                    724: /* {{{ proto bool defined(string constant_name)
                    725:    Check whether a constant exists */
                    726: ZEND_FUNCTION(defined)
                    727: {
                    728:        char *name;
                    729:        int name_len;
                    730:        zval c;
                    731: 
                    732:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
                    733:                return;
                    734:        }
                    735:        
                    736:        if (zend_get_constant_ex(name, name_len, &c, NULL, ZEND_FETCH_CLASS_SILENT TSRMLS_CC)) {
                    737:                zval_dtor(&c);
                    738:                RETURN_TRUE;
                    739:        } else {
                    740:                RETURN_FALSE;
                    741:        }
                    742: }
                    743: /* }}} */
                    744: 
                    745: 
                    746: /* {{{ proto string get_class([object object])
                    747:    Retrieves the class name */
                    748: ZEND_FUNCTION(get_class)
                    749: {
                    750:        zval *obj = NULL;
1.1.1.2   misho     751:        const char *name = "";
1.1       misho     752:        zend_uint name_len = 0;
                    753:        int dup;
                    754: 
                    755:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|o!", &obj) == FAILURE) {
                    756:                RETURN_FALSE;
                    757:        }
                    758: 
                    759:        if (!obj) {
                    760:                if (EG(scope)) {
                    761:                        RETURN_STRINGL(EG(scope)->name, EG(scope)->name_length, 1);
                    762:                } else {
                    763:                        zend_error(E_WARNING, "get_class() called without object from outside a class");
                    764:                        RETURN_FALSE;
                    765:                }
                    766:        }
                    767: 
                    768:        dup = zend_get_object_classname(obj, &name, &name_len TSRMLS_CC);
                    769: 
                    770:        RETURN_STRINGL(name, name_len, dup);
                    771: }
                    772: /* }}} */
                    773: 
                    774: 
                    775: /* {{{ proto string get_called_class()
                    776:    Retrieves the "Late Static Binding" class name */
                    777: ZEND_FUNCTION(get_called_class)
                    778: {
                    779:        if (zend_parse_parameters_none() == FAILURE) {
                    780:                return;
                    781:        }
                    782: 
                    783:        if (EG(called_scope)) {
                    784:                RETURN_STRINGL(EG(called_scope)->name, EG(called_scope)->name_length, 1);
                    785:        } else if (!EG(scope))  {
                    786:                zend_error(E_WARNING, "get_called_class() called from outside a class");
                    787:        }
                    788:        RETURN_FALSE;
                    789: }
                    790: /* }}} */
                    791: 
                    792: 
                    793: /* {{{ proto string get_parent_class([mixed object])
                    794:    Retrieves the parent class name for object or class or current scope. */
                    795: ZEND_FUNCTION(get_parent_class)
                    796: {
                    797:        zval *arg;
                    798:        zend_class_entry *ce = NULL;
1.1.1.2   misho     799:        const char *name;
1.1       misho     800:        zend_uint name_length;
                    801:        
                    802:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &arg) == FAILURE) {
                    803:                return;
                    804:        }
                    805: 
                    806:        if (!ZEND_NUM_ARGS()) {
                    807:                ce = EG(scope);
                    808:                if (ce && ce->parent) {
                    809:                        RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
                    810:                } else {
                    811:                        RETURN_FALSE;
                    812:                }
                    813:        }
                    814: 
                    815:        if (Z_TYPE_P(arg) == IS_OBJECT) {
                    816:                if (Z_OBJ_HT_P(arg)->get_class_name
                    817:                        && Z_OBJ_HT_P(arg)->get_class_name(arg, &name, &name_length, 1 TSRMLS_CC) == SUCCESS) {
                    818:                        RETURN_STRINGL(name, name_length, 0);
                    819:                } else {
                    820:                        ce = zend_get_class_entry(arg TSRMLS_CC);
                    821:                }
                    822:        } else if (Z_TYPE_P(arg) == IS_STRING) {
                    823:                zend_class_entry **pce;
                    824:                
                    825:                if (zend_lookup_class(Z_STRVAL_P(arg), Z_STRLEN_P(arg), &pce TSRMLS_CC) == SUCCESS) {
                    826:                        ce = *pce;
                    827:                }
                    828:        }
                    829: 
                    830:        if (ce && ce->parent) {
                    831:                RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
                    832:        } else {
                    833:                RETURN_FALSE;
                    834:        }
                    835: }
                    836: /* }}} */
                    837: 
                    838: 
                    839: static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass)
                    840: {
                    841:        zval *obj;
                    842:        char *class_name;
                    843:        int class_name_len;
                    844:        zend_class_entry *instance_ce;
                    845:        zend_class_entry **ce;
                    846:        zend_bool allow_string = only_subclass;
                    847:        zend_bool retval;
                    848: 
                    849:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs|b", &obj, &class_name, &class_name_len, &allow_string) == FAILURE) {
                    850:                return;
                    851:        }
                    852:        /*
1.1.1.2   misho     853:         * allow_string - is_a default is no, is_subclass_of is yes. 
                    854:         *   if it's allowed, then the autoloader will be called if the class does not exist.
                    855:         *   default behaviour is different, as 'is_a' used to be used to test mixed return values
                    856:         *   and there is no easy way to deprecate this.
                    857:         */
1.1       misho     858: 
                    859:        if (allow_string && Z_TYPE_P(obj) == IS_STRING) {
                    860:                zend_class_entry **the_ce;
                    861:                if (zend_lookup_class(Z_STRVAL_P(obj), Z_STRLEN_P(obj), &the_ce TSRMLS_CC) == FAILURE) {
                    862:                        RETURN_FALSE;
                    863:                }
                    864:                instance_ce = *the_ce;
                    865:        } else if (Z_TYPE_P(obj) == IS_OBJECT && HAS_CLASS_ENTRY(*obj)) {
                    866:                instance_ce = Z_OBJCE_P(obj);
                    867:        } else {
                    868:                RETURN_FALSE;
                    869:        }
                    870: 
1.1.1.2   misho     871:        if (zend_lookup_class_ex(class_name, class_name_len, NULL, 0, &ce TSRMLS_CC) == FAILURE) {
1.1       misho     872:                retval = 0;
                    873:        } else {
                    874:                if (only_subclass && instance_ce == *ce) {
                    875:                        retval = 0;
1.1.1.2   misho     876:                } else {
1.1       misho     877:                        retval = instanceof_function(instance_ce, *ce TSRMLS_CC);
                    878:                }
                    879:        }
                    880: 
                    881:        RETURN_BOOL(retval);
                    882: }
                    883: 
                    884: 
                    885: /* {{{ proto bool is_subclass_of(mixed object_or_string, string class_name [, bool allow_string=true])
                    886:    Returns true if the object has this class as one of its parents */
                    887: ZEND_FUNCTION(is_subclass_of)
                    888: {
                    889:        is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
                    890: }
                    891: /* }}} */
                    892: 
                    893: 
                    894: /* {{{ proto bool is_a(mixed object_or_string, string class_name [, bool allow_string=false])
                    895:    Returns true if the first argument is an object and is this class or has this class as one of its parents, */
                    896: ZEND_FUNCTION(is_a)
                    897: {
                    898:        is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
                    899: }
                    900: /* }}} */
                    901: 
                    902: 
                    903: /* {{{ add_class_vars */
1.1.1.2   misho     904: static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value TSRMLS_DC)
1.1       misho     905: {
1.1.1.2   misho     906:        HashPosition pos;
                    907:        zend_property_info *prop_info;
                    908:        zval *prop, *prop_copy;
                    909:        char *key;
                    910:        uint key_len;
                    911:        ulong num_index;
1.1       misho     912: 
1.1.1.2   misho     913:        zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
                    914:        while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop_info, &pos) == SUCCESS) {
                    915:                zend_hash_get_current_key_ex(&ce->properties_info, &key, &key_len, &num_index, 0, &pos);
                    916:                zend_hash_move_forward_ex(&ce->properties_info, &pos);
                    917:                if (((prop_info->flags & ZEND_ACC_SHADOW) &&
                    918:                     prop_info->ce != EG(scope)) ||
                    919:                    ((prop_info->flags & ZEND_ACC_PROTECTED) &&
                    920:                     !zend_check_protected(prop_info->ce, EG(scope))) ||
                    921:                    ((prop_info->flags & ZEND_ACC_PRIVATE) &&
                    922:                      ce != EG(scope) &&
                    923:                          prop_info->ce != EG(scope))) {
                    924:                        continue;
                    925:                }
                    926:                prop = NULL;
                    927:                if (prop_info->offset >= 0) {
                    928:                        if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) {
                    929:                                prop = ce->default_static_members_table[prop_info->offset];
                    930:                        } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) {
                    931:                                prop = ce->default_properties_table[prop_info->offset];
                    932:                        }
                    933:                }
                    934:                if (!prop) {
                    935:                        continue;
                    936:                }
                    937: 
                    938:                /* copy: enforce read only access */
                    939:                ALLOC_ZVAL(prop_copy);
                    940:                *prop_copy = *prop;
                    941:                zval_copy_ctor(prop_copy);
                    942:                INIT_PZVAL(prop_copy);
                    943: 
                    944:                /* this is necessary to make it able to work with default array
                    945:                 * properties, returned to user */
                    946:                if (Z_TYPE_P(prop_copy) == IS_CONSTANT_ARRAY || (Z_TYPE_P(prop_copy) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
                    947:                        zval_update_constant(&prop_copy, 0 TSRMLS_CC);
1.1       misho     948:                }
1.1.1.2   misho     949: 
                    950:                add_assoc_zval(return_value, key, prop_copy);
1.1       misho     951:        }
                    952: }
                    953: /* }}} */
                    954: 
                    955: 
                    956: /* {{{ proto array get_class_vars(string class_name)
                    957:    Returns an array of default properties of the class. */
                    958: ZEND_FUNCTION(get_class_vars)
                    959: {
                    960:        char *class_name;
                    961:        int class_name_len;
                    962:        zend_class_entry **pce;
                    963: 
                    964:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &class_name, &class_name_len) == FAILURE) {
                    965:                return;
                    966:        }
                    967: 
                    968:        if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC) == FAILURE) {
                    969:                RETURN_FALSE;
                    970:        } else {
                    971:                array_init(return_value);
                    972:                zend_update_class_constants(*pce TSRMLS_CC);
1.1.1.2   misho     973:                add_class_vars(*pce, 0, return_value TSRMLS_CC);
                    974:                add_class_vars(*pce, 1, return_value TSRMLS_CC);
1.1       misho     975:        }
                    976: }
                    977: /* }}} */
                    978: 
                    979: 
                    980: /* {{{ proto array get_object_vars(object obj)
                    981:    Returns an array of object properties */
                    982: ZEND_FUNCTION(get_object_vars)
                    983: {
                    984:        zval *obj;
                    985:        zval **value;
                    986:        HashTable *properties;
                    987:        HashPosition pos;
1.1.1.2   misho     988:        char *key;
                    989:        const char *prop_name, *class_name;
1.1       misho     990:        uint key_len;
                    991:        ulong num_index;
                    992:        zend_object *zobj;
                    993: 
                    994:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
                    995:                return;
                    996:        }
                    997: 
                    998:        if (Z_OBJ_HT_P(obj)->get_properties == NULL) {
                    999:                RETURN_FALSE;
                   1000:        }
                   1001: 
                   1002:        properties = Z_OBJ_HT_P(obj)->get_properties(obj TSRMLS_CC);
                   1003: 
                   1004:        if (properties == NULL) {
                   1005:                RETURN_FALSE;
                   1006:        }
                   1007: 
                   1008:        zobj = zend_objects_get_address(obj TSRMLS_CC);
                   1009: 
                   1010:        array_init(return_value);
                   1011: 
                   1012:        zend_hash_internal_pointer_reset_ex(properties, &pos);
                   1013: 
                   1014:        while (zend_hash_get_current_data_ex(properties, (void **) &value, &pos) == SUCCESS) {
                   1015:                if (zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos) == HASH_KEY_IS_STRING) {
                   1016:                        if (zend_check_property_access(zobj, key, key_len-1 TSRMLS_CC) == SUCCESS) {
                   1017:                                zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
                   1018:                                /* Not separating references */
                   1019:                                Z_ADDREF_PP(value);
                   1020:                                add_assoc_zval_ex(return_value, prop_name, strlen(prop_name)+1, *value);
                   1021:                        }
                   1022:                }
                   1023:                zend_hash_move_forward_ex(properties, &pos);
                   1024:        }
                   1025: }
                   1026: /* }}} */
                   1027: 
1.1.1.3   misho    1028: static int same_name(const char *key, const char *name, zend_uint name_len)
                   1029: {
                   1030:        char *lcname = zend_str_tolower_dup(name, name_len);
                   1031:        int ret = memcmp(lcname, key, name_len) == 0;
                   1032:        efree(lcname);
                   1033:        return ret;
                   1034: }
1.1       misho    1035: 
                   1036: /* {{{ proto array get_class_methods(mixed class)
                   1037:    Returns an array of method names for class or class instance. */
                   1038: ZEND_FUNCTION(get_class_methods)
                   1039: {
                   1040:        zval *klass;
                   1041:        zval *method_name;
                   1042:        zend_class_entry *ce = NULL, **pce;
                   1043:        HashPosition pos;
                   1044:        zend_function *mptr;
                   1045: 
                   1046:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &klass) == FAILURE) {
                   1047:                return;
                   1048:        }
                   1049: 
                   1050:        if (Z_TYPE_P(klass) == IS_OBJECT) {
                   1051:                /* TBI!! new object handlers */
                   1052:                if (!HAS_CLASS_ENTRY(*klass)) {
                   1053:                        RETURN_FALSE;
                   1054:                }
                   1055:                ce = Z_OBJCE_P(klass);
                   1056:        } else if (Z_TYPE_P(klass) == IS_STRING) {
                   1057:                if (zend_lookup_class(Z_STRVAL_P(klass), Z_STRLEN_P(klass), &pce TSRMLS_CC) == SUCCESS) {
                   1058:                        ce = *pce;
                   1059:                }
                   1060:        }
                   1061: 
                   1062:        if (!ce) {
                   1063:                RETURN_NULL();
                   1064:        }
                   1065: 
                   1066:        array_init(return_value);
                   1067:        zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
                   1068: 
                   1069:        while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
                   1070:                if ((mptr->common.fn_flags & ZEND_ACC_PUBLIC) 
                   1071:                 || (EG(scope) &&
                   1072:                     (((mptr->common.fn_flags & ZEND_ACC_PROTECTED) &&
                   1073:                       zend_check_protected(mptr->common.scope, EG(scope)))
                   1074:                   || ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) &&
                   1075:                       EG(scope) == mptr->common.scope)))) {
                   1076:                        char *key;
                   1077:                        uint key_len;
                   1078:                        ulong num_index;
                   1079:                        uint len = strlen(mptr->common.function_name);
                   1080: 
                   1081:                        /* Do not display old-style inherited constructors */
1.1.1.3   misho    1082:                        if (zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len, &num_index, 0, &pos) != HASH_KEY_IS_STRING) {
1.1       misho    1083:                                MAKE_STD_ZVAL(method_name);
                   1084:                                ZVAL_STRINGL(method_name, mptr->common.function_name, len, 1);
                   1085:                                zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
1.1.1.3   misho    1086:                        } else if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 ||
                   1087:                            mptr->common.scope == ce ||
                   1088:                            zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0) {
                   1089: 
                   1090:                                if (mptr->type == ZEND_USER_FUNCTION &&
                   1091:                                    *mptr->op_array.refcount > 1 &&
                   1092:                                (len != key_len - 1 ||
                   1093:                                 !same_name(key, mptr->common.function_name, len))) {
                   1094:                                        MAKE_STD_ZVAL(method_name);
                   1095:                                        ZVAL_STRINGL(method_name, zend_find_alias_name(mptr->common.scope, key, key_len - 1), key_len - 1, 1);
                   1096:                                        zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
                   1097:                                } else {
                   1098:                                        MAKE_STD_ZVAL(method_name);
                   1099:                                        ZVAL_STRINGL(method_name, mptr->common.function_name, len, 1);
                   1100:                                        zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
                   1101:                                }
1.1       misho    1102:                        }
                   1103:                }
                   1104:                zend_hash_move_forward_ex(&ce->function_table, &pos);
                   1105:        }
                   1106: }
                   1107: /* }}} */
                   1108: 
                   1109: 
                   1110: /* {{{ proto bool method_exists(object object, string method)
                   1111:    Checks if the class method exists */
                   1112: ZEND_FUNCTION(method_exists)
                   1113: {
                   1114:        zval *klass; 
                   1115:        char *method_name;
                   1116:        int method_len;
                   1117:        char *lcname;
                   1118:        zend_class_entry * ce, **pce;
                   1119: 
                   1120:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &klass, &method_name, &method_len) == FAILURE) {
                   1121:                return;
                   1122:        }
                   1123:        if (Z_TYPE_P(klass) == IS_OBJECT) {
                   1124:                ce = Z_OBJCE_P(klass);
                   1125:        } else if (Z_TYPE_P(klass) == IS_STRING) {
                   1126:                if (zend_lookup_class(Z_STRVAL_P(klass), Z_STRLEN_P(klass), &pce TSRMLS_CC) == FAILURE) {
                   1127:                        RETURN_FALSE;
                   1128:                }
                   1129:                ce = *pce;
                   1130:        } else {
                   1131:                RETURN_FALSE;
                   1132:        }
                   1133: 
                   1134:        lcname = zend_str_tolower_dup(method_name, method_len);
                   1135:        if (zend_hash_exists(&ce->function_table, lcname, method_len+1)) {
                   1136:                efree(lcname);
                   1137:                RETURN_TRUE;
                   1138:        } else {
                   1139:                union _zend_function *func = NULL;
                   1140: 
                   1141:                if (Z_TYPE_P(klass) == IS_OBJECT 
                   1142:                && Z_OBJ_HT_P(klass)->get_method != NULL
1.1.1.2   misho    1143:                && (func = Z_OBJ_HT_P(klass)->get_method(&klass, method_name, method_len, NULL TSRMLS_CC)) != NULL
1.1       misho    1144:                ) {
                   1145:                        if (func->type == ZEND_INTERNAL_FUNCTION 
                   1146:                        && (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0
                   1147:                        ) {
                   1148:                                /* Returns true to the fake Closure's __invoke */
                   1149:                                RETVAL_BOOL((func->common.scope == zend_ce_closure
                   1150:                                        && (method_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
                   1151:                                        && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0) ? 1 : 0);
1.1.1.2   misho    1152:                                        
1.1       misho    1153:                                efree(lcname);
1.1.1.2   misho    1154:                                efree((char*)((zend_internal_function*)func)->function_name);
1.1       misho    1155:                                efree(func);
                   1156:                                return;
                   1157:                        }
                   1158:                        efree(lcname);
                   1159:                        RETURN_TRUE;
                   1160:                }
                   1161:        }
                   1162:        efree(lcname);
                   1163:        RETURN_FALSE;
                   1164: }
                   1165: /* }}} */
                   1166: 
                   1167: /* {{{ proto bool property_exists(mixed object_or_class, string property_name)
                   1168:    Checks if the object or class has a property */
                   1169: ZEND_FUNCTION(property_exists)
                   1170: {
                   1171:        zval *object;
                   1172:        char *property;
                   1173:        int property_len;
                   1174:        zend_class_entry *ce, **pce;
                   1175:        zend_property_info *property_info;
                   1176:        zval property_z;
                   1177:        ulong h;
                   1178: 
                   1179:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &object, &property, &property_len) == FAILURE) {
                   1180:                return;
                   1181:        }
                   1182: 
                   1183:        if (property_len == 0) {
                   1184:                RETURN_FALSE;
                   1185:        }
                   1186: 
                   1187:        if (Z_TYPE_P(object) == IS_STRING) {
                   1188:                if (zend_lookup_class(Z_STRVAL_P(object), Z_STRLEN_P(object), &pce TSRMLS_CC) == FAILURE) {
                   1189:                        RETURN_FALSE;
                   1190:                }
                   1191:                ce = *pce;
                   1192:        } else if (Z_TYPE_P(object) == IS_OBJECT) {
                   1193:                ce = Z_OBJCE_P(object);
                   1194:        } else {
                   1195:                zend_error(E_WARNING, "First parameter must either be an object or the name of an existing class");
                   1196:                RETURN_NULL();
                   1197:        }
                   1198: 
                   1199:        h = zend_get_hash_value(property, property_len+1);
                   1200:        if (zend_hash_quick_find(&ce->properties_info, property, property_len+1, h, (void **) &property_info) == SUCCESS
                   1201:                && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
                   1202:                RETURN_TRUE;
                   1203:        }
                   1204: 
                   1205:        ZVAL_STRINGL(&property_z, property, property_len, 0);
                   1206: 
                   1207:        if (Z_TYPE_P(object) ==  IS_OBJECT &&
                   1208:                Z_OBJ_HANDLER_P(object, has_property) && 
1.1.1.2   misho    1209:                Z_OBJ_HANDLER_P(object, has_property)(object, &property_z, 2, 0 TSRMLS_CC)) {
1.1       misho    1210:                RETURN_TRUE;
                   1211:        }
                   1212:        RETURN_FALSE;
                   1213: }
                   1214: /* }}} */
                   1215: 
                   1216: 
                   1217: /* {{{ proto bool class_exists(string classname [, bool autoload])
                   1218:    Checks if the class exists */
                   1219: ZEND_FUNCTION(class_exists)
                   1220: {
                   1221:        char *class_name, *lc_name;
                   1222:        zend_class_entry **ce;
                   1223:        int class_name_len;
                   1224:        int found;
                   1225:        zend_bool autoload = 1;
                   1226:        ALLOCA_FLAG(use_heap)
                   1227: 
                   1228:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &class_name, &class_name_len, &autoload) == FAILURE) {
                   1229:                return;
                   1230:        }
                   1231: 
                   1232:        if (!autoload) {
                   1233:                char *name;
                   1234:                int len;
                   1235: 
                   1236:                lc_name = do_alloca(class_name_len + 1, use_heap);
                   1237:                zend_str_tolower_copy(lc_name, class_name, class_name_len);
                   1238: 
                   1239:                /* Ignore leading "\" */
                   1240:                name = lc_name;
                   1241:                len = class_name_len;
                   1242:                if (lc_name[0] == '\\') {
                   1243:                        name = &lc_name[1];
                   1244:                        len--;
                   1245:                }
                   1246:        
                   1247:                found = zend_hash_find(EG(class_table), name, len+1, (void **) &ce);
                   1248:                free_alloca(lc_name, use_heap);
1.1.1.2   misho    1249:                RETURN_BOOL(found == SUCCESS && !(((*ce)->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT)) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
1.1       misho    1250:        }
                   1251: 
                   1252:        if (zend_lookup_class(class_name, class_name_len, &ce TSRMLS_CC) == SUCCESS) {
1.1.1.2   misho    1253:                RETURN_BOOL(((*ce)->ce_flags & (ZEND_ACC_INTERFACE | (ZEND_ACC_TRAIT - ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) == 0);
1.1       misho    1254:        } else {
                   1255:                RETURN_FALSE;
                   1256:        }
                   1257: }
                   1258: /* }}} */
                   1259: 
                   1260: /* {{{ proto bool interface_exists(string classname [, bool autoload])
                   1261:    Checks if the class exists */
                   1262: ZEND_FUNCTION(interface_exists)
                   1263: {
                   1264:        char *iface_name, *lc_name;
                   1265:        zend_class_entry **ce;
                   1266:        int iface_name_len;
                   1267:        int found;
                   1268:        zend_bool autoload = 1;
                   1269:        ALLOCA_FLAG(use_heap)
                   1270: 
                   1271:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &iface_name, &iface_name_len, &autoload) == FAILURE) {
                   1272:                return;
                   1273:        }
                   1274: 
                   1275:        if (!autoload) {
                   1276:                char *name;
                   1277:                int len;
                   1278:                
                   1279:                lc_name = do_alloca(iface_name_len + 1, use_heap);
                   1280:                zend_str_tolower_copy(lc_name, iface_name, iface_name_len);
                   1281:        
                   1282:                /* Ignore leading "\" */
                   1283:                name = lc_name;
                   1284:                len = iface_name_len;
                   1285:                if (lc_name[0] == '\\') {
                   1286:                        name = &lc_name[1];
                   1287:                        len--;
                   1288:                }
                   1289: 
                   1290:                found = zend_hash_find(EG(class_table), name, len+1, (void **) &ce);
                   1291:                free_alloca(lc_name, use_heap);
                   1292:                RETURN_BOOL(found == SUCCESS && (*ce)->ce_flags & ZEND_ACC_INTERFACE);
                   1293:        }
                   1294: 
                   1295:        if (zend_lookup_class(iface_name, iface_name_len, &ce TSRMLS_CC) == SUCCESS) {
                   1296:                RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_INTERFACE) > 0);
                   1297:        } else {
                   1298:                RETURN_FALSE;
                   1299:        }
                   1300: }
                   1301: /* }}} */
                   1302: 
1.1.1.2   misho    1303: /* {{{ proto bool trait_exists(string traitname [, bool autoload])
                   1304:  Checks if the trait exists */
                   1305: ZEND_FUNCTION(trait_exists)
                   1306: {
                   1307:        char *trait_name, *lc_name;
                   1308:        zend_class_entry **ce;
                   1309:        int trait_name_len;
                   1310:        int found;
                   1311:        zend_bool autoload = 1;
                   1312:        ALLOCA_FLAG(use_heap)
                   1313:   
                   1314:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &trait_name, &trait_name_len, &autoload) == FAILURE) {
                   1315:                return;
                   1316:        }
                   1317:   
                   1318:        if (!autoload) {
                   1319:                char *name;
                   1320:                int len;
                   1321:                
                   1322:                lc_name = do_alloca(trait_name_len + 1, use_heap);
                   1323:                zend_str_tolower_copy(lc_name, trait_name, trait_name_len);
                   1324:     
                   1325:                /* Ignore leading "\" */
                   1326:                name = lc_name;
                   1327:                len = trait_name_len;
                   1328:                if (lc_name[0] == '\\') {
                   1329:                        name = &lc_name[1];
                   1330:                        len--;
                   1331:                }
                   1332:     
                   1333:                found = zend_hash_find(EG(class_table), name, len+1, (void **) &ce);
                   1334:                free_alloca(lc_name, use_heap);
                   1335:                RETURN_BOOL(found == SUCCESS && (((*ce)->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
                   1336:        }
                   1337:   
                   1338:        if (zend_lookup_class(trait_name, trait_name_len, &ce TSRMLS_CC) == SUCCESS) {
                   1339:                RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
                   1340:        } else {
                   1341:                RETURN_FALSE;
                   1342:        }
                   1343: }
                   1344: /* }}} */
                   1345: 
1.1       misho    1346: 
                   1347: /* {{{ proto bool function_exists(string function_name) 
                   1348:    Checks if the function exists */
                   1349: ZEND_FUNCTION(function_exists)
                   1350: {
                   1351:        char *name;
                   1352:        int name_len;
                   1353:        zend_function *func;
                   1354:        char *lcname;
                   1355:        zend_bool retval;
                   1356:        
                   1357:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
                   1358:                return;
                   1359:        }
                   1360: 
                   1361:        lcname = zend_str_tolower_dup(name, name_len);
                   1362:        
                   1363:        /* Ignore leading "\" */
                   1364:        name = lcname;
                   1365:        if (lcname[0] == '\\') {
                   1366:                name = &lcname[1];
                   1367:                name_len--;
                   1368:        }
                   1369: 
                   1370:        retval = (zend_hash_find(EG(function_table), name, name_len+1, (void **)&func) == SUCCESS);
                   1371:        
                   1372:        efree(lcname);
                   1373: 
                   1374:        /*
                   1375:         * A bit of a hack, but not a bad one: we see if the handler of the function
                   1376:         * is actually one that displays "function is disabled" message.
                   1377:         */
                   1378:        if (retval && func->type == ZEND_INTERNAL_FUNCTION &&
                   1379:                func->internal_function.handler == zif_display_disabled_function) {
                   1380:                retval = 0;
                   1381:        }
                   1382: 
                   1383:        RETURN_BOOL(retval);
                   1384: }
                   1385: /* }}} */
                   1386: 
                   1387: /* {{{ proto bool class_alias(string user_class_name , string alias_name [, bool autoload])
                   1388:    Creates an alias for user defined class */
                   1389: ZEND_FUNCTION(class_alias)
                   1390: {
                   1391:        char *class_name, *lc_name, *alias_name;
                   1392:        zend_class_entry **ce;
                   1393:        int class_name_len, alias_name_len;
                   1394:        int found;
                   1395:        zend_bool autoload = 1;
                   1396:        ALLOCA_FLAG(use_heap)
                   1397: 
                   1398:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &class_name, &class_name_len, &alias_name, &alias_name_len, &autoload) == FAILURE) {
                   1399:                return;
                   1400:        }
                   1401: 
1.1.1.4   misho    1402:        found = zend_lookup_class_ex(class_name, class_name_len, NULL, autoload, &ce TSRMLS_CC);
1.1       misho    1403:        
                   1404:        if (found == SUCCESS) {
                   1405:                if ((*ce)->type == ZEND_USER_CLASS) { 
                   1406:                        if (zend_register_class_alias_ex(alias_name, alias_name_len, *ce TSRMLS_CC) == SUCCESS) {
                   1407:                                RETURN_TRUE;
                   1408:                        } else {
                   1409:                                zend_error(E_WARNING, "Cannot redeclare class %s", alias_name);
                   1410:                                RETURN_FALSE;
                   1411:                        }
                   1412:                } else {
                   1413:                        zend_error(E_WARNING, "First argument of class_alias() must be a name of user defined class");
                   1414:                        RETURN_FALSE;
                   1415:                }
                   1416:        } else {
                   1417:                zend_error(E_WARNING, "Class '%s' not found", class_name);
                   1418:                RETURN_FALSE;
                   1419:        }
                   1420: }
                   1421: /* }}} */
                   1422: 
                   1423: #if ZEND_DEBUG
                   1424: /* {{{ proto void leak(int num_bytes=3)
                   1425:    Cause an intentional memory leak, for testing/debugging purposes */
                   1426: ZEND_FUNCTION(leak)
                   1427: {
                   1428:        long leakbytes=3;
                   1429: 
                   1430:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &leakbytes) == FAILURE) {
                   1431:                return;
                   1432:        }
                   1433: 
                   1434:        emalloc(leakbytes);
                   1435: }
                   1436: /* }}} */
                   1437: 
1.1.1.2   misho    1438: /* {{{ proto leak_variable(mixed variable [, bool leak_data]) */
                   1439: ZEND_FUNCTION(leak_variable)
                   1440: {
                   1441:        zval *zv;
                   1442:        zend_bool leak_data = 0;
                   1443: 
                   1444:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &zv, &leak_data) == FAILURE) {
                   1445:                return;
                   1446:        }
                   1447: 
                   1448:        if (!leak_data) {
                   1449:                zval_add_ref(&zv);
                   1450:        } else if (Z_TYPE_P(zv) == IS_RESOURCE) {
                   1451:                zend_list_addref(Z_RESVAL_P(zv));
                   1452:        } else if (Z_TYPE_P(zv) == IS_OBJECT) {
                   1453:                Z_OBJ_HANDLER_P(zv, add_ref)(zv TSRMLS_CC);
                   1454:        } else {
                   1455:                zend_error(E_WARNING, "Leaking non-zval data is only applicable to resources and objects");
                   1456:        }
                   1457: }
                   1458: /* }}} */
                   1459: 
1.1       misho    1460: 
                   1461: #ifdef ZEND_TEST_EXCEPTIONS
                   1462: ZEND_FUNCTION(crash)
                   1463: {
                   1464:        char *nowhere=NULL;
                   1465: 
                   1466:        memcpy(nowhere, "something", sizeof("something"));
                   1467: }
                   1468: #endif
                   1469: 
                   1470: #endif /* ZEND_DEBUG */
                   1471: 
                   1472: /* {{{ proto array get_included_files(void)
                   1473:    Returns an array with the file names that were include_once()'d */
                   1474: ZEND_FUNCTION(get_included_files)
                   1475: {
                   1476:        char *entry;
1.1.1.2   misho    1477: 
1.1       misho    1478:        if (zend_parse_parameters_none() == FAILURE) {
                   1479:                return;
                   1480:        }
                   1481: 
                   1482:        array_init(return_value);
                   1483:        zend_hash_internal_pointer_reset(&EG(included_files));
                   1484:        while (zend_hash_get_current_key(&EG(included_files), &entry, NULL, 1) == HASH_KEY_IS_STRING) {
                   1485:                add_next_index_string(return_value, entry, 0);
                   1486:                zend_hash_move_forward(&EG(included_files));
                   1487:        }
                   1488: }
                   1489: /* }}} */
                   1490: 
                   1491: 
                   1492: /* {{{ proto void trigger_error(string message [, int error_type])
                   1493:    Generates a user-level error/warning/notice message */
                   1494: ZEND_FUNCTION(trigger_error)
                   1495: {
                   1496:        long error_type = E_USER_NOTICE;
                   1497:        char *message;
                   1498:        int message_len;
                   1499: 
                   1500:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &message, &message_len, &error_type) == FAILURE) {
                   1501:                return;
                   1502:        }
                   1503: 
                   1504:        switch (error_type) {
                   1505:                case E_USER_ERROR:
                   1506:                case E_USER_WARNING:
                   1507:                case E_USER_NOTICE:
                   1508:                case E_USER_DEPRECATED:
                   1509:                        break;
                   1510:                default:
                   1511:                        zend_error(E_WARNING, "Invalid error type specified");
                   1512:                        RETURN_FALSE;
                   1513:                        break;
                   1514:        }
                   1515: 
                   1516:        zend_error((int)error_type, "%s", message);
                   1517:        RETURN_TRUE;
                   1518: }
                   1519: /* }}} */
                   1520: 
                   1521: 
                   1522: /* {{{ proto string set_error_handler(string error_handler [, int error_types])
                   1523:    Sets a user-defined error handler function.  Returns the previously defined error handler, or false on error */
                   1524: ZEND_FUNCTION(set_error_handler)
                   1525: {
                   1526:        zval *error_handler;
                   1527:        zend_bool had_orig_error_handler=0;
                   1528:        char *error_handler_name = NULL;
1.1.1.2   misho    1529:        long error_type = E_ALL;
1.1       misho    1530: 
                   1531:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &error_handler, &error_type) == FAILURE) {
                   1532:                return;
                   1533:        }
                   1534: 
                   1535:        if (!zend_is_callable(error_handler, 0, &error_handler_name TSRMLS_CC)) {
                   1536:                zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
                   1537:                                   get_active_function_name(TSRMLS_C), error_handler_name?error_handler_name:"unknown");
                   1538:                efree(error_handler_name);
                   1539:                return;
                   1540:        }
                   1541:        efree(error_handler_name);
                   1542: 
                   1543:        if (EG(user_error_handler)) {
                   1544:                had_orig_error_handler = 1;
                   1545:                *return_value = *EG(user_error_handler);
                   1546:                zval_copy_ctor(return_value);
                   1547:                INIT_PZVAL(return_value);
                   1548:                zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting), sizeof(EG(user_error_handler_error_reporting)));
                   1549:                zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler));
                   1550:        }
                   1551:        ALLOC_ZVAL(EG(user_error_handler));
                   1552: 
                   1553:        if (!zend_is_true(error_handler)) { /* unset user-defined handler */
                   1554:                FREE_ZVAL(EG(user_error_handler));
                   1555:                EG(user_error_handler) = NULL;
                   1556:                RETURN_TRUE;
                   1557:        }
                   1558: 
                   1559:        EG(user_error_handler_error_reporting) = (int)error_type;
                   1560:        *EG(user_error_handler) = *error_handler;
                   1561:        zval_copy_ctor(EG(user_error_handler));
                   1562:        INIT_PZVAL(EG(user_error_handler));
                   1563: 
                   1564:        if (!had_orig_error_handler) {
                   1565:                RETURN_NULL();
                   1566:        }
                   1567: }
                   1568: /* }}} */
                   1569: 
                   1570: 
                   1571: /* {{{ proto void restore_error_handler(void)
                   1572:    Restores the previously defined error handler function */
                   1573: ZEND_FUNCTION(restore_error_handler)
                   1574: {
                   1575:        if (EG(user_error_handler)) {
                   1576:                zval *zeh = EG(user_error_handler);
                   1577: 
                   1578:                EG(user_error_handler) = NULL;
                   1579:                zval_ptr_dtor(&zeh);
                   1580:        }
                   1581: 
                   1582:        if (zend_ptr_stack_num_elements(&EG(user_error_handlers))==0) {
                   1583:                EG(user_error_handler) = NULL;
                   1584:        } else {
                   1585:                EG(user_error_handler_error_reporting) = zend_stack_int_top(&EG(user_error_handlers_error_reporting));
                   1586:                zend_stack_del_top(&EG(user_error_handlers_error_reporting));
                   1587:                EG(user_error_handler) = zend_ptr_stack_pop(&EG(user_error_handlers));
                   1588:        }
                   1589:        RETURN_TRUE;
                   1590: }
                   1591: /* }}} */
                   1592: 
                   1593: 
                   1594: /* {{{ proto string set_exception_handler(callable exception_handler)
                   1595:    Sets a user-defined exception handler function.  Returns the previously defined exception handler, or false on error */
                   1596: ZEND_FUNCTION(set_exception_handler)
                   1597: {
                   1598:        zval *exception_handler;
                   1599:        char *exception_handler_name = NULL;
                   1600:        zend_bool had_orig_exception_handler=0;
                   1601: 
                   1602:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &exception_handler) == FAILURE) {
                   1603:                return;
                   1604:        }
                   1605: 
                   1606:        if (Z_TYPE_P(exception_handler) != IS_NULL) { /* NULL == unset */
                   1607:                if (!zend_is_callable(exception_handler, 0, &exception_handler_name TSRMLS_CC)) {
                   1608:                        zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
                   1609:                                           get_active_function_name(TSRMLS_C), exception_handler_name?exception_handler_name:"unknown");
                   1610:                        efree(exception_handler_name);
                   1611:                        return;
                   1612:                }
                   1613:                efree(exception_handler_name);
                   1614:        }
                   1615: 
                   1616:        if (EG(user_exception_handler)) {
                   1617:                had_orig_exception_handler = 1;
                   1618:                *return_value = *EG(user_exception_handler);
                   1619:                zval_copy_ctor(return_value);
                   1620:                zend_ptr_stack_push(&EG(user_exception_handlers), EG(user_exception_handler));
                   1621:        }
                   1622:        ALLOC_ZVAL(EG(user_exception_handler));
                   1623: 
                   1624:        if (Z_TYPE_P(exception_handler) == IS_NULL) { /* unset user-defined handler */
                   1625:                FREE_ZVAL(EG(user_exception_handler));
                   1626:                EG(user_exception_handler) = NULL;
                   1627:                RETURN_TRUE;
                   1628:        }
                   1629: 
1.1.1.2   misho    1630:        MAKE_COPY_ZVAL(&exception_handler, EG(user_exception_handler))
1.1       misho    1631: 
                   1632:        if (!had_orig_exception_handler) {
                   1633:                RETURN_NULL();
                   1634:        }
                   1635: }
                   1636: /* }}} */
                   1637: 
                   1638: 
                   1639: /* {{{ proto void restore_exception_handler(void)
                   1640:    Restores the previously defined exception handler function */
                   1641: ZEND_FUNCTION(restore_exception_handler)
                   1642: {
                   1643:        if (EG(user_exception_handler)) {
                   1644:                zval_ptr_dtor(&EG(user_exception_handler));
                   1645:        }
                   1646:        if (zend_ptr_stack_num_elements(&EG(user_exception_handlers))==0) {
                   1647:                EG(user_exception_handler) = NULL;
                   1648:        } else {
                   1649:                EG(user_exception_handler) = zend_ptr_stack_pop(&EG(user_exception_handlers));
                   1650:        }
                   1651:        RETURN_TRUE;
                   1652: }
                   1653: /* }}} */
                   1654: 
                   1655: static int copy_class_or_interface_name(zend_class_entry **pce TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
                   1656: {
                   1657:        zval *array = va_arg(args, zval *);
                   1658:        zend_uint mask = va_arg(args, zend_uint);
                   1659:        zend_uint comply = va_arg(args, zend_uint);
                   1660:        zend_uint comply_mask = (comply)? mask:0;
                   1661:        zend_class_entry *ce  = *pce;
                   1662: 
                   1663:        if ((hash_key->nKeyLength==0 || hash_key->arKey[0]!=0)
                   1664:                && (comply_mask == (ce->ce_flags & mask))) {
1.1.1.3   misho    1665:                if (ce->refcount > 1 && 
                   1666:                    (ce->name_length != hash_key->nKeyLength - 1 || 
                   1667:                     !same_name(hash_key->arKey, ce->name, ce->name_length))) {
                   1668:                        add_next_index_stringl(array, hash_key->arKey, hash_key->nKeyLength - 1, 1);
                   1669:                } else {
                   1670:                        add_next_index_stringl(array, ce->name, ce->name_length, 1);
                   1671:                }
1.1       misho    1672:        }
                   1673:        return ZEND_HASH_APPLY_KEEP;
                   1674: }
                   1675: 
1.1.1.2   misho    1676: /* {{{ proto array get_declared_traits()
                   1677:    Returns an array of all declared traits. */
                   1678: ZEND_FUNCTION(get_declared_traits)
                   1679: {
                   1680:        zend_uint mask = ZEND_ACC_TRAIT;
                   1681:        zend_uint comply = 1;
                   1682: 
                   1683:        if (zend_parse_parameters_none() == FAILURE) {
                   1684:                return;
                   1685:        }
                   1686: 
                   1687:        array_init(return_value);
                   1688:        zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) copy_class_or_interface_name, 3, return_value, mask, comply);
                   1689: }
                   1690: /* }}} */
                   1691: 
1.1       misho    1692: 
                   1693: /* {{{ proto array get_declared_classes()
                   1694:    Returns an array of all declared classes. */
                   1695: ZEND_FUNCTION(get_declared_classes)
                   1696: {
1.1.1.2   misho    1697:        zend_uint mask = ZEND_ACC_INTERFACE | (ZEND_ACC_TRAIT & ~ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
1.1       misho    1698:        zend_uint comply = 0;
                   1699: 
                   1700:        if (zend_parse_parameters_none() == FAILURE) {
                   1701:                return;
                   1702:        }
                   1703: 
                   1704:        array_init(return_value);
                   1705:        zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) copy_class_or_interface_name, 3, return_value, mask, comply);
                   1706: }
                   1707: /* }}} */
                   1708: 
                   1709: /* {{{ proto array get_declared_interfaces()
                   1710:    Returns an array of all declared interfaces. */
                   1711: ZEND_FUNCTION(get_declared_interfaces)
                   1712: {
                   1713:        zend_uint mask = ZEND_ACC_INTERFACE;
                   1714:        zend_uint comply = 1;
                   1715: 
                   1716:        if (zend_parse_parameters_none() == FAILURE) {
                   1717:                return;
                   1718:        }
                   1719: 
                   1720:        array_init(return_value);
                   1721:        zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) copy_class_or_interface_name, 3, return_value, mask, comply);
                   1722: }
                   1723: /* }}} */
                   1724: 
                   1725: 
                   1726: static int copy_function_name(zend_function *func TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
                   1727: {
                   1728:        zval *internal_ar = va_arg(args, zval *),
                   1729:             *user_ar     = va_arg(args, zval *);
                   1730: 
                   1731:        if (hash_key->nKeyLength == 0 || hash_key->arKey[0] == 0) {
                   1732:                return 0;
                   1733:        }
                   1734: 
                   1735:        if (func->type == ZEND_INTERNAL_FUNCTION) {
                   1736:                add_next_index_stringl(internal_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
                   1737:        } else if (func->type == ZEND_USER_FUNCTION) {
                   1738:                add_next_index_stringl(user_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
                   1739:        }
                   1740: 
                   1741:        return 0;
                   1742: }
                   1743: 
                   1744: 
                   1745: /* {{{ proto array get_defined_functions(void)
                   1746:    Returns an array of all defined functions */
                   1747: ZEND_FUNCTION(get_defined_functions)
                   1748: {
                   1749:        zval *internal;
                   1750:        zval *user;
                   1751: 
                   1752:        if (zend_parse_parameters_none() == FAILURE) {
                   1753:                return;
                   1754:        }
                   1755: 
                   1756:        MAKE_STD_ZVAL(internal);
                   1757:        MAKE_STD_ZVAL(user);
                   1758: 
                   1759:        array_init(internal);
                   1760:        array_init(user);
                   1761:        array_init(return_value);
                   1762: 
                   1763:        zend_hash_apply_with_arguments(EG(function_table) TSRMLS_CC, (apply_func_args_t) copy_function_name, 2, internal, user);
                   1764: 
                   1765:        if (zend_hash_add(Z_ARRVAL_P(return_value), "internal", sizeof("internal"), (void **)&internal, sizeof(zval *), NULL) == FAILURE) {
                   1766:                zval_ptr_dtor(&internal);
                   1767:                zval_ptr_dtor(&user);
                   1768:                zval_dtor(return_value);
                   1769:                zend_error(E_WARNING, "Cannot add internal functions to return value from get_defined_functions()");
                   1770:                RETURN_FALSE;
                   1771:        }
                   1772: 
                   1773:        if (zend_hash_add(Z_ARRVAL_P(return_value), "user", sizeof("user"), (void **)&user, sizeof(zval *), NULL) == FAILURE) {
                   1774:                zval_ptr_dtor(&user);
                   1775:                zval_dtor(return_value);
                   1776:                zend_error(E_WARNING, "Cannot add user functions to return value from get_defined_functions()");
                   1777:                RETURN_FALSE;
                   1778:        }
                   1779: }
                   1780: /* }}} */
                   1781: 
                   1782: 
                   1783: /* {{{ proto array get_defined_vars(void)
                   1784:    Returns an associative array of names and values of all currently defined variable names (variables in the current scope) */
                   1785: ZEND_FUNCTION(get_defined_vars)
                   1786: {
                   1787:        if (!EG(active_symbol_table)) {
                   1788:                zend_rebuild_symbol_table(TSRMLS_C);
                   1789:        }
                   1790: 
                   1791:        array_init_size(return_value, zend_hash_num_elements(EG(active_symbol_table)));
                   1792: 
                   1793:        zend_hash_copy(Z_ARRVAL_P(return_value), EG(active_symbol_table),
                   1794:                                        (copy_ctor_func_t)zval_add_ref, NULL, sizeof(zval *));
                   1795: }
                   1796: /* }}} */
                   1797: 
                   1798: 
                   1799: #define LAMBDA_TEMP_FUNCNAME   "__lambda_func"
                   1800: /* {{{ proto string create_function(string args, string code)
                   1801:    Creates an anonymous function, and returns its name (funny, eh?) */
                   1802: ZEND_FUNCTION(create_function)
                   1803: {
                   1804:        char *eval_code, *function_name, *function_args, *function_code;
                   1805:        int eval_code_length, function_name_length, function_args_len, function_code_len;
                   1806:        int retval;
                   1807:        char *eval_name;
                   1808: 
                   1809:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &function_args, &function_args_len, &function_code, &function_code_len) == FAILURE) {
                   1810:                return;
                   1811:        }
                   1812: 
                   1813:        eval_code = (char *) emalloc(sizeof("function " LAMBDA_TEMP_FUNCNAME)
                   1814:                        +function_args_len
                   1815:                        +2      /* for the args parentheses */
                   1816:                        +2      /* for the curly braces */
                   1817:                        +function_code_len);
                   1818: 
                   1819:        eval_code_length = sizeof("function " LAMBDA_TEMP_FUNCNAME "(") - 1;
                   1820:        memcpy(eval_code, "function " LAMBDA_TEMP_FUNCNAME "(", eval_code_length);
                   1821: 
                   1822:        memcpy(eval_code + eval_code_length, function_args, function_args_len);
                   1823:        eval_code_length += function_args_len;
                   1824: 
                   1825:        eval_code[eval_code_length++] = ')';
                   1826:        eval_code[eval_code_length++] = '{';
                   1827: 
                   1828:        memcpy(eval_code + eval_code_length, function_code, function_code_len);
                   1829:        eval_code_length += function_code_len;
                   1830: 
                   1831:        eval_code[eval_code_length++] = '}';
                   1832:        eval_code[eval_code_length] = '\0';
                   1833: 
                   1834:        eval_name = zend_make_compiled_string_description("runtime-created function" TSRMLS_CC);
                   1835:        retval = zend_eval_stringl(eval_code, eval_code_length, NULL, eval_name TSRMLS_CC);
                   1836:        efree(eval_code);
                   1837:        efree(eval_name);
                   1838: 
                   1839:        if (retval==SUCCESS) {
                   1840:                zend_function new_function, *func;
                   1841: 
                   1842:                if (zend_hash_find(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME), (void **) &func)==FAILURE) {
                   1843:                        zend_error(E_ERROR, "Unexpected inconsistency in create_function()");
                   1844:                        RETURN_FALSE;
                   1845:                }
                   1846:                new_function = *func;
                   1847:                function_add_ref(&new_function);
                   1848: 
                   1849:                function_name = (char *) emalloc(sizeof("0lambda_")+MAX_LENGTH_OF_LONG);
                   1850:                function_name[0] = '\0';
                   1851: 
                   1852:                do {
                   1853:                        function_name_length = 1 + snprintf(function_name + 1, sizeof("lambda_")+MAX_LENGTH_OF_LONG, "lambda_%d", ++EG(lambda_count));
                   1854:                } while (zend_hash_add(EG(function_table), function_name, function_name_length+1, &new_function, sizeof(zend_function), NULL)==FAILURE);
                   1855:                zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME));
                   1856:                RETURN_STRINGL(function_name, function_name_length, 0);
                   1857:        } else {
                   1858:                zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME));
                   1859:                RETURN_FALSE;
                   1860:        }
                   1861: }
                   1862: /* }}} */
                   1863: 
                   1864: 
                   1865: #if ZEND_DEBUG
                   1866: ZEND_FUNCTION(zend_test_func)
                   1867: {
                   1868:        zval *arg1, *arg2;
                   1869: 
                   1870:        zend_get_parameters(ht, 2, &arg1, &arg2);
                   1871: }
                   1872: 
                   1873: 
                   1874: #ifdef ZTS
                   1875: ZEND_FUNCTION(zend_thread_id)
                   1876: {
                   1877:        RETURN_LONG((long)tsrm_thread_id());
                   1878: }
                   1879: #endif
                   1880: #endif
                   1881: 
                   1882: /* {{{ proto string get_resource_type(resource res)
                   1883:    Get the resource type name for a given resource */
                   1884: ZEND_FUNCTION(get_resource_type)
                   1885: {
1.1.1.2   misho    1886:        const char *resource_type;
1.1       misho    1887:        zval *z_resource_type;
                   1888: 
                   1889:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_resource_type) == FAILURE) {
                   1890:                return;
                   1891:        }
                   1892: 
                   1893:        resource_type = zend_rsrc_list_get_rsrc_type(Z_LVAL_P(z_resource_type) TSRMLS_CC);
                   1894:        if (resource_type) {
                   1895:                RETURN_STRING(resource_type, 1);
                   1896:        } else {
                   1897:                RETURN_STRING("Unknown", 1);
                   1898:        }
                   1899: }
                   1900: /* }}} */
                   1901: 
                   1902: 
                   1903: static int add_extension_info(zend_module_entry *module, void *arg TSRMLS_DC)
                   1904: {
                   1905:        zval *name_array = (zval *)arg;
                   1906:        add_next_index_string(name_array, module->name, 1);
                   1907:        return 0;
                   1908: }
                   1909: 
                   1910: static int add_zendext_info(zend_extension *ext, void *arg TSRMLS_DC)
                   1911: {
                   1912:        zval *name_array = (zval *)arg;
                   1913:        add_next_index_string(name_array, ext->name, 1);
                   1914:        return 0;
                   1915: }
                   1916: 
                   1917: static int add_constant_info(zend_constant *constant, void *arg TSRMLS_DC)
                   1918: {
                   1919:        zval *name_array = (zval *)arg;
                   1920:        zval *const_val;
                   1921: 
1.1.1.4   misho    1922:        if (!constant->name) {
                   1923:                /* skip special constants */
                   1924:                return 0;
                   1925:        }
                   1926: 
1.1       misho    1927:        MAKE_STD_ZVAL(const_val);
                   1928:        *const_val = constant->value;
                   1929:        zval_copy_ctor(const_val);
                   1930:        INIT_PZVAL(const_val);
                   1931:        add_assoc_zval_ex(name_array, constant->name, constant->name_len, const_val);
                   1932:        return 0;
                   1933: }
                   1934: 
                   1935: 
                   1936: /* {{{ proto array get_loaded_extensions([bool zend_extensions]) U
                   1937:    Return an array containing names of loaded extensions */
                   1938: ZEND_FUNCTION(get_loaded_extensions)
                   1939: {
                   1940:        zend_bool zendext = 0;
                   1941: 
                   1942:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &zendext) == FAILURE) {
                   1943:                return;
                   1944:        }
                   1945: 
                   1946:        array_init(return_value);
                   1947: 
                   1948:        if (zendext) {
                   1949:                zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) add_zendext_info, return_value TSRMLS_CC);
                   1950:        } else {
                   1951:                zend_hash_apply_with_argument(&module_registry, (apply_func_arg_t) add_extension_info, return_value TSRMLS_CC);
                   1952:        }
                   1953: }
                   1954: /* }}} */
                   1955: 
                   1956: 
                   1957: /* {{{ proto array get_defined_constants([bool categorize])
                   1958:    Return an array containing the names and values of all defined constants */
                   1959: ZEND_FUNCTION(get_defined_constants)
                   1960: {
                   1961:        zend_bool categorize = 0;
                   1962:        
                   1963:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &categorize) == FAILURE) {
                   1964:                return;
                   1965:        }
                   1966: 
                   1967:        array_init(return_value);
                   1968: 
                   1969:        if (categorize) {
                   1970:                HashPosition pos;
                   1971:                zend_constant *val;
                   1972:                int module_number;
                   1973:                zval **modules;
                   1974:                char **module_names;
                   1975:                zend_module_entry *module;
                   1976:                int i = 1;
                   1977: 
                   1978:                modules = ecalloc(zend_hash_num_elements(&module_registry) + 2, sizeof(zval *));
                   1979:                module_names = emalloc((zend_hash_num_elements(&module_registry) + 2) * sizeof(char *));
                   1980: 
                   1981:                module_names[0] = "internal";
                   1982:                zend_hash_internal_pointer_reset_ex(&module_registry, &pos);
                   1983:                while (zend_hash_get_current_data_ex(&module_registry, (void *) &module, &pos) != FAILURE) {
                   1984:                        module_names[module->module_number] = (char *)module->name;
                   1985:                        i++;
                   1986:                        zend_hash_move_forward_ex(&module_registry, &pos);
                   1987:                }
                   1988:                module_names[i] = "user";
                   1989: 
                   1990:                zend_hash_internal_pointer_reset_ex(EG(zend_constants), &pos);
                   1991:                while (zend_hash_get_current_data_ex(EG(zend_constants), (void **) &val, &pos) != FAILURE) {
                   1992:                        zval *const_val;
                   1993: 
1.1.1.4   misho    1994:                        if (!val->name) {
                   1995:                                /* skip special constants */
                   1996:                                goto next_constant;
                   1997:                        }
                   1998: 
1.1       misho    1999:                        if (val->module_number == PHP_USER_CONSTANT) {
                   2000:                                module_number = i;
                   2001:                        } else if (val->module_number > i || val->module_number < 0) {
                   2002:                                /* should not happen */
1.1.1.4   misho    2003:                                goto next_constant;
1.1       misho    2004:                        } else {
                   2005:                                module_number = val->module_number;
                   2006:                        }
                   2007: 
                   2008:                        if (!modules[module_number]) {
                   2009:                                MAKE_STD_ZVAL(modules[module_number]);
                   2010:                                array_init(modules[module_number]);
                   2011:                                add_assoc_zval(return_value, module_names[module_number], modules[module_number]);
                   2012:                        }
                   2013: 
                   2014:                        MAKE_STD_ZVAL(const_val);
                   2015:                        *const_val = val->value;
                   2016:                        zval_copy_ctor(const_val);
                   2017:                        INIT_PZVAL(const_val);
                   2018: 
                   2019:                        add_assoc_zval_ex(modules[module_number], val->name, val->name_len, const_val);
1.1.1.4   misho    2020: next_constant:
1.1       misho    2021:                        zend_hash_move_forward_ex(EG(zend_constants), &pos);
                   2022:                }
                   2023:                efree(module_names);
                   2024:                efree(modules);
                   2025:        } else {
                   2026:                zend_hash_apply_with_argument(EG(zend_constants), (apply_func_arg_t) add_constant_info, return_value TSRMLS_CC);
                   2027:        }
                   2028: }
                   2029: /* }}} */
                   2030: 
                   2031: 
                   2032: static zval *debug_backtrace_get_args(void **curpos TSRMLS_DC)
                   2033: {
                   2034:        void **p = curpos;
                   2035:        zval *arg_array, **arg;
                   2036:        int arg_count = (int)(zend_uintptr_t) *p;
                   2037: 
                   2038:        MAKE_STD_ZVAL(arg_array);
                   2039:        array_init_size(arg_array, arg_count);
                   2040:        p -= arg_count;
                   2041: 
                   2042:        while (--arg_count >= 0) {
                   2043:                arg = (zval **) p++;
                   2044:                if (*arg) {
                   2045:                        if (Z_TYPE_PP(arg) != IS_OBJECT) {
                   2046:                                SEPARATE_ZVAL_TO_MAKE_IS_REF(arg);
                   2047:                        }
                   2048:                        Z_ADDREF_PP(arg);
                   2049:                        add_next_index_zval(arg_array, *arg);
                   2050:                } else {
                   2051:                        add_next_index_null(arg_array);
                   2052:                }
                   2053:        }
                   2054: 
                   2055:        return arg_array;
                   2056: }
                   2057: 
                   2058: void debug_print_backtrace_args(zval *arg_array TSRMLS_DC)
                   2059: {
                   2060:        zval **tmp;
                   2061:        HashPosition iterator;
                   2062:        int i = 0;
                   2063: 
                   2064:        zend_hash_internal_pointer_reset_ex(arg_array->value.ht, &iterator);
                   2065:        while (zend_hash_get_current_data_ex(arg_array->value.ht, (void **) &tmp, &iterator) == SUCCESS) {
                   2066:                if (i++) {
                   2067:                        ZEND_PUTS(", ");
                   2068:                }
                   2069:                zend_print_flat_zval_r(*tmp TSRMLS_CC);
                   2070:                zend_hash_move_forward_ex(arg_array->value.ht, &iterator);
                   2071:        }
                   2072: }
                   2073: 
1.1.1.2   misho    2074: /* {{{ proto void debug_print_backtrace([int options[, int limit]]) */
1.1       misho    2075: ZEND_FUNCTION(debug_print_backtrace)
                   2076: {
                   2077:        zend_execute_data *ptr, *skip;
1.1.1.2   misho    2078:        int lineno, frameno = 0;
                   2079:        const char *function_name;
                   2080:        const char *filename;
                   2081:        const char *class_name = NULL;
1.1       misho    2082:        char *call_type;
1.1.1.2   misho    2083:        const char *include_filename = NULL;
1.1       misho    2084:        zval *arg_array = NULL;
                   2085:        int indent = 0;
                   2086:        long options = 0;
1.1.1.2   misho    2087:        long limit = 0;
1.1       misho    2088: 
1.1.1.2   misho    2089:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &options, &limit) == FAILURE) {
1.1       misho    2090:                return;
                   2091:        }
                   2092: 
                   2093:        ptr = EG(current_execute_data);
                   2094: 
                   2095:        /* skip debug_backtrace() */
                   2096:        ptr = ptr->prev_execute_data;
                   2097: 
1.1.1.2   misho    2098:        while (ptr && (limit == 0 || frameno < limit)) {
                   2099:                const char *free_class_name = NULL;
1.1       misho    2100: 
1.1.1.2   misho    2101:                frameno++;
1.1       misho    2102:                class_name = call_type = NULL;   
                   2103:                arg_array = NULL;
                   2104: 
                   2105:                skip = ptr;
                   2106:                /* skip internal handler */
                   2107:                if (!skip->op_array &&
                   2108:                    skip->prev_execute_data &&
                   2109:                    skip->prev_execute_data->opline &&
                   2110:                    skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
                   2111:                    skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
                   2112:                    skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
                   2113:                        skip = skip->prev_execute_data;
                   2114:                }
                   2115: 
                   2116:                if (skip->op_array) {
                   2117:                        filename = skip->op_array->filename;
                   2118:                        lineno = skip->opline->lineno;
                   2119:                } else {
                   2120:                        filename = NULL;
                   2121:                        lineno = 0;
                   2122:                }
                   2123: 
1.1.1.3   misho    2124:                function_name = (ptr->function_state.function->common.scope &&
                   2125:                        ptr->function_state.function->common.scope->trait_aliases) ?
                   2126:                                zend_resolve_method_name(
                   2127:                                        ptr->object ?
                   2128:                                                Z_OBJCE_P(ptr->object) : 
                   2129:                                                ptr->function_state.function->common.scope,
                   2130:                                        ptr->function_state.function) :
                   2131:                                ptr->function_state.function->common.function_name;
1.1       misho    2132: 
                   2133:                if (function_name) {
                   2134:                        if (ptr->object) {
                   2135:                                if (ptr->function_state.function->common.scope) {
                   2136:                                        class_name = ptr->function_state.function->common.scope->name;
                   2137:                                } else {
                   2138:                                        zend_uint class_name_len;
                   2139:                                        int dup;
                   2140: 
                   2141:                                        dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC);
                   2142:                                        if(!dup) {
                   2143:                                                free_class_name = class_name;
                   2144:                                        }
                   2145:                                }
                   2146: 
                   2147:                                call_type = "->";
                   2148:                        } else if (ptr->function_state.function->common.scope) {
                   2149:                                class_name = ptr->function_state.function->common.scope->name;
                   2150:                                call_type = "::";
                   2151:                        } else {
                   2152:                                class_name = NULL;
                   2153:                                call_type = NULL;
                   2154:                        }
                   2155:                        if ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL))) {
                   2156:                                if (ptr->function_state.arguments && (options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0) {
                   2157:                                        arg_array = debug_backtrace_get_args(ptr->function_state.arguments TSRMLS_CC);
                   2158:                                }
                   2159:                        }
                   2160:                } else {
                   2161:                        /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
                   2162:                        zend_bool build_filename_arg = 1;
                   2163: 
                   2164:                        if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
                   2165:                                /* can happen when calling eval from a custom sapi */
                   2166:                                function_name = "unknown";
                   2167:                                build_filename_arg = 0;
                   2168:                        } else
1.1.1.2   misho    2169:                        switch (ptr->opline->extended_value) {
1.1       misho    2170:                                case ZEND_EVAL:
                   2171:                                        function_name = "eval";
                   2172:                                        build_filename_arg = 0;
                   2173:                                        break;
                   2174:                                case ZEND_INCLUDE:
                   2175:                                        function_name = "include";
                   2176:                                        break;
                   2177:                                case ZEND_REQUIRE:
                   2178:                                        function_name = "require";
                   2179:                                        break;
                   2180:                                case ZEND_INCLUDE_ONCE:
                   2181:                                        function_name = "include_once";
                   2182:                                        break;
                   2183:                                case ZEND_REQUIRE_ONCE:
                   2184:                                        function_name = "require_once";
                   2185:                                        break;
                   2186:                                default:
                   2187:                                        /* this can actually happen if you use debug_backtrace() in your error_handler and 
                   2188:                                         * you're in the top-scope */
                   2189:                                        function_name = "unknown"; 
                   2190:                                        build_filename_arg = 0;
                   2191:                                        break;
                   2192:                        }
                   2193: 
                   2194:                        if (build_filename_arg && include_filename) {
                   2195:                                MAKE_STD_ZVAL(arg_array);
                   2196:                                array_init(arg_array);
1.1.1.2   misho    2197:                                add_next_index_string(arg_array, (char*)include_filename, 1);
1.1       misho    2198:                        }
                   2199:                        call_type = NULL;
                   2200:                }
                   2201:                zend_printf("#%-2d ", indent);
                   2202:                if (class_name) {
                   2203:                        ZEND_PUTS(class_name);
                   2204:                        ZEND_PUTS(call_type);
                   2205:                }
                   2206:                zend_printf("%s(", function_name);
                   2207:                if (arg_array) {
                   2208:                        debug_print_backtrace_args(arg_array TSRMLS_CC);
                   2209:                        zval_ptr_dtor(&arg_array);
                   2210:                }
                   2211:                if (filename) {
                   2212:                        zend_printf(") called at [%s:%d]\n", filename, lineno);
                   2213:                } else {
                   2214:                        zend_execute_data *prev = skip->prev_execute_data;
                   2215: 
                   2216:                        while (prev) {
                   2217:                                if (prev->function_state.function &&
                   2218:                                        prev->function_state.function->common.type != ZEND_USER_FUNCTION) {
                   2219:                                        prev = NULL;
                   2220:                                        break;
                   2221:                                }                                   
                   2222:                                if (prev->op_array) {
                   2223:                                        zend_printf(") called at [%s:%d]\n", prev->op_array->filename, prev->opline->lineno);
                   2224:                                        break;
                   2225:                                }
                   2226:                                prev = prev->prev_execute_data;
                   2227:                        }
                   2228:                        if (!prev) {
                   2229:                                ZEND_PUTS(")\n");
                   2230:                        }
                   2231:                }
                   2232:                include_filename = filename;
                   2233:                ptr = skip->prev_execute_data;
                   2234:                ++indent;
                   2235:                if (free_class_name) {
1.1.1.2   misho    2236:                        efree((char*)free_class_name);
1.1       misho    2237:                }
                   2238:        }
                   2239: }
                   2240: 
                   2241: /* }}} */
                   2242: 
1.1.1.2   misho    2243: ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int options, int limit TSRMLS_DC)
1.1       misho    2244: {
                   2245:        zend_execute_data *ptr, *skip;
1.1.1.2   misho    2246:        int lineno, frameno = 0;
                   2247:        const char *function_name;
                   2248:        const char *filename;
                   2249:        const char *class_name;
                   2250:        const char *include_filename = NULL;
1.1       misho    2251:        zval *stack_frame;
                   2252: 
                   2253:        ptr = EG(current_execute_data);
                   2254: 
                   2255:        /* skip "new Exception()" */
                   2256:        if (ptr && (skip_last == 0) && ptr->opline && (ptr->opline->opcode == ZEND_NEW)) {
                   2257:                ptr = ptr->prev_execute_data;
                   2258:        }
                   2259: 
                   2260:        /* skip debug_backtrace() */
                   2261:        if (skip_last-- && ptr) {
                   2262:                ptr = ptr->prev_execute_data;
                   2263:        }
                   2264: 
                   2265:        array_init(return_value);
                   2266: 
1.1.1.2   misho    2267:        while (ptr && (limit == 0 || frameno < limit)) {
                   2268:                frameno++;
1.1       misho    2269:                MAKE_STD_ZVAL(stack_frame);
                   2270:                array_init(stack_frame);
                   2271: 
                   2272:                skip = ptr;
                   2273:                /* skip internal handler */
                   2274:                if (!skip->op_array &&
                   2275:                    skip->prev_execute_data &&
                   2276:                    skip->prev_execute_data->opline &&
                   2277:                    skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
                   2278:                    skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
                   2279:                    skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
                   2280:                        skip = skip->prev_execute_data;
                   2281:                }
                   2282: 
                   2283:                if (skip->op_array) {
                   2284:                        filename = skip->op_array->filename;
                   2285:                        lineno = skip->opline->lineno;
1.1.1.2   misho    2286:                        add_assoc_string_ex(stack_frame, "file", sizeof("file"), (char*)filename, 1);
1.1       misho    2287:                        add_assoc_long_ex(stack_frame, "line", sizeof("line"), lineno);
                   2288: 
                   2289:                        /* try to fetch args only if an FCALL was just made - elsewise we're in the middle of a function
                   2290:                         * and debug_baktrace() might have been called by the error_handler. in this case we don't 
                   2291:                         * want to pop anything of the argument-stack */
                   2292:                } else {
                   2293:                        zend_execute_data *prev = skip->prev_execute_data;
                   2294: 
                   2295:                        while (prev) {
                   2296:                                if (prev->function_state.function &&
                   2297:                                        prev->function_state.function->common.type != ZEND_USER_FUNCTION &&
                   2298:                                        !(prev->function_state.function->common.type == ZEND_INTERNAL_FUNCTION &&
                   2299:                                                (prev->function_state.function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER))) {
                   2300:                                        break;
                   2301:                                }                                   
                   2302:                                if (prev->op_array) {
1.1.1.2   misho    2303:                                        add_assoc_string_ex(stack_frame, "file", sizeof("file"), (char*)prev->op_array->filename, 1);
1.1       misho    2304:                                        add_assoc_long_ex(stack_frame, "line", sizeof("line"), prev->opline->lineno);
                   2305:                                        break;
                   2306:                                }
                   2307:                                prev = prev->prev_execute_data;
                   2308:                        }
                   2309:                        filename = NULL;
                   2310:                }
                   2311: 
1.1.1.3   misho    2312:                function_name = (ptr->function_state.function->common.scope &&
                   2313:                        ptr->function_state.function->common.scope->trait_aliases) ?
                   2314:                                zend_resolve_method_name(
                   2315:                                        ptr->object ?
                   2316:                                                Z_OBJCE_P(ptr->object) : 
                   2317:                                                ptr->function_state.function->common.scope,
                   2318:                                        ptr->function_state.function) :
                   2319:                                ptr->function_state.function->common.function_name;
1.1       misho    2320: 
                   2321:                if (function_name) {
1.1.1.2   misho    2322:                        add_assoc_string_ex(stack_frame, "function", sizeof("function"), (char*)function_name, 1);
1.1       misho    2323: 
                   2324:                        if (ptr->object && Z_TYPE_P(ptr->object) == IS_OBJECT) {
                   2325:                                if (ptr->function_state.function->common.scope) {
1.1.1.2   misho    2326:                                        add_assoc_string_ex(stack_frame, "class", sizeof("class"), (char*)ptr->function_state.function->common.scope->name, 1);
1.1       misho    2327:                                } else {
                   2328:                                        zend_uint class_name_len;
                   2329:                                        int dup;
                   2330: 
                   2331:                                        dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC);
1.1.1.2   misho    2332:                                        add_assoc_string_ex(stack_frame, "class", sizeof("class"), (char*)class_name, dup);
1.1       misho    2333:                                        
                   2334:                                }
                   2335:                                if ((options & DEBUG_BACKTRACE_PROVIDE_OBJECT) != 0) {
                   2336:                                        add_assoc_zval_ex(stack_frame, "object", sizeof("object"), ptr->object);
                   2337:                                        Z_ADDREF_P(ptr->object);
                   2338:                                }
                   2339: 
                   2340:                                add_assoc_string_ex(stack_frame, "type", sizeof("type"), "->", 1);
                   2341:                        } else if (ptr->function_state.function->common.scope) {
1.1.1.2   misho    2342:                                add_assoc_string_ex(stack_frame, "class", sizeof("class"), (char*)ptr->function_state.function->common.scope->name, 1);
1.1       misho    2343:                                add_assoc_string_ex(stack_frame, "type", sizeof("type"), "::", 1);
                   2344:                        }
                   2345: 
                   2346:                        if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0 && 
                   2347:                                ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL)))) {
                   2348:                                if (ptr->function_state.arguments) {
                   2349:                                        add_assoc_zval_ex(stack_frame, "args", sizeof("args"), debug_backtrace_get_args(ptr->function_state.arguments TSRMLS_CC));
                   2350:                                }
                   2351:                        }
                   2352:                } else {
                   2353:                        /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
                   2354:                        zend_bool build_filename_arg = 1;
                   2355: 
                   2356:                        if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
                   2357:                                /* can happen when calling eval from a custom sapi */
                   2358:                                function_name = "unknown";
                   2359:                                build_filename_arg = 0;
                   2360:                        } else
1.1.1.2   misho    2361:                        switch (ptr->opline->extended_value) {
1.1       misho    2362:                                case ZEND_EVAL:
                   2363:                                        function_name = "eval";
                   2364:                                        build_filename_arg = 0;
                   2365:                                        break;
                   2366:                                case ZEND_INCLUDE:
                   2367:                                        function_name = "include";
                   2368:                                        break;
                   2369:                                case ZEND_REQUIRE:
                   2370:                                        function_name = "require";
                   2371:                                        break;
                   2372:                                case ZEND_INCLUDE_ONCE:
                   2373:                                        function_name = "include_once";
                   2374:                                        break;
                   2375:                                case ZEND_REQUIRE_ONCE:
                   2376:                                        function_name = "require_once";
                   2377:                                        break;
                   2378:                                default:
                   2379:                                        /* this can actually happen if you use debug_backtrace() in your error_handler and 
                   2380:                                         * you're in the top-scope */
                   2381:                                        function_name = "unknown"; 
                   2382:                                        build_filename_arg = 0;
                   2383:                                        break;
                   2384:                        }
                   2385: 
                   2386:                        if (build_filename_arg && include_filename) {
                   2387:                                zval *arg_array;
                   2388: 
                   2389:                                MAKE_STD_ZVAL(arg_array);
                   2390:                                array_init(arg_array);
                   2391: 
1.1.1.4   misho    2392:                                /* include_filename always points to the last filename of the last last called-function.
1.1       misho    2393:                                   if we have called include in the frame above - this is the file we have included.
                   2394:                                 */
                   2395: 
1.1.1.2   misho    2396:                                add_next_index_string(arg_array, (char*)include_filename, 1);
1.1       misho    2397:                                add_assoc_zval_ex(stack_frame, "args", sizeof("args"), arg_array);
                   2398:                        }
                   2399: 
1.1.1.2   misho    2400:                        add_assoc_string_ex(stack_frame, "function", sizeof("function"), (char*)function_name, 1);
1.1       misho    2401:                }
                   2402: 
                   2403:                add_next_index_zval(return_value, stack_frame);
                   2404: 
                   2405:                include_filename = filename; 
                   2406: 
                   2407:                ptr = skip->prev_execute_data;
                   2408:        }
                   2409: }
                   2410: /* }}} */
                   2411: 
                   2412: 
1.1.1.2   misho    2413: /* {{{ proto array debug_backtrace([int options[, int limit]])
1.1       misho    2414:    Return backtrace as array */
                   2415: ZEND_FUNCTION(debug_backtrace)
                   2416: {
                   2417:        long options = DEBUG_BACKTRACE_PROVIDE_OBJECT;
1.1.1.2   misho    2418:        long limit = 0;
1.1       misho    2419:        
1.1.1.2   misho    2420:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &options, &limit) == FAILURE) {
1.1       misho    2421:                return;
                   2422:        }
                   2423: 
1.1.1.2   misho    2424:        zend_fetch_debug_backtrace(return_value, 1, options, limit TSRMLS_CC);
1.1       misho    2425: }
                   2426: /* }}} */
                   2427: 
                   2428: /* {{{ proto bool extension_loaded(string extension_name)
                   2429:    Returns true if the named extension is loaded */
                   2430: ZEND_FUNCTION(extension_loaded)
                   2431: {
                   2432:        char *extension_name;
                   2433:        int extension_name_len;
                   2434:        char *lcname;
                   2435: 
                   2436:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &extension_name, &extension_name_len) == FAILURE) {
                   2437:                return;
                   2438:        }
                   2439: 
                   2440:        lcname = zend_str_tolower_dup(extension_name, extension_name_len);
                   2441:        if (zend_hash_exists(&module_registry, lcname, extension_name_len+1)) {
                   2442:                RETVAL_TRUE;
                   2443:        } else {
                   2444:                RETVAL_FALSE;
                   2445:        }
                   2446:        efree(lcname);
                   2447: }
                   2448: /* }}} */
                   2449: 
                   2450: 
                   2451: /* {{{ proto array get_extension_funcs(string extension_name)
                   2452:    Returns an array with the names of functions belonging to the named extension */
                   2453: ZEND_FUNCTION(get_extension_funcs)
                   2454: {
1.1.1.5 ! misho    2455:        char *extension_name, *lcname;
        !          2456:        int extension_name_len, array;
1.1       misho    2457:        zend_module_entry *module;
1.1.1.5 ! misho    2458:        HashPosition iterator;
        !          2459:        zend_function *zif;
1.1       misho    2460:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &extension_name, &extension_name_len) == FAILURE) {
                   2461:                return;
                   2462:        }
                   2463:        if (strncasecmp(extension_name, "zend", sizeof("zend"))) {
1.1.1.5 ! misho    2464:                lcname = zend_str_tolower_dup(extension_name, extension_name_len);
        !          2465:        } else {
        !          2466:                lcname = estrdup("core");
        !          2467:        }
        !          2468:        if (zend_hash_find(&module_registry, lcname,
        !          2469:                extension_name_len+1, (void**)&module) == FAILURE) {
1.1       misho    2470:                efree(lcname);
1.1.1.5 ! misho    2471:                RETURN_FALSE;
        !          2472:        }
1.1       misho    2473: 
1.1.1.5 ! misho    2474:        zend_hash_internal_pointer_reset_ex(CG(function_table), &iterator);
        !          2475:        if (module->functions) {
        !          2476:                /* avoid BC break, if functions list is empty, will return an empty array */
        !          2477:                array_init(return_value);
        !          2478:                array = 1;
1.1       misho    2479:        } else {
1.1.1.5 ! misho    2480:                array = 0;
        !          2481:        }
        !          2482:        while (zend_hash_get_current_data_ex(CG(function_table), (void **) &zif, &iterator) == SUCCESS) {
        !          2483:                if (zif->common.type==ZEND_INTERNAL_FUNCTION
        !          2484:                        && zif->internal_function.module == module) {
        !          2485:                        if (!array) {
        !          2486:                                array_init(return_value);
        !          2487:                                array = 1;
        !          2488:                        }
        !          2489:                        add_next_index_string(return_value, zif->common.function_name, 1);
        !          2490:                }
        !          2491:                zend_hash_move_forward_ex(CG(function_table), &iterator);
1.1       misho    2492:        }
                   2493: 
1.1.1.5 ! misho    2494:        efree(lcname);
1.1       misho    2495: 
1.1.1.5 ! misho    2496:        if (!array) {
        !          2497:                RETURN_FALSE;
1.1       misho    2498:        }
                   2499: }
                   2500: /* }}} */
                   2501: 
                   2502: /*
                   2503:  * Local variables:
                   2504:  * tab-width: 4
                   2505:  * c-basic-offset: 4
                   2506:  * indent-tabs-mode: t
                   2507:  * End:
                   2508:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>