Annotation of embedaddon/php/Zend/zend_constants.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | Zend Engine                                                          |
                      4:    +----------------------------------------------------------------------+
1.1.1.3 ! misho       5:    | Copyright (c) 1998-2013 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_constants.h"
                     24: #include "zend_execute.h"
                     25: #include "zend_variables.h"
                     26: #include "zend_operators.h"
                     27: #include "zend_globals.h"
                     28: 
                     29: 
                     30: void free_zend_constant(zend_constant *c)
                     31: {
                     32:        if (!(c->flags & CONST_PERSISTENT)) {
                     33:                zval_dtor(&c->value);
                     34:        }
1.1.1.2   misho      35:        str_free(c->name);
1.1       misho      36: }
                     37: 
                     38: 
                     39: void copy_zend_constant(zend_constant *c)
                     40: {
1.1.1.2   misho      41:        if (!IS_INTERNED(c->name)) {
                     42:                c->name = zend_strndup(c->name, c->name_len - 1);
                     43:        }
1.1       misho      44:        if (!(c->flags & CONST_PERSISTENT)) {
                     45:                zval_copy_ctor(&c->value);
                     46:        }
                     47: }
                     48: 
                     49: 
                     50: void zend_copy_constants(HashTable *target, HashTable *source)
                     51: {
                     52:        zend_constant tmp_constant;
                     53: 
                     54:        zend_hash_copy(target, source, (copy_ctor_func_t) copy_zend_constant, &tmp_constant, sizeof(zend_constant));
                     55: }
                     56: 
                     57: 
                     58: static int clean_non_persistent_constant(const zend_constant *c TSRMLS_DC)
                     59: {
                     60:        return (c->flags & CONST_PERSISTENT) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
                     61: }
                     62: 
                     63: 
                     64: static int clean_non_persistent_constant_full(const zend_constant *c TSRMLS_DC)
                     65: {
                     66:        return (c->flags & CONST_PERSISTENT) ? 0 : 1;
                     67: }
                     68: 
                     69: 
                     70: static int clean_module_constant(const zend_constant *c, int *module_number TSRMLS_DC)
                     71: {
                     72:        if (c->module_number == *module_number) {
                     73:                return 1;
                     74:        } else {
                     75:                return 0;
                     76:        }
                     77: }
                     78: 
                     79: 
                     80: void clean_module_constants(int module_number TSRMLS_DC)
                     81: {
                     82:        zend_hash_apply_with_argument(EG(zend_constants), (apply_func_arg_t) clean_module_constant, (void *) &module_number TSRMLS_CC);
                     83: }
                     84: 
                     85: 
                     86: int zend_startup_constants(TSRMLS_D)
                     87: {
                     88:        EG(zend_constants) = (HashTable *) malloc(sizeof(HashTable));
                     89: 
                     90:        if (zend_hash_init(EG(zend_constants), 20, NULL, ZEND_CONSTANT_DTOR, 1)==FAILURE) {
                     91:                return FAILURE;
                     92:        }
                     93:        return SUCCESS;
                     94: }
                     95: 
                     96: 
                     97: 
                     98: void zend_register_standard_constants(TSRMLS_D)
                     99: {
                    100:        REGISTER_MAIN_LONG_CONSTANT("E_ERROR", E_ERROR, CONST_PERSISTENT | CONST_CS);
                    101:        REGISTER_MAIN_LONG_CONSTANT("E_RECOVERABLE_ERROR", E_RECOVERABLE_ERROR, CONST_PERSISTENT | CONST_CS);
                    102:        REGISTER_MAIN_LONG_CONSTANT("E_WARNING", E_WARNING, CONST_PERSISTENT | CONST_CS);
                    103:        REGISTER_MAIN_LONG_CONSTANT("E_PARSE", E_PARSE, CONST_PERSISTENT | CONST_CS);
                    104:        REGISTER_MAIN_LONG_CONSTANT("E_NOTICE", E_NOTICE, CONST_PERSISTENT | CONST_CS);
                    105:        REGISTER_MAIN_LONG_CONSTANT("E_STRICT", E_STRICT, CONST_PERSISTENT | CONST_CS);
                    106:        REGISTER_MAIN_LONG_CONSTANT("E_DEPRECATED", E_DEPRECATED, CONST_PERSISTENT | CONST_CS);
                    107:        REGISTER_MAIN_LONG_CONSTANT("E_CORE_ERROR", E_CORE_ERROR, CONST_PERSISTENT | CONST_CS);
                    108:        REGISTER_MAIN_LONG_CONSTANT("E_CORE_WARNING", E_CORE_WARNING, CONST_PERSISTENT | CONST_CS);
                    109:        REGISTER_MAIN_LONG_CONSTANT("E_COMPILE_ERROR", E_COMPILE_ERROR, CONST_PERSISTENT | CONST_CS);
                    110:        REGISTER_MAIN_LONG_CONSTANT("E_COMPILE_WARNING", E_COMPILE_WARNING, CONST_PERSISTENT | CONST_CS);
                    111:        REGISTER_MAIN_LONG_CONSTANT("E_USER_ERROR", E_USER_ERROR, CONST_PERSISTENT | CONST_CS);
                    112:        REGISTER_MAIN_LONG_CONSTANT("E_USER_WARNING", E_USER_WARNING, CONST_PERSISTENT | CONST_CS);
                    113:        REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
                    114:        REGISTER_MAIN_LONG_CONSTANT("E_USER_DEPRECATED", E_USER_DEPRECATED, CONST_PERSISTENT | CONST_CS);
                    115: 
                    116:        REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
                    117: 
                    118:        REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_PROVIDE_OBJECT", DEBUG_BACKTRACE_PROVIDE_OBJECT, CONST_PERSISTENT | CONST_CS);
                    119:        REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT | CONST_CS);
                    120:        /* true/false constants */
                    121:        {
                    122:                zend_constant c;
                    123:        
                    124:                c.flags = CONST_PERSISTENT | CONST_CT_SUBST;
                    125:                c.module_number = 0;
                    126: 
                    127:                c.name = zend_strndup(ZEND_STRL("TRUE"));
                    128:                c.name_len = sizeof("TRUE");
                    129:                c.value.value.lval = 1;
                    130:                c.value.type = IS_BOOL;
                    131:                zend_register_constant(&c TSRMLS_CC);
                    132:                
                    133:                c.name = zend_strndup(ZEND_STRL("FALSE"));
                    134:                c.name_len = sizeof("FALSE");
                    135:                c.value.value.lval = 0;
                    136:                c.value.type = IS_BOOL;
                    137:                zend_register_constant(&c TSRMLS_CC);
                    138: 
                    139:                c.name = zend_strndup(ZEND_STRL("NULL"));
                    140:                c.name_len = sizeof("NULL");
                    141:                c.value.type = IS_NULL;
                    142:                zend_register_constant(&c TSRMLS_CC);
                    143: 
1.1.1.2   misho     144:                c.flags = CONST_PERSISTENT | CONST_CS;
1.1       misho     145: 
                    146:                c.name = zend_strndup(ZEND_STRL("ZEND_THREAD_SAFE"));
                    147:                c.name_len = sizeof("ZEND_THREAD_SAFE");
                    148:                c.value.value.lval = ZTS_V;
                    149:                c.value.type = IS_BOOL;
                    150:                zend_register_constant(&c TSRMLS_CC);
                    151: 
                    152:                c.name = zend_strndup(ZEND_STRL("ZEND_DEBUG_BUILD"));
                    153:                c.name_len = sizeof("ZEND_DEBUG_BUILD");
                    154:                c.value.value.lval = ZEND_DEBUG;
                    155:                c.value.type = IS_BOOL;
                    156:                zend_register_constant(&c TSRMLS_CC);
                    157:        }
                    158: }
                    159: 
                    160: 
                    161: int zend_shutdown_constants(TSRMLS_D)
                    162: {
                    163:        zend_hash_destroy(EG(zend_constants));
                    164:        free(EG(zend_constants));
                    165:        return SUCCESS;
                    166: }
                    167: 
                    168: 
                    169: void clean_non_persistent_constants(TSRMLS_D)
                    170: {
                    171:        if (EG(full_tables_cleanup)) {
                    172:                zend_hash_apply(EG(zend_constants), (apply_func_t) clean_non_persistent_constant_full TSRMLS_CC);
                    173:        } else {
                    174:                zend_hash_reverse_apply(EG(zend_constants), (apply_func_t) clean_non_persistent_constant TSRMLS_CC);
                    175:        }
                    176: }
                    177: 
                    178: 
                    179: ZEND_API void zend_register_long_constant(const char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC)
                    180: {
                    181:        zend_constant c;
                    182:        
                    183:        c.value.type = IS_LONG;
                    184:        c.value.value.lval = lval;
                    185:        c.flags = flags;
                    186:        c.name = zend_strndup(name, name_len-1);
                    187:        c.name_len = name_len;
                    188:        c.module_number = module_number;
                    189:        zend_register_constant(&c TSRMLS_CC);
                    190: }
                    191: 
                    192: 
                    193: ZEND_API void zend_register_double_constant(const char *name, uint name_len, double dval, int flags, int module_number TSRMLS_DC)
                    194: {
                    195:        zend_constant c;
                    196:        
                    197:        c.value.type = IS_DOUBLE;
                    198:        c.value.value.dval = dval;
                    199:        c.flags = flags;
                    200:        c.name = zend_strndup(name, name_len-1);
                    201:        c.name_len = name_len;
                    202:        c.module_number = module_number;
                    203:        zend_register_constant(&c TSRMLS_CC);
                    204: }
                    205: 
                    206: 
                    207: ZEND_API void zend_register_stringl_constant(const char *name, uint name_len, char *strval, uint strlen, int flags, int module_number TSRMLS_DC)
                    208: {
                    209:        zend_constant c;
                    210:        
                    211:        c.value.type = IS_STRING;
                    212:        c.value.value.str.val = strval;
                    213:        c.value.value.str.len = strlen;
                    214:        c.flags = flags;
                    215:        c.name = zend_strndup(name, name_len-1);
                    216:        c.name_len = name_len;
                    217:        c.module_number = module_number;
                    218:        zend_register_constant(&c TSRMLS_CC);
                    219: }
                    220: 
                    221: 
                    222: ZEND_API void zend_register_string_constant(const char *name, uint name_len, char *strval, int flags, int module_number TSRMLS_DC)
                    223: {
                    224:        zend_register_stringl_constant(name, name_len, strval, strlen(strval), flags, module_number TSRMLS_CC);
                    225: }
                    226: 
