⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aggregation.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    +----------------------------------------------------------------------+   | PHP Version 4                                                        |   +----------------------------------------------------------------------+   | Copyright (c) 1997-2007 The PHP Group                                |   +----------------------------------------------------------------------+   | This source file is subject to version 3.01 of the PHP license,      |   | that is bundled with this package in the file LICENSE, and is        |   | available through the world-wide-web at the following url:           |   | http://www.php.net/license/3_01.txt                                  |   | If you did not receive a copy of the PHP license and are unable to   |   | obtain it through the world-wide-web, please send a note to          |   | license@php.net so we can mail you a copy immediately.               |   +----------------------------------------------------------------------+   | Author: Andrei Zmievski <andrei@php.net>                             |   +----------------------------------------------------------------------+*//* $Id: aggregation.c,v 1.11.4.7.4.3 2007/01/01 09:46:47 sebastian Exp $ */#include "php.h"#include "basic_functions.h"#include "aggregation.h"#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)#include "ext/pcre/php_pcre.h"#endifstatic void aggregation_info_dtor(aggregation_info *info){#ifndef ZEND_ENGINE_2	destroy_zend_class(info->new_ce);	efree(info->new_ce);#else	destroy_zend_class(&info->new_ce);#endif	zval_ptr_dtor(&info->aggr_members);}/* {{{ static zval* array_to_hash */static zval *array_to_hash(zval *array){	zval *hash, **entry;	char *name_lc;	/*	 * Well, this just transposes the array, popularly known as flipping it, or	 * giving it the finger.	 */	MAKE_STD_ZVAL(hash);	array_init(hash);	for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(array));		 zend_hash_get_current_data(Z_ARRVAL_P(array), (void**)&entry) == SUCCESS;		 zend_hash_move_forward(Z_ARRVAL_P(array))) {		if (Z_TYPE_PP(entry) == IS_STRING) {			/*			 * I hate case-insensitivity. Die, die, die.			 */			name_lc = estrndup(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry));			zend_str_tolower(name_lc, Z_STRLEN_PP(entry));			add_assoc_bool_ex(hash, name_lc, Z_STRLEN_PP(entry)+1, 1);			efree(name_lc);		}	}	return hash;}/* }}} *//* {{{ static void aggregate_methods() */static void aggregate_methods(zend_class_entry *ce, zend_class_entry *from_ce, int aggr_type, zval *aggr_filter, zend_bool exclude, zval *aggr_methods TSRMLS_DC){	HashPosition pos;	zend_function *function;	char *func_name;	uint func_name_len;	ulong num_key;	zval *list_hash = NULL;#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)	pcre *re = NULL;	pcre_extra *re_extra = NULL;	int re_options = 0;#endif	/*	 * Flip the array for easy lookup, or compile the regexp.	 */	if (aggr_type == AGGREGATE_BY_LIST) {		list_hash = array_to_hash(aggr_filter);	}#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)	else if (aggr_type == AGGREGATE_BY_REGEXP) {		if ((re = pcre_get_compiled_regex(Z_STRVAL_P(aggr_filter), &re_extra, &re_options)) == NULL) {			return;		}	}#endif	/*	 * "Just because it's not nice doesn't mean it's not miraculous."	 * 			-- _Interesting Times_, Terry Pratchett	 */	/*	 * Aggregating by list without exclusion can be done more efficiently if we	 * iterate through the list and check against function table instead of the	 * other way around.	 */	if (aggr_type != AGGREGATE_BY_LIST || exclude) {		zend_hash_internal_pointer_reset_ex(&from_ce->function_table, &pos);		while (zend_hash_get_current_data_ex(&from_ce->function_table, (void**)&function, &pos) == SUCCESS) {			zend_hash_get_current_key_ex(&from_ce->function_table, &func_name, &func_name_len, &num_key, 0, &pos);			/* We do not aggregate:			 * 1. constructors */			if (!strncmp(func_name, from_ce->name, MAX(func_name_len-1, from_ce->name_length)) ||			/* 2. private methods (heh, like we really have them) */				func_name[0] == '_' ||			/* 3. explicitly excluded methods */				(aggr_type == AGGREGATE_BY_LIST && zend_hash_exists(Z_ARRVAL_P(list_hash), func_name, func_name_len))#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE) 				||			/* 4. methods matching regexp as modified by the exclusion flag */				(aggr_type == AGGREGATE_BY_REGEXP && (pcre_exec(re, re_extra, func_name, func_name_len-1, 0, 0, NULL, 0) < 0) ^ exclude) == 1#endif				) {				zend_hash_move_forward_ex(&from_ce->function_table, &pos);				continue;			}			/*			 * This is where the magic happens.			 */			if (zend_hash_add(&ce->function_table, func_name, func_name_len,							  (void*)function, sizeof(zend_function), NULL) == SUCCESS) {				function_add_ref(function);				add_next_index_stringl(aggr_methods, func_name, func_name_len-1, 1);			}			zend_hash_move_forward_ex(&from_ce->function_table, &pos);		}	} else {		/*		 * This is just like above except the other way around.		 */		zend_hash_internal_pointer_reset(Z_ARRVAL_P(list_hash));		while (zend_hash_get_current_key_ex(Z_ARRVAL_P(list_hash), &func_name, &func_name_len, &num_key, 0, NULL) == HASH_KEY_IS_STRING) {			if (!strncmp(func_name, from_ce->name, MAX(func_name_len-1, from_ce->name_length)) ||				func_name[0] == '_' ||				zend_hash_find(&from_ce->function_table, func_name, func_name_len, (void**)&function) == FAILURE) {				zend_hash_move_forward(Z_ARRVAL_P(list_hash));				continue;			}			if (zend_hash_add(&ce->function_table, func_name, func_name_len,							  (void*)function, sizeof(zend_function), NULL) == SUCCESS) {				function_add_ref(function);				add_next_index_stringl(aggr_methods, func_name, func_name_len-1, 1);			}			zend_hash_move_forward(Z_ARRVAL_P(list_hash));		}	}	if (list_hash) {		zval_ptr_dtor(&list_hash);	}}/* }}} *//* {{{ static void aggregate_properties() */static void aggregate_properties(zval *obj, zend_class_entry *from_ce, int aggr_type, zval *aggr_filter, zend_bool exclude, zval *aggr_props TSRMLS_DC){	HashPosition pos;	zval **prop;	char *prop_name;	uint prop_name_len;	ulong num_key;	zval *list_hash = NULL;#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)	pcre *re = NULL;	pcre_extra *re_extra = NULL;	int re_options = 0;#endif	if (!from_ce->constants_updated) {		zend_hash_apply_with_argument(&from_ce->default_properties, (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);		from_ce->constants_updated = 1;	}	/*	 * Flip the array for easy lookup, or compile the regexp.	 */	if (aggr_type == AGGREGATE_BY_LIST) {		list_hash = array_to_hash(aggr_filter);	}#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)	else if (aggr_type == AGGREGATE_BY_REGEXP) {		if ((re = pcre_get_compiled_regex(Z_STRVAL_P(aggr_filter), &re_extra, &re_options)) == NULL) {			return;		}	}#endif	/*	 * "Just because it's not nice doesn't mean it's not miraculous."	 * 			-- _Interesting Times_, Terry Pratchett	 */	/*	 * Aggregating by list without exclusion can be done more efficiently if we	 * iterate through the list and check against default properties table	 * instead of the other way around.	 */	if (aggr_type != AGGREGATE_BY_LIST || exclude) {		zend_hash_internal_pointer_reset_ex(&from_ce->default_properties, &pos);		while (zend_hash_get_current_data_ex(&from_ce->default_properties, (void**)&prop, &pos) == SUCCESS) {			zend_hash_get_current_key_ex(&from_ce->default_properties, &prop_name, &prop_name_len, &num_key, 0, &pos);			/* We do not aggregate:			 * 1. private properties (heh, like we really have them) */			if (prop_name[0] == '_' ||			/* 2. explicitly excluded properties */				(aggr_type == AGGREGATE_BY_LIST && zend_hash_exists(Z_ARRVAL_P(list_hash), prop_name, prop_name_len))#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)				||			/* 3. properties matching regexp as modified by the exclusion flag */				(aggr_type == AGGREGATE_BY_REGEXP && (pcre_exec(re, re_extra, prop_name, prop_name_len-1, 0, 0, NULL, 0) < 0) ^ exclude) == 1#endif				) {				zend_hash_move_forward_ex(&from_ce->default_properties, &pos);				continue;			}			/*			 * This is where the magic happens.			 */			if (zend_hash_add(Z_OBJPROP_P(obj), prop_name, prop_name_len,							  (void*)prop, sizeof(zval *), NULL) == SUCCESS) {				zval_add_ref(prop);				add_next_index_stringl(aggr_props, prop_name, prop_name_len-1, 1);			}			zend_hash_move_forward_ex(&from_ce->default_properties, &pos);		}	} else {		/*		 * This is just like above except the other way around.		 */		zend_hash_internal_pointer_reset(Z_ARRVAL_P(list_hash));		while (zend_hash_get_current_key_ex(Z_ARRVAL_P(list_hash), &prop_name, &prop_name_len, &num_key, 0, NULL) == HASH_KEY_IS_STRING) {			if (prop_name[0] == '_' ||				zend_hash_find(&from_ce->default_properties, prop_name, prop_name_len, (void**)&prop) == FAILURE) {				zend_hash_move_forward(Z_ARRVAL_P(list_hash));				continue;			}			if (zend_hash_add(Z_OBJPROP_P(obj), prop_name, prop_name_len,							  (void*)prop, sizeof(zval *), NULL) == SUCCESS) {				zval_add_ref(prop);				add_next_index_stringl(aggr_props, prop_name, prop_name_len-1, 1);			}			zend_hash_move_forward(Z_ARRVAL_P(list_hash));		}	}	if (list_hash) {		zval_ptr_dtor(&list_hash);	}}/* }}} *//* {{{ static void aggregate() */static void aggregate(INTERNAL_FUNCTION_PARAMETERS, int aggr_what, int aggr_type){	/* Incoming parameters. */	zval *obj, *aggr_list = NULL;	char *class_name, *class_name_lc, *aggr_regexp;	int class_name_len, aggr_regexp_len;	zend_bool exclude = 0;	/* Other variables. */  	zval **aggr_members, z_aggr_regexp;	zend_class_entry *ce, *new_ce;	zend_function tmp_zend_function;	aggregation_info aggr_info_new, *aggr_info = &aggr_info_new;	zval *aggr_methods_new, **aggr_methods = &aggr_methods_new;	zval *aggr_props_new, **aggr_props = &aggr_props_new;	zval *aggr_filter = NULL;	int zpp_result = FAILURE;	/*	 * Ah, the beauty of the new parameter parsing API. Almost as good as Heidi Klum.	 */	switch (aggr_type) {		case AGGREGATE_ALL:			zpp_result = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "os", &obj,											   &class_name, &class_name_len);			break;		case AGGREGATE_BY_LIST:			zpp_result = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "osa|b", &obj,											   &class_name, &class_name_len,											   &aggr_list, &exclude);			break;		case AGGREGATE_BY_REGEXP:			zpp_result = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oss|b", &obj,											   &class_name, &class_name_len,											   &aggr_regexp, &aggr_regexp_len, &exclude);			ZVAL_STRINGL(&z_aggr_regexp, aggr_regexp, aggr_regexp_len, 0);			break;	}	if (zpp_result == FAILURE) {		return;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -