]> granicus.if.org Git - php/commitdiff
- Fix setting previous exception and add new helper function
authorMarcus Boerger <helly@php.net>
Sun, 13 Jul 2008 21:35:23 +0000 (21:35 +0000)
committerMarcus Boerger <helly@php.net>
Sun, 13 Jul 2008 21:35:23 +0000 (21:35 +0000)
Zend/zend_exceptions.c
Zend/zend_exceptions.h

index 8ec5ecdb5e03c989143995dc8b7c15ec543b8f55..af0128618f6b3a9dad2d2384b4b07906d041f1ef 100644 (file)
@@ -33,13 +33,37 @@ zend_class_entry *error_exception_ce;
 static zend_object_handlers default_exception_handlers;
 ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);
 
+void zend_exception_set_previous(zval *add_previous TSRMLS_DC)
+{
+       zval *exception = EG(exception), *previous;
+
+       if (exception == add_previous || !add_previous) {
+               return;
+       }       
+       if (Z_TYPE_P(add_previous) != IS_OBJECT && !instanceof_function(Z_OBJCE_P(add_previous), default_exception_ce TSRMLS_CC)) {
+               zend_error(E_ERROR, "Cannot set non exception as previous exception");
+               return;
+       }
+       if (!exception) {
+               EG(exception) = add_previous;
+               return;
+       }
+       while (exception && exception != add_previous && Z_OBJ_HANDLE_P(exception) != Z_OBJ_HANDLE_P(add_previous)) {
+               previous = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
+               if (Z_TYPE_P(previous) == IS_NULL) {
+                       zend_update_property(default_exception_ce, exception, "previous", sizeof("previous")-1, add_previous TSRMLS_CC);
+                       return;
+               }
+               exception = previous;
+       }
+}
+
 void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */
 {
        if (exception != NULL) {
-               if (EG(exception)) {
-                       zend_update_property(default_exception_ce, exception, "previous", sizeof("previous")-1, EG(exception) TSRMLS_CC);
-               }
+               zval *previous = EG(exception);
                EG(exception) = exception;
+               zend_exception_set_previous(previous TSRMLS_CC);
        }
        if (!EG(current_execute_data)) {
                zend_error(E_ERROR, "Exception thrown without a stack frame");
@@ -130,8 +154,8 @@ ZEND_METHOD(exception, __construct)
        int    argc = ZEND_NUM_ARGS(), message_len;
        zend_uchar message_type;
 
-       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|tlO", &message, &message_len, &message_type, &code, &previous, default_exception_ce) == FAILURE) {
-               zend_error(E_ERROR, "Wrong parameters for Exception([string $exception [, long $code ]])");
+       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|tlO!", &message, &message_len, &message_type, &code, &previous, default_exception_ce) == FAILURE) {
+               zend_error(E_ERROR, "Wrong parameters for Exception([string $exception [, long $code  [, Exception $previous = NULL]]])");
        }
 
        object = getThis();
@@ -164,8 +188,8 @@ ZEND_METHOD(error_exception, __construct)
        int    argc = ZEND_NUM_ARGS(), message_len, filename_len;
        zend_uchar message_type, file_type;
 
-       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|tlltlO", &message, &message_len, &message_type, &code, &severity, &filename, &filename_len, &file_type, &lineno, &previous, default_exception_ce) == FAILURE) {
-               zend_error(E_ERROR, "Wrong parameters for ErrorException([string $exception [, long $code, [ long $severity, [ string $filename, [ long $lineno ]]]]])");
+       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|tlltlO!", &message, &message_len, &message_type, &code, &severity, &filename, &filename_len, &file_type, &lineno, &previous, default_exception_ce) == FAILURE) {
+               zend_error(E_ERROR, "Wrong parameters for ErrorException([string $exception [, long $code, [ long $severity, [ string $filename, [ long $lineno  [, Exception $previous = NULL]]]]]])");
        }
 
        object = getThis();
@@ -317,7 +341,7 @@ ZEND_METHOD(error_exception, getSeverity)
 #define TRACE_APPEND_STR(val)                                            \
        TRACE_APPEND_STRL(val, sizeof(val)-1)
 
-#define TRACE_APPEND_KEY(key,dump)                                            \
+#define TRACE_APPEND_KEY(key)                                            \
        if (zend_ascii_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) { \
            TRACE_APPEND_ZVAL(*tmp);           \
        }
@@ -493,9 +517,9 @@ static int _build_trace_string(zval **frame, int num_args, va_list args, zend_ha
        } else {
                TRACE_APPEND_STR("[internal function]: ");
        }
-       TRACE_APPEND_KEY("class",0);
-       TRACE_APPEND_KEY("type",0);
-       TRACE_APPEND_KEY("function",1);
+       TRACE_APPEND_KEY("class");
+       TRACE_APPEND_KEY("type");
+       TRACE_APPEND_KEY("function");
        TRACE_APPEND_CHR('(');
        if (zend_ascii_hash_find(ht, "args", sizeof("args"), (void**)&tmp) == SUCCESS) {
                int last_len = *len;
index d1ed1f58e2c22c1c860b9fc7f49c482b5bd703f7..d8fa3938f062579648437b0765ca93dc611483b3 100644 (file)
@@ -26,6 +26,8 @@
 
 BEGIN_EXTERN_C()
 
+ZEND_API void zend_exception_set_previous(zval *add_previous TSRMLS_DC);
+
 void zend_throw_exception_internal(zval *exception TSRMLS_DC);
 
 void zend_register_default_exception(TSRMLS_D);