1.1.1.2   misho     227: static int zend_get_special_constant(const char *name, uint name_len, zend_constant **c TSRMLS_DC)
                    228: {
                    229:        int ret;
                    230:        static char haltoff[] = "__COMPILER_HALT_OFFSET__";
                    231: 
                    232:        if (!EG(in_execution)) {
                    233:                return 0;
                    234:        } else if (name_len == sizeof("__CLASS__")-1 &&
                    235:                  !memcmp(name, "__CLASS__", sizeof("__CLASS__")-1)) {
                    236:                zend_constant tmp;
                    237: 
                    238:                /* Returned constants may be cached, so they have to be stored */
                    239:                if (EG(scope) && EG(scope)->name) {
                    240:                        int const_name_len;
                    241:                        char *const_name;
                    242:                        ALLOCA_FLAG(use_heap)
                    243:                        
                    244:                        const_name_len = sizeof("\0__CLASS__") + EG(scope)->name_length;
                    245:                        const_name = do_alloca(const_name_len, use_heap);
                    246:                        memcpy(const_name, "\0__CLASS__", sizeof("\0__CLASS__")-1);
                    247:                        zend_str_tolower_copy(const_name + sizeof("\0__CLASS__")-1, EG(scope)->name, EG(scope)->name_length);
                    248:                        if (zend_hash_find(EG(zend_constants), const_name, const_name_len, (void**)c) == FAILURE) {
                    249:                                zend_hash_add(EG(zend_constants), const_name, const_name_len, (void*)&tmp, sizeof(zend_constant), (void**)c);
                    250:                                memset(*c, 0, sizeof(zend_constant));
                    251:                                Z_STRVAL((**c).value) = estrndup(EG(scope)->name, EG(scope)->name_length);
                    252:                                Z_STRLEN((**c).value) = EG(scope)->name_length;
                    253:                                Z_TYPE((**c).value) = IS_STRING;
                    254:                        }
                    255:                        free_alloca(const_name, use_heap);
                    256:                } else {
                    257:                        if (zend_hash_find(EG(zend_constants), "\0__CLASS__", sizeof("\0__CLASS__"), (void**)c) == FAILURE) {
                    258:                                zend_hash_add(EG(zend_constants), "\0__CLASS__", sizeof("\0__CLASS__"), (void*)&tmp, sizeof(zend_constant), (void**)c);
                    259:                                memset(*c, 0, sizeof(zend_constant));
                    260:                                Z_STRVAL((**c).value) = estrndup("", 0);
                    261:                                Z_STRLEN((**c).value) = 0;
                    262:                                Z_TYPE((**c).value) = IS_STRING;
                    263:                        }
                    264:                }
                    265:                return 1;
                    266:        } else if (name_len == sizeof("__COMPILER_HALT_OFFSET__")-1 &&
                    267:                  !memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) {
                    268:                const char *cfilename;
                    269:                char *haltname;
                    270:                int len, clen;
                    271: 
                    272:                cfilename = zend_get_executed_filename(TSRMLS_C);
                    273:                clen = strlen(cfilename);
                    274:                /* check for __COMPILER_HALT_OFFSET__ */
                    275:                zend_mangle_property_name(&haltname, &len, haltoff,
                    276:                        sizeof("__COMPILER_HALT_OFFSET__") - 1, cfilename, clen, 0);
                    277:                ret = zend_hash_find(EG(zend_constants), haltname, len+1, (void **) c);
                    278:                efree(haltname);
                    279:                return (ret == SUCCESS);
                    280:        } else {
                    281:                return 0;
                    282:        }
                    283: }
                    284: 
