There appear to have been changes checked in to Zend/ after it branched
for PHP 4.3.  Many of these have been backported the 4.3 branch, but a
few things appear to be orphaned on HEAD.  

The attached patch has those changes which have not yet been
backported.  Is there chance that some of these, especially the
backtrace printing functionality, will get backported?

Thanks.
Peter
Index: zend_builtin_functions.c
===================================================================
RCS file: /repository/Zend/zend_builtin_functions.c,v
retrieving revision 1.124
retrieving revision 1.133
diff -u -r1.124 -r1.133
--- zend_builtin_functions.c	21 Oct 2002 08:42:32 -0000	1.124
+++ zend_builtin_functions.c	8 Jan 2003 16:40:22 -0000	1.133
@@ -66,6 +68,7 @@
 static ZEND_FUNCTION(get_extension_funcs);
 static ZEND_FUNCTION(get_defined_constants);
 static ZEND_FUNCTION(debug_backtrace);
+static ZEND_FUNCTION(debug_print_backtrace);
 #if ZEND_DEBUG
 static ZEND_FUNCTION(zend_test_func);
 #endif
@@ -118,6 +123,7 @@
 	ZEND_FE(get_extension_funcs,		NULL)
 	ZEND_FE(get_defined_constants,		NULL)
 	ZEND_FE(debug_backtrace,			NULL)
+	ZEND_FE(debug_print_backtrace,			NULL)
 #if ZEND_DEBUG
 	ZEND_FE(zend_test_func,		NULL)
 #endif
@@ -1168,6 +1175,151 @@
 	return arg_array;
 }
 
+
+void debug_print_backtrace_args(zval *arg_array) 
+{
+    zval **tmp;
+    HashPosition iterator;
+    int i = 0;
+    
+    zend_hash_internal_pointer_reset_ex(arg_array->value.ht, &iterator);
+    while (zend_hash_get_current_data_ex(arg_array->value.ht, (void **) &tmp, &iterator) == SUCCESS) {
+	if (i++) {
+	    ZEND_PUTS(", ");
+	}
+	zend_print_flat_zval_r(*tmp);
+	zend_hash_move_forward_ex(arg_array->value.ht, &iterator);
+    }
+}
+    
+/* {{{ proto void debug_backtrace(void)
+   Prints out a backtrace */
+ZEND_FUNCTION(debug_print_backtrace)
+{
+	zend_execute_data *ptr;
+	int lineno;
+	char *function_name;
+	char *filename;
+	char *class_name = NULL;
+	char *call_type;
+	char *include_filename = NULL;
+	zval *arg_array = NULL;
+	void **cur_arg_pos = EG(argument_stack).top_element;
+	void **args = cur_arg_pos;
+	int arg_stack_consistent = 0;
+	int frames_on_stack = 0;
+	int indent = 0;
+
+	if (ZEND_NUM_ARGS()) {
+		ZEND_WRONG_PARAM_COUNT();
+	}
+
+	while (--args >= EG(argument_stack).elements) {
+		if (*args--) {
+			break;
+		}
+		args -= *(ulong*)args;
+		frames_on_stack++;
+
+		if (args == EG(argument_stack).elements) {
+			arg_stack_consistent = 1;
+			break;
+		}
+	}
+
+	ptr = EG(current_execute_data);
+
+	/* skip debug_backtrace() */
+	ptr = ptr->prev_execute_data;
+	cur_arg_pos -= 2;
+	frames_on_stack--;
+
+	array_init(return_value);
+
+	while (ptr) {
+		if (ptr->op_array) {
+			filename = ptr->op_array->filename;
+			lineno = ptr->opline->lineno;
+		} else {
+			filename = NULL;
+		}
+
+		function_name = ptr->function_state.function->common.function_name;
+
+		if (function_name) {
+			if (ptr->ce) {
+				class_name = ptr->ce->name;
+				call_type = "::";
+			} else if (ptr->object.ptr) {
+				class_name = ptr->object.ptr->value.obj.ce->name;
+				call_type = "->";
+			} else {
+				class_name = NULL;
+				call_type = NULL;
+			}
+			if ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL))) {
+				if (arg_stack_consistent && (frames_on_stack > 0)) {
+					arg_array = debug_backtrace_get_args(&cur_arg_pos TSRMLS_CC);
+					frames_on_stack--;
+				}
+			}	
+		} else {
+			/* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
+			zend_bool build_filename_arg = 1;
+
+			switch (ptr->opline->op2.u.constant.value.lval) {
+				case ZEND_EVAL:
+					function_name = "eval";
+					build_filename_arg = 0;
+					break;
+				case ZEND_INCLUDE:
+					function_name = "include";
+					break;
+				case ZEND_REQUIRE:
+					function_name = "require";
+					break;
+				case ZEND_INCLUDE_ONCE:
+					function_name = "include_once";
+					break;
+				case ZEND_REQUIRE_ONCE:
+					function_name = "require_once";
+					break;
+				default:
+					/* this can actually happen if you use debug_backtrace() in your error_handler and 
+					 * you're in the top-scope */
+					function_name = "unknown"; 
+					build_filename_arg = 0;
+					break;
+			}
+
+			if (build_filename_arg && include_filename) {
+				MAKE_STD_ZVAL(arg_array);
+				array_init(arg_array);
+				/* include_filename always points to the last filename of the last last called-fuction.
+				   if we have called include in the frame above - this is the file we have included.
+				 */
+
+				add_next_index_string(arg_array, include_filename, 1);
+			}
+
+		}
+		zend_printf("#%-2d ", indent);
+		if (class_name) {
+			ZEND_PUTS(class_name);
+			ZEND_PUTS(call_type);
+		}
+		zend_printf("%s(", function_name?function_name:"main");
+		if (arg_array) {
+			debug_print_backtrace_args(arg_array);
+			zval_ptr_dtor(&arg_array);
+		}
+		zend_printf(") called at [%s:%d]\n", filename, lineno);
+		include_filename = filename; 
+		ptr = ptr->prev_execute_data;
+		++indent;
+	}
+}
+
 /* {{{ proto void debug_backtrace(void)
    Prints out a backtrace */
 ZEND_FUNCTION(debug_backtrace)
