]> granicus.if.org Git - php/commitdiff
Unicode support
authorDmitry Stogov <dmitry@php.net>
Thu, 18 Aug 2005 10:18:40 +0000 (10:18 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 18 Aug 2005 10:18:40 +0000 (10:18 +0000)
Zend/zend_exceptions.c
main/output.c

index 5b92168507af840d873df2041b5973285e06b472..e1261b17c1bd115fd7eb8e70235a6ae0e0f0485f 100644 (file)
@@ -283,7 +283,15 @@ ZEND_METHOD(error_exception, getSeverity)
 
 #define TRACE_APPEND_KEY(key)                                            \
        if (zend_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) { \
+               if (Z_TYPE_PP(tmp) == IS_UNICODE) { \
+                       zval copy; \
+                       int use_copy; \
+                       zend_make_printable_zval(*tmp, &copy, &use_copy); \
+           TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \
+           zval_dtor(&copy); \
+               } else { \
            TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));           \
+         } \
        }
 
 static int _build_trace_args(zval **arg, int num_args, va_list args, zend_hash_key *hash_key)
@@ -475,8 +483,6 @@ ZEND_METHOD(exception, __toString)
        _default_exception_get_entry(getThis(), "file", sizeof("file")-1, &file TSRMLS_CC);
        _default_exception_get_entry(getThis(), "line", sizeof("line")-1, &line TSRMLS_CC);
 
-       convert_to_text(&message);
-       convert_to_text(&file);
        convert_to_long(&line);
 
        ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1, 0);