1.1       misho     285: 
                    286: ZEND_API int zend_get_constant(const char *name, uint name_len, zval *result TSRMLS_DC)
                    287: {
                    288:        zend_constant *c;
                    289:        int retval = 1;
                    290:        char *lookup_name;
                    291: 
                    292:        if (zend_hash_find(EG(zend_constants), name, name_len+1, (void **) &c) == FAILURE) {
                    293:                lookup_name = zend_str_tolower_dup(name, name_len);
                    294: 
                    295:                if (zend_hash_find(EG(zend_constants), lookup_name, name_len+1, (void **) &c)==SUCCESS) {
                    296:                        if (c->flags & CONST_CS) {
                    297:                                retval=0;
                    298:                        }
                    299:                } else {
1.1.1.2   misho     300:                        retval = zend_get_special_constant(name, name_len, &c TSRMLS_CC);
1.1       misho     301:                }
                    302:                efree(lookup_name);
                    303:        }
                    304: 
                    305:        if (retval) {
                    306:                *result = c->value;
                    307:                zval_copy_ctor(result);
                    308:                Z_SET_REFCOUNT_P(result, 1);
                    309:                Z_UNSET_ISREF_P(result);
                    310:        }
                    311: 
                    312:        return retval;
                    313: }
                    314: 
                    315: ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result, zend_class_entry *scope, ulong flags TSRMLS_DC)
                    316: {
                    317:        zend_constant *c;
                    318:        int retval = 1;
1.1.1.2   misho     319:        const char *colon;
1.1       misho     320:        zend_class_entry *ce = NULL;
                    321:        char *class_name;
                    322:        zval **ret_constant;
                    323: 
                    324:        /* Skip leading \\ */
                    325:        if (name[0] == '\\') {
                    326:                name += 1;
                    327:                name_len -= 1;
                    328:        }
                    329: 
                    330: 
                    331:        if ((colon = zend_memrchr(name, ':', name_len)) &&
                    332:            colon > name && (*(colon - 1) == ':')) {
                    333:                int class_name_len = colon - name - 1;
                    334:                int const_name_len = name_len - class_name_len - 2;
1.1.1.2   misho     335:                const char *constant_name = colon + 1;
1.1       misho     336:                char *lcname;
                    337: 
                    338:                class_name = estrndup(name, class_name_len);
                    339:                lcname = zend_str_tolower_dup(class_name, class_name_len);
                    340:                if (!scope) {
                    341:                        if (EG(in_execution)) {
                    342:                                scope = EG(scope);
                    343:                        } else {
                    344:                                scope = CG(active_class_entry);
                    345:                        }
                    346:                }
                    347: 
                    348:                if (class_name_len == sizeof("self")-1 &&
                    349:                    !memcmp(lcname, "self", sizeof("self")-1)) {
                    350:                        if (scope) {
                    351:                                ce = scope;
                    352:                        } else {
                    353:                                zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
                    354:                                retval = 0;
                    355:                        }
                    356:                        efree(lcname);
                    357:                } else if (class_name_len == sizeof("parent")-1 &&
                    358:                           !memcmp(lcname, "parent", sizeof("parent")-1)) {
                    359:                        if (!scope) {
                    360:                                zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
                    361:                        } else if (!scope->parent) {
                    362:                                zend_error(E_ERROR, "Cannot access parent:: when current class scope has no parent");
                    363:                        } else {
                    364:                                ce = scope->parent;
                    365:                        }
                    366:                        efree(lcname);
                    367:                } else if (class_name_len == sizeof("static")-1 &&
                    368:                           !memcmp(lcname, "static", sizeof("static")-1)) {
                    369:                        if (EG(called_scope)) {
                    370:                                ce = EG(called_scope);
                    371:                        } else {
                    372:                                zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
                    373:                        }
                    374:                        efree(lcname);
                    375:                } else {
                    376:                        efree(lcname);
                    377:                        ce = zend_fetch_class(class_name, class_name_len, flags TSRMLS_CC);
                    378:                }
                    379:                if (retval && ce) {
                    380:                        if (zend_hash_find(&ce->constants_table, constant_name, const_name_len+1, (void **) &ret_constant) != SUCCESS) {
                    381:                                retval = 0;
                    382:                                if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
                    383:                                        zend_error(E_ERROR, "Undefined class constant '%s::%s'", class_name, constant_name);
                    384:                                }
                    385:                        }
                    386:                } else if (!ce) {
                    387:                        retval = 0;
                    388:                }
                    389:                efree(class_name);
                    390:                goto finish;
                    391:        }
                    392: 
                    393:        /* non-class constant */
                    394:        if ((colon = zend_memrchr(name, '\\', name_len)) != NULL) {
                    395:                /* compound constant name */
                    396:                int prefix_len = colon - name;
                    397:                int const_name_len = name_len - prefix_len - 1;
1.1.1.2   misho     398:                const char *constant_name = colon + 1;
1.1       misho     399:                char *lcname;
                    400:                int found_const = 0;
                    401: 
                    402:                lcname = zend_str_tolower_dup(name, prefix_len);
                    403:                /* Check for namespace constant */
                    404: 
                    405:                /* Concatenate lowercase namespace name and constant name */
                    406:                lcname = erealloc(lcname, prefix_len + 1 + const_name_len + 1);
                    407:                lcname[prefix_len] = '\\';
                    408:                memcpy(lcname + prefix_len + 1, constant_name, const_name_len + 1);
                    409: 
                    410:                if (zend_hash_find(EG(zend_constants), lcname, prefix_len + 1 + const_name_len + 1, (void **) &c) == SUCCESS) {
                    411:                        found_const = 1;
                    412:                } else {
                    413:                        /* try lowercase */
                    414:                        zend_str_tolower(lcname + prefix_len + 1, const_name_len);
                    415:                        if (zend_hash_find(EG(zend_constants), lcname, prefix_len + 1 + const_name_len + 1, (void **) &c) == SUCCESS) {
                    416:                                if ((c->flags & CONST_CS) == 0) {
                    417:                                        found_const = 1;
                    418:                                }
                    419:                        }
                    420:                }
                    421:                efree(lcname);
                    422:                if(found_const) {
                    423:                        *result = c->value;
                    424:                        zval_update_constant_ex(&result, (void*)1, NULL TSRMLS_CC);
                    425:                        zval_copy_ctor(result);
                    426:                        Z_SET_REFCOUNT_P(result, 1);
                    427:                        Z_UNSET_ISREF_P(result);
                    428:                        return 1;
                    429:                }
                    430:                /* name requires runtime resolution, need to check non-namespaced name */
                    431:                if ((flags & IS_CONSTANT_UNQUALIFIED) != 0) {
                    432:                        name = constant_name;
                    433:                        name_len = const_name_len;
                    434:                        return zend_get_constant(name, name_len, result TSRMLS_CC);
                    435:                }
                    436:                retval = 0;
                    437: finish:
                    438:                if (retval) {
                    439:                        zval_update_constant_ex(ret_constant, (void*)1, ce TSRMLS_CC);
                    440:                        *result = **ret_constant;
                    441:                        zval_copy_ctor(result);
                    442:                        INIT_PZVAL(result);
                    443:                }
                    444: 
                    445:                return retval;
                    446:        }
                    447: 
                    448:        return zend_get_constant(name, name_len, result TSRMLS_CC);
                    449: }
                    450: 