Index: zend.c
===================================================================
RCS file: /repository/Zend/zend.c,v
retrieving revision 1.162
retrieving revision 1.174
diff -u -r1.162 -r1.174
--- zend.c	1 Nov 2002 22:19:55 -0000	1.162
+++ zend.c	8 Jan 2003 09:44:48 -0000	1.174
@@ -35,7 +35,7 @@
 #else
 #	define GLOBAL_FUNCTION_TABLE	CG(function_table)
 #	define GLOBAL_CLASS_TABLE		CG(class_table)
-#	define GLOBAL_CONSTANTS_TABLE	CG(zend_constants)
+#	define GLOBAL_CONSTANTS_TABLE	EG(zend_constants)
 #	define GLOBAL_AUTO_GLOBALS_TABLE	CG(auto_globals)
 #endif
 
@@ -122,6 +138,35 @@
 }
 
 
+static void print_flat_hash(HashTable *ht)
+{
+	zval **tmp;
+	char *string_key;
+	HashPosition iterator;
+	ulong num_key;
+	uint str_len;
+	int i = 0;
+
+	zend_hash_internal_pointer_reset_ex(ht, &iterator);
+	while (zend_hash_get_current_data_ex(ht, (void **) &tmp, &iterator) == SUCCESS) {
+		if (i++ > 0) {
+		    ZEND_PUTS(",");
+		}
+		ZEND_PUTS("[");
+		switch (zend_hash_get_current_key_ex(ht, &string_key, &str_len, &num_key, 0, &iterator)) {
+			case HASH_KEY_IS_STRING:
+				ZEND_PUTS(string_key);
+				break;
+			case HASH_KEY_IS_LONG:
+				zend_printf("%ld", num_key);
+				break;
+		}
+		ZEND_PUTS("] => ");
+		zend_print_flat_zval_r(*tmp);
+		zend_hash_move_forward_ex(ht, &iterator);
+	}
+}
+
 ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy)
 {
 	if (expr->type==IS_STRING) {
@@ -199,6 +244,43 @@
 }
 
 
+ZEND_API void zend_print_flat_zval_r(zval *expr)
+{
+	zend_write_func_t write_func = zend_write;
+
+	switch (expr->type) {
+		case IS_ARRAY:
+			ZEND_PUTS("Array (");
+			if (++expr->value.ht->nApplyCount>1) {
+				ZEND_PUTS(" *RECURSION*");
+				expr->value.ht->nApplyCount--;
+				return;
+			}
+			print_flat_hash(expr->value.ht);
+			ZEND_PUTS(")");
+			expr->value.ht->nApplyCount--;
+			break;
+		case IS_OBJECT:
+			{
+				zend_object *object = Z_OBJ_P(expr);
+
+				if (++object->properties->nApplyCount>1) {
+					ZEND_PUTS(" *RECURSION*");
+					object->properties->nApplyCount--;
+					return;
+				}
+				zend_printf("%s Object (", object->ce->name);
+				print_flat_hash(object->properties);
+				ZEND_PUTS(")");
+				object->properties->nApplyCount--;
+				break;
+			}
+		default:
+			zend_print_variable(expr);
+			break;
+	}
+}
+
 ZEND_API void zend_print_zval_r(zval *expr, int indent)
 {
 	zend_print_zval_r_ex(zend_write, expr, indent);
@@ -389,13 +472,8 @@
 	zend_compiler_globals *compiler_globals;
 	zend_executor_globals *executor_globals;
 	void ***tsrm_ls;
-#ifdef ZTS
 	extern ZEND_API ts_rsrc_id ini_scanner_globals_id;
 	extern ZEND_API ts_rsrc_id language_scanner_globals_id;
-#else
-	extern zend_scanner_globals ini_scanner_globals;
-	extern zend_scanner_globals language_scanner_globals;
-#endif
 
 	ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
 #else
@@ -524,9 +610,8 @@
 	free(GLOBAL_AUTO_GLOBALS_TABLE);
 	zend_shutdown_extensions(TSRMLS_C);
 	free(zend_version_info);
-#ifndef ZTS
-	zend_shutdown_constants();
-#endif
+	zend_hash_destroy(GLOBAL_CONSTANTS_TABLE);
+	free(GLOBAL_CONSTANTS_TABLE);
 }
 
 
Index: zend_compile.c
===================================================================
RCS file: /repository/Zend/zend_compile.c,v
retrieving revision 1.240
retrieving revision 1.243
diff -u -r1.240 -r1.243
--- zend_compile.c	10 Nov 2002 05:25:27 -0000	1.240
+++ zend_compile.c	5 Jan 2003 16:07:03 -0000	1.243
@@ -83,6 +83,7 @@
 	zend_stack_init(&CG(list_stack));
 	CG(handle_op_arrays) = 1;
 	CG(in_compilation) = 0;
+	CG(start_lineno) = 0;
 	init_compiler_declarables(TSRMLS_C);
 #ifdef ZEND_MULTIBYTE
 	CG(script_encoding_list) = NULL;
Index: zend_globals.h
===================================================================
RCS file: /repository/Zend/zend_globals.h,v
retrieving revision 1.93
retrieving revision 1.95
diff -u -r1.93 -r1.95
--- zend_globals.h	14 Oct 2002 23:29:13 -0000	1.93
+++ zend_globals.h	5 Jan 2003 16:07:03 -0000	1.95
@@ -118,7 +118,9 @@
 
 	int interactive;
 
+	zend_uint start_lineno;
 	zend_bool increment_lineno;
+	
 
 #ifdef ZEND_MULTIBYTE
 	zend_encoding **script_encoding_list;
Index: zend.h
===================================================================
RCS file: /repository/Zend/zend.h,v
retrieving revision 1.164
retrieving revision 1.170
diff -u -r1.164 -r1.170
--- zend.h	11 Nov 2002 16:31:52 -0000	1.164
+++ zend.h	2 Jan 2003 14:59:11 -0000	1.170
@@ -382,6 +388,7 @@
 ZEND_API int zend_print_zval(zval *expr, int indent);
 ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent);
 ZEND_API void zend_print_zval_r(zval *expr, int indent);