@@ -498,12 +504,12 @@ ZEND_METHOD(exception, __toString)
        }
 
        if (Z_UNILEN(message) > 0) {
-               len = zend_spprintf(&str, 0, "exception '%v' with message '%R' in %s:%ld\nStack trace:\n%s", 
-                                                       Z_OBJCE_P(getThis())->name, Z_TYPE(message), Z_UNIVAL(message), Z_STRVAL(file), Z_LVAL(line), 
+               len = zend_spprintf(&str, 0, "exception '%v' with message '%R' in %R:%ld\nStack trace:\n%s", 
+                                                       Z_OBJCE_P(getThis())->name, Z_TYPE(message), Z_UNIVAL(message), Z_TYPE(file), Z_UNIVAL(file), Z_LVAL(line), 
                                                        (trace && Z_STRLEN_P(trace)) ? Z_STRVAL_P(trace) : "#0 {main}\n");
        } else {
-               len = zend_spprintf(&str, 0, "exception '%v' in %s:%ld\nStack trace:\n%s", 
-                                                       Z_OBJCE_P(getThis())->name, Z_STRVAL(file), Z_LVAL(line), 
+               len = zend_spprintf(&str, 0, "exception '%v' in %R:%ld\nStack trace:\n%s", 
+                                                       Z_OBJCE_P(getThis())->name, Z_TYPE(file), Z_UNIVAL(file), Z_LVAL(line), 
                                                        (trace && Z_STRLEN_P(trace)) ? Z_STRVAL_P(trace) : "#0 {main}\n");
        }
 
index af4f6a5ed974fe9e48802de1fe84e458f594fa69..9dc7c80a16e4afc3c23030cd5f709521e32f559c 100644 (file)
@@ -411,14 +411,23 @@ PHPAPI int php_ob_init_conflict(char *handler_new, char *handler_set TSRMLS_DC)
 
 /* {{{ php_ob_init_named
  */
-static int php_ob_init_named(uint initial_size, uint block_size, char *handler_name, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC)
+static int php_ob_init_named(uint initial_size, uint block_size, zend_uchar type, char *handler_name, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC)
 {
+       int handler_len;
+
        if (output_handler && !zend_is_callable(output_handler, 0, NULL)) {
                return FAILURE;
        }
+       if (type == IS_UNICODE) {
+               handler_len = u_strlen(handler_name);
+       } else {
+               handler_len = strlen(handler_name);
+       }
        if (OG(ob_nesting_level)>0) {
 #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
-               if (!strncmp(handler_name, "ob_gzhandler", sizeof("ob_gzhandler")) && php_ob_gzhandler_check(TSRMLS_C)) {
+               if ((handler_len == sizeof("ob_gzhandler")-1) && 
+                   (ZEND_U_EQUAL(type, handler_name, handler_len, "ob_gzhandler", sizeof("ob_gzhandler"))) &&
+                   php_ob_gzhandler_check(TSRMLS_C)) {
                        return FAILURE;
                }
 #endif
@@ -436,7 +445,11 @@ static int php_ob_init_named(uint initial_size, uint block_size, char *handler_n
        OG(active_ob_buffer).chunk_size = chunk_size;
        OG(active_ob_buffer).status = 0;
        OG(active_ob_buffer).internal_output_handler = NULL;
-       OG(active_ob_buffer).handler_name = estrdup(handler_name&&handler_name[0]?handler_name:OB_DEFAULT_HANDLER_NAME);
+       if (type == IS_UNICODE) {
+               OG(active_ob_buffer).handler_name = eustrdup(handler_name&&handler_name[0]?handler_name:OB_DEFAULT_HANDLER_NAME);
+       } else {
+               OG(active_ob_buffer).handler_name = estrdup(handler_name&&handler_name[0]?handler_name:OB_DEFAULT_HANDLER_NAME);
+       }
        OG(active_ob_buffer).erase = erase;
        OG(php_body_write) = php_b_body_write;
        return SUCCESS;
@@ -458,18 +471,33 @@ static zval* php_ob_handler_from_string(const char *handler_name, int len TSRMLS
 }
 /* }}} */
 
+/* {{{ php_ob_handler_from_unicode
+ * Create zval output handler from unicode 
+ */
+static zval* php_ob_handler_from_unicode(const UChar *handler_name, int len TSRMLS_DC)
+{
+       zval *output_handler;
+
+       ALLOC_INIT_ZVAL(output_handler);
+       Z_USTRLEN_P(output_handler) = len;
+       Z_USTRVAL_P(output_handler) = eustrndup(handler_name, len);
+       Z_TYPE_P(output_handler) = IS_UNICODE;
+       return output_handler;
+}
+/* }}} */
+
 /* {{{ php_ob_init
  */
 static int php_ob_init(uint initial_size, uint block_size, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC)
 {
        int result = FAILURE, handler_len, len;
-       char *handler_name, *next_handler_name;
        HashPosition pos;
        zval **tmp;
        zval *handler_zval;
 
        if (output_handler && output_handler->type == IS_STRING) {
-               handler_name = Z_STRVAL_P(output_handler);
+               char* next_handler_name;
+               char* handler_name = Z_STRVAL_P(output_handler);
                handler_len  = Z_STRLEN_P(output_handler);
 
                result = SUCCESS;
@@ -478,7 +506,7 @@ static int php_ob_init(uint initial_size, uint block_size, zval *output_handler,
                                len = next_handler_name-handler_name;
                                next_handler_name = estrndup(handler_name, len);
                                handler_zval = php_ob_handler_from_string(next_handler_name, len TSRMLS_CC);
-                               result = php_ob_init_named(initial_size, block_size, next_handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
+                               result = php_ob_init_named(initial_size, block_size, IS_STRING, next_handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
                                if (result != SUCCESS) {
                                        zval_dtor(handler_zval);
                                        FREE_ZVAL(handler_zval);
@@ -490,18 +518,49 @@ static int php_ob_init(uint initial_size, uint block_size, zval *output_handler,
                }
                if (result == SUCCESS) {
                        handler_zval = php_ob_handler_from_string(handler_name, handler_len TSRMLS_CC);
-                       result = php_ob_init_named(initial_size, block_size, handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
+                       result = php_ob_init_named(initial_size, block_size, IS_STRING, handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
+                       if (result != SUCCESS) {
+                               zval_dtor(handler_zval);
+                               FREE_ZVAL(handler_zval);
+                       }
+               }
+       } else if (output_handler && output_handler->type == IS_UNICODE) {
+               UChar* next_handler_name;
+               UChar* handler_name = Z_USTRVAL_P(output_handler);
+               handler_len  = Z_USTRLEN_P(output_handler);
+
+               result = SUCCESS;
+               if (handler_len && handler_name[0] != 0) {
+                       while ((next_handler_name=u_strchr(handler_name, ',')) != NULL) {
+                               len = next_handler_name-handler_name;
+                               next_handler_name = eustrndup(handler_name, len);
+                               handler_zval = php_ob_handler_from_unicode(next_handler_name, len TSRMLS_CC);
+                               result = php_ob_init_named(initial_size, block_size, IS_UNICODE, next_handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
+                               if (result != SUCCESS) {
+                                       zval_dtor(handler_zval);
+                                       FREE_ZVAL(handler_zval);
+                               }
+                               handler_name += len+1;
+                               handler_len -= len+1;
+                               efree(next_handler_name);
+                       }
+               }
+               if (result == SUCCESS) {
+                       handler_zval = php_ob_handler_from_unicode(handler_name, handler_len TSRMLS_CC);
+                       result = php_ob_init_named(initial_size, block_size, IS_UNICODE, handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
                        if (result != SUCCESS) {
                                zval_dtor(handler_zval);
                                FREE_ZVAL(handler_zval);
                        }
                }
        } else if (output_handler && output_handler->type == IS_ARRAY) {
+               char* handler_name;
+
                /* do we have array(object,method) */
                if (zend_is_callable(output_handler, 0, &handler_name)) {
                        SEPARATE_ZVAL(&output_handler);
                        output_handler->refcount++;
-                       result = php_ob_init_named(initial_size, block_size, handler_name, output_handler, chunk_size, erase TSRMLS_CC);
+                       result = php_ob_init_named(initial_size, block_size, UG(unicode)?IS_UNICODE:IS_STRING, handler_name, output_handler, chunk_size, erase TSRMLS_CC);
                        efree(handler_name);
                } else {
                        efree(handler_name);
@@ -519,7 +578,7 @@ static int php_ob_init(uint initial_size, uint block_size, zval *output_handler,
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "No method name given: use ob_start(array($object,'method')) to specify instance $object and the name of a method of class %v to use as output handler", Z_OBJCE_P(output_handler)->name);
                result = FAILURE;
        } else {
-               result = php_ob_init_named(initial_size, block_size, OB_DEFAULT_HANDLER_NAME, NULL, chunk_size, erase TSRMLS_CC);
+               result = php_ob_init_named(initial_size, block_size, IS_STRING, OB_DEFAULT_HANDLER_NAME, NULL, chunk_size, erase TSRMLS_CC);
        }
        return result;
 }