1.1.1.2   misho     451: zend_constant *zend_quick_get_constant(const zend_literal *key, ulong flags TSRMLS_DC)
                    452: {
                    453:        zend_constant *c;
                    454: 
                    455:        if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(key->constant), Z_STRLEN(key->constant) + 1, key->hash_value, (void **) &c) == FAILURE) {
                    456:                key++;
                    457:                if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(key->constant), Z_STRLEN(key->constant) + 1, key->hash_value, (void **) &c) == FAILURE ||
                    458:                    (c->flags & CONST_CS) != 0) {
                    459:                        if ((flags & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) {
                    460:                                key++;
                    461:                                if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(key->constant), Z_STRLEN(key->constant) + 1, key->hash_value, (void **) &c) == FAILURE) {
                    462:                                    key++;
                    463:                                        if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(key->constant), Z_STRLEN(key->constant) + 1, key->hash_value, (void **) &c) == FAILURE ||
                    464:                                            (c->flags & CONST_CS) != 0) {
                    465: 
                    466:                                                key--;
                    467:                                                if (!zend_get_special_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) {
                    468:                                                        return NULL;
                    469:                                                }
                    470:                                        }
                    471:                                }
                    472:                        } else {
                    473:                                key--;
                    474:                                if (!zend_get_special_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) {
                    475:                                        return NULL;
                    476:                                }
                    477:                        }
                    478:                }
                    479:        }
                    480:        return c;
                    481: }
                    482: 