+ZEND_API void zend_print_flat_zval_r(zval *expr);
 ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent);
 ZEND_API void zend_output_debug_string(zend_bool trigger_break, char *format, ...);
 
Index: zend_ini.c
===================================================================
RCS file: /repository/Zend/zend_ini.c,v
retrieving revision 1.23
retrieving revision 1.27
diff -u -r1.23 -r1.27
--- zend_ini.c	23 Sep 2002 12:00:39 -0000	1.23
+++ zend_ini.c	8 Jan 2003 10:02:43 -0000	1.27
@@ -78,6 +78,15 @@
 ZEND_API int zend_ini_shutdown(TSRMLS_D)
 {
 	zend_hash_destroy(EG(ini_directives));
+	free(EG(ini_directives));
+	return SUCCESS;
+}
+
+
+ZEND_API int zend_ini_global_shutdown()
+{
+	zend_hash_destroy(registered_zend_ini_directives);
+	free(registered_zend_ini_directives);
 	return SUCCESS;
 }
 
Index: zend_ini.h
===================================================================
RCS file: /repository/Zend/zend_ini.h,v
retrieving revision 1.21
retrieving revision 1.23
diff -u -r1.21 -r1.23
--- zend_ini.h	28 Aug 2002 13:19:30 -0000	1.21
+++ zend_ini.h	7 Jan 2003 15:56:51 -0000	1.23
@@ -84,6 +84,7 @@
 
 ZEND_API int zend_ini_startup(TSRMLS_D);
 ZEND_API int zend_ini_shutdown(TSRMLS_D);
