File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / Zend / zend_constants.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:04:03 2014 UTC (10 years, 4 months ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

    1: /*
    2:    +----------------------------------------------------------------------+
    3:    | Zend Engine                                                          |
    4:    +----------------------------------------------------------------------+
    5:    | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
    6:    +----------------------------------------------------------------------+
    7:    | This source file is subject to version 2.00 of the Zend license,     |
    8:    | that is bundled with this package in the file LICENSE, and is        | 
    9:    | available through the world-wide-web at the following url:           |
   10:    | http://www.zend.com/license/2_00.txt.                                |
   11:    | If you did not receive a copy of the Zend license and are unable to  |
   12:    | obtain it through the world-wide-web, please send a note to          |
   13:    | license@zend.com so we can mail you a copy immediately.              |
   14:    +----------------------------------------------------------------------+
   15:    | Authors: Andi Gutmans <andi@zend.com>                                |
   16:    |          Zeev Suraski <zeev@zend.com>                                |
   17:    +----------------------------------------------------------------------+
   18: */
   19: 
   20: /* $Id: zend_constants.c,v 1.1.1.4 2014/06/15 20:04:03 misho Exp $ */
   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: 	}
   35: 	str_free(c->name);
   36: }
   37: 
   38: 
   39: void copy_zend_constant(zend_constant *c)
   40: {
   41: 	if (!IS_INTERNED(c->name)) {
   42: 		c->name = zend_strndup(c->name, c->name_len - 1);
   43: 	}
   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: 
  144: 		c.flags = CONST_PERSISTENT | CONST_CS;
  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: 
  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: 
  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 {
  300: 			retval = zend_get_special_constant(name, name_len, &c TSRMLS_CC);
  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;
  319: 	const char *colon;
  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;
  335: 		const char *constant_name = colon + 1;
  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;
  398: 		const char *constant_name = colon + 1;
  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: 
  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: 
  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;
  488: 	ulong chash = 0;
  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);
  498: 		lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC);
  499: 		name = lowercase_name;
  500: 		chash = IS_INTERNED(lowercase_name) ? INTERNED_HASH(lowercase_name) : 0;
  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);
  506: 			lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC);
  507: 			name = lowercase_name;
  508: 			
  509: 			chash = IS_INTERNED(lowercase_name) ? INTERNED_HASH(lowercase_name) : 0;
  510: 		} else {
  511: 			name = c->name;
  512: 		}
  513: 	}
  514: 	if (chash == 0) {
  515: 		chash = zend_hash_func(name, c->name_len);
  516: 	}
  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))
  521: 		|| zend_hash_quick_add(EG(zend_constants), name, c->name_len, chash, (void *) c, sizeof(zend_constant), NULL)==FAILURE) {
  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);
  529: 		str_free(c->name);
  530: 		if (!(c->flags & CONST_PERSISTENT)) {
  531: 			zval_dtor(&c->value);
  532: 		}
  533: 		ret = FAILURE;
  534: 	}
  535: 	if (lowercase_name && !IS_INTERNED(lowercase_name)) {
  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>