1.1       misho     483: ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
                    484: {
                    485:        char *lowercase_name = NULL;
                    486:        char *name;
                    487:        int ret = SUCCESS;
1.1.1.2   misho     488:        ulong chash = 0;
1.1       misho     489: 
                    490: #if 0
                    491:        printf("Registering constant for module %d\n", c->module_number);
                    492: #endif
                    493: 
                    494:        if (!(c->flags & CONST_CS)) {
                    495:                /* keep in mind that c->name_len already contains the '\0' */
                    496:                lowercase_name = estrndup(c->name, c->name_len-1);
                    497:                zend_str_tolower(lowercase_name, c->name_len-1);
1.1.1.2   misho     498:                lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC);
1.1       misho     499:                name = lowercase_name;
1.1.1.2   misho     500:                chash = IS_INTERNED(lowercase_name) ? INTERNED_HASH(lowercase_name) : 0;
1.1       misho     501:        } else {
                    502:                char *slash = strrchr(c->name, '\\');
                    503:                if(slash) {
                    504:                        lowercase_name = estrndup(c->name, c->name_len-1);
                    505:                        zend_str_tolower(lowercase_name, slash-c->name);
1.1.1.2   misho     506:                        lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC);
1.1       misho     507:                        name = lowercase_name;
1.1.1.2   misho     508:                        
                    509:                        chash = IS_INTERNED(lowercase_name) ? INTERNED_HASH(lowercase_name) : 0;
1.1       misho     510:                } else {
                    511:                        name = c->name;
                    512:                }
                    513:        }