+ZEND_API int zend_ini_global_shutdown();
 ZEND_API int zend_ini_deactivate(TSRMLS_D);
 
 ZEND_API int zend_copy_ini_directives(TSRMLS_D);
Index: zend_language_scanner.l
===================================================================
RCS file: /repository/Zend/zend_language_scanner.l,v
retrieving revision 1.54
retrieving revision 1.64
diff -u -r1.54 -r1.64
--- zend_language_scanner.l	13 Nov 2002 03:28:23 -0000	1.54
+++ zend_language_scanner.l	13 Feb 2003 16:46:16 -0000	1.64
@@ -305,8 +300,9 @@
 
 	zend_set_compiled_filename(file_path TSRMLS_CC);
 	
-	if (CG(zend_lineno) < 0) { /* position is (n_lines * -1), position was changed by an external app */
-		CG(zend_lineno) = CG(zend_lineno) * -1;
+	if (CG(start_lineno)) {
+		CG(zend_lineno) = CG(start_lineno);
+		CG(start_lineno) = 0;
 	} else {
 		CG(zend_lineno) = 1;
 	}
Index: zend_operators.c
===================================================================
RCS file: /repository/Zend/zend_operators.c,v
retrieving revision 1.129
retrieving revision 1.135
diff -u -r1.129 -r1.135
--- zend_operators.c	14 Oct 2002 13:41:50 -0000	1.129
+++ zend_operators.c	31 Dec 2002 15:55:04 -0000	1.135
@@ -816,8 +816,13 @@
 	op1 = &op1_copy;
 	
 	if (op1->type == IS_DOUBLE) {
-		op1->value.lval = (long) op1->value.dval;
-		op1->type = IS_LONG;
+#ifdef SIZEOF_LONG_LONG
+		result->value.lval = (long) (~(long long) op1->value.dval);
+#else
+		result->value.lval = ~ (long) op1->value.dval;
+#endif		
+		result->type = IS_LONG;
+		return SUCCESS;
 	}
 	if (op1->type == IS_LONG) {
 		result->value.lval = ~op1->value.lval;

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to