1.1.1.2   misho     514:        if (chash == 0) {
                    515:                chash = zend_hash_func(name, c->name_len);
                    516:        }
1.1       misho     517: 
                    518:        /* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */
                    519:        if ((c->name_len == sizeof("__COMPILER_HALT_OFFSET__")
                    520:                && !memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1))
1.1.1.2   misho     521:                || zend_hash_quick_add(EG(zend_constants), name, c->name_len, chash, (void *) c, sizeof(zend_constant), NULL)==FAILURE) {
1.1       misho     522:                
                    523:                /* The internal __COMPILER_HALT_OFFSET__ is prefixed by NULL byte */
                    524:                if (c->name[0] == '\0' && c->name_len > sizeof("\0__COMPILER_HALT_OFFSET__")
                    525:                        && memcmp(name, "\0__COMPILER_HALT_OFFSET__", sizeof("\0__COMPILER_HALT_OFFSET__")) == 0) {
                    526:                        name++;
                    527:                }
                    528:                zend_error(E_NOTICE,"Constant %s already defined", name);
1.1.1.2   misho     529:                str_free(c->name);
1.1       misho     530:                if (!(c->flags & CONST_PERSISTENT)) {
                    531:                        zval_dtor(&c->value);
                    532:                }
                    533:                ret = FAILURE;
                    534:        }
1.1.1.2   misho     535:        if (lowercase_name && !IS_INTERNED(lowercase_name)) {
1.1       misho     536:                efree(lowercase_name);
                    537:        }
                    538:        return ret;
                    539: }
                    540: 
                    541: 
                    542: /*
                    543:  * Local variables:
                    544:  * tab-width: 4
                    545:  * c-basic-offset: 4
                    546:  * indent-tabs-mode: t
                    547:  * End:
                    548:  */

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