mike            Wed Aug 30 07:39:09 2006 UTC

  Modified files:              
    /php-src/main       output.c php_output.h 
    /php-src    README.NEW-OUTPUT-API 
  Log:
  - revise output handler alias API
  - add convenience macros for conflicts and aliases
  - generalize flags to php_output_stack_pop()
  - mark the handler as started *after* run
  - handler should still be flushable after marking it immutable
  
  
  
http://cvs.php.net/viewvc.cgi/php-src/main/output.c?r1=1.191&r2=1.192&diff_format=u
Index: php-src/main/output.c
diff -u php-src/main/output.c:1.191 php-src/main/output.c:1.192
--- php-src/main/output.c:1.191 Tue Aug 22 09:56:24 2006
+++ php-src/main/output.c       Wed Aug 30 07:39:09 2006
@@ -19,7 +19,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: output.c,v 1.191 2006/08/22 09:56:24 mike Exp $ */
+/* $Id: output.c,v 1.192 2006/08/30 07:39:09 mike Exp $ */
 
 #ifndef PHP_OUTPUT_DEBUG
 #      define PHP_OUTPUT_DEBUG 0
@@ -62,7 +62,7 @@
 static inline void php_output_context_swap(php_output_context *context);
 static inline void php_output_context_dtor(php_output_context *context);
 
-static inline int php_output_stack_pop(int discard, int shutdown TSRMLS_DC);
+static inline int php_output_stack_pop(int flags TSRMLS_DC);
 
 static int php_output_stack_apply_op(void *h, void *c);
 static int php_output_stack_apply_clean(void *h, void *c);
@@ -344,7 +344,7 @@
        Finalizes the most recent output handler at pops it off the stack if 
the handler is removable */
 PHPAPI int php_output_end(TSRMLS_D)
 {
-       if (php_output_stack_pop(0, 0 TSRMLS_CC)) {
+       if (php_output_stack_pop(PHP_OUTPUT_POP_TRY TSRMLS_CC)) {
                return SUCCESS;
        }
        return FAILURE;
@@ -355,7 +355,7 @@
        Finalizes all output handlers and ends output buffering without regard 
whether a handler is removable */
 PHPAPI void php_output_end_all(TSRMLS_D)
 {
-       while (OG(active) && php_output_stack_pop(0, 1 TSRMLS_CC));
+       while (OG(active) && php_output_stack_pop(PHP_OUTPUT_POP_FORCE 
TSRMLS_CC));
 }
 /* }}} */
 
@@ -363,7 +363,7 @@
        Discards the most recent output handlers buffer and pops it off the 
stack if the handler is removable */
 PHPAPI int php_output_discard(TSRMLS_D)
 {
-       if (php_output_stack_pop(1, 0 TSRMLS_CC)) {
+       if (php_output_stack_pop(PHP_OUTPUT_POP_DISCARD|PHP_OUTPUT_POP_TRY 
TSRMLS_CC)) {
                return SUCCESS;
        }
        return FAILURE;
@@ -375,7 +375,7 @@
 PHPAPI void php_output_discard_all(TSRMLS_D)
 {
        while (OG(active)) {
-               php_output_stack_pop(1, 1 TSRMLS_CC);
+               
php_output_stack_pop(PHP_OUTPUT_POP_DISCARD|PHP_OUTPUT_POP_FORCE TSRMLS_CC);
        }
 }
 /* }}} */
@@ -486,15 +486,17 @@
 {
        zval *handler_name = NULL;
        php_output_handler *handler = NULL;
-       php_output_handler_context_func_t *internal = NULL;
+       php_output_handler_alias_ctor_t *alias = NULL;
        
        switch (Z_TYPE_P(output_handler)) {
                case IS_NULL:
+                       handler = 
php_output_handler_create_internal(OG(default_output_handler_name), 
php_output_handler_default_func, chunk_size, flags TSRMLS_CC);
                        break;
                case IS_STRING:
                case IS_UNICODE:
-                       if (Z_UNILEN_P(output_handler) && (internal = 
php_output_handler_alias(output_handler TSRMLS_CC))) {
-                               return 
php_output_handler_create_internal(output_handler, *internal, chunk_size, flags 
TSRMLS_CC);
+                       if (Z_UNILEN_P(output_handler) && (alias = 
php_output_handler_alias(output_handler TSRMLS_CC))) {
+                               handler = (*alias)(output_handler TSRMLS_CC);
+                               break;
                        }
                default:
                        MAKE_STD_ZVAL(handler_name);
@@ -505,10 +507,9 @@
                                handler->func.user = output_handler;
                        }
                        zval_ptr_dtor(&handler_name);
-                       return handler;
        }
        
-       return 
php_output_handler_create_internal(OG(default_output_handler_name), 
php_output_handler_default_func, chunk_size, flags TSRMLS_CC);
+       return handler;
 }
 /* }}} */
 
@@ -596,7 +597,11 @@
 PHPAPI int php_output_handler_conflict(zval *handler_new, zval *handler_set 
TSRMLS_DC)
 {
        if (php_output_handler_started(handler_set TSRMLS_CC)) {
-               php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "output 
handler '%v' conflicts with '%v'", Z_UNIVAL_P(handler_new), 
Z_UNIVAL_P(handler_set));
+               if (zend_binary_zval_strcmp(handler_new, handler_set)) {
+                       php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, 
"output handler '%v' conflicts with '%v'", Z_UNIVAL_P(handler_new), 
Z_UNIVAL_P(handler_set));
+               } else {
+                       php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, 
"output handler '%v' cannot be used twice", Z_UNIVAL_P(handler_new));
+               }
                return 1;
        }
        return 0;
@@ -644,24 +649,24 @@
 
 /* {{{ php_output_handler_context_func_t php_output_handler_alias(zval *name 
TSRMLS_DC)
        Get an internal output handler for a user handler if it exists */
-PHPAPI php_output_handler_context_func_t *php_output_handler_alias(zval *name 
TSRMLS_DC)
+PHPAPI php_output_handler_alias_ctor_t *php_output_handler_alias(zval *name 
TSRMLS_DC)
 {
-       php_output_handler_context_func_t *func = NULL;
+       php_output_handler_alias_ctor_t *func = NULL;
        
        zend_u_hash_find(&php_output_handler_aliases, Z_TYPE_P(name), 
Z_UNIVAL_P(name), Z_UNILEN_P(name), (void *) &func);
        return func;
 }
 /* }}} */
 
-/* {{{ SUCCESS|FAILURE php_output_handler_alias_register(zval *name, 
php_output_handler_context_func_t func TSRMLS_DC)
+/* {{{ SUCCESS|FAILURE php_output_handler_alias_register(zval *name, 
php_output_handler_alias_ctor_t func TSRMLS_DC)
        Registers an internal output handler as alias for a user handler */
-PHPAPI int php_output_handler_alias_register_ex(zval *name, 
php_output_handler_context_func_t func TSRMLS_DC)
+PHPAPI int php_output_handler_alias_register(zval *name, 
php_output_handler_alias_ctor_t func TSRMLS_DC)
 {
        if (!EG(current_module)) {
                zend_error(E_ERROR, "Cannot register an output handler alias 
outside of MINIT");
                return FAILURE;
        }
-       return zend_u_hash_update(&php_output_handler_aliases, Z_TYPE_P(name), 
Z_UNIVAL_P(name), Z_UNILEN_P(name), &func, 
sizeof(php_output_handler_context_func_t *), NULL);
+       return zend_u_hash_update(&php_output_handler_aliases, Z_TYPE_P(name), 
Z_UNIVAL_P(name), Z_UNILEN_P(name), &func, 
sizeof(php_output_handler_alias_ctor_t *), NULL);
 }
 /* }}} */
 
@@ -680,7 +685,7 @@
                        case PHP_OUTPUT_HANDLER_HOOK_GET_LEVEL:
                                *(int *) arg = OG(running)->level;
                        case PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE:
-                               OG(running)->flags &= 
~PHP_OUTPUT_HANDLER_STDFLAGS;
+                               OG(running)->flags &= 
~(PHP_OUTPUT_HANDLER_REMOVABLE|PHP_OUTPUT_HANDLER_CLEANABLE);
                                return SUCCESS;
                        case PHP_OUTPUT_HANDLER_HOOK_DISABLE:
                                OG(running)->flags |= 
PHP_OUTPUT_HANDLER_DISABLED;
@@ -919,7 +924,6 @@
        } else {
                /* need to start? */
                if (!(handler->flags & PHP_OUTPUT_HANDLER_STARTED)) {
-                       handler->flags |= PHP_OUTPUT_HANDLER_STARTED;
                        op |= PHP_OUTPUT_HANDLER_START;
                }
                
@@ -973,6 +977,7 @@
                                status = PHP_OUTPUT_HANDLER_FAILURE;
                        }
                }
+               handler->flags |= PHP_OUTPUT_HANDLER_STARTED;
                OG(running) = NULL;
        }
        
@@ -1172,18 +1177,22 @@
 }
 /* }}} */
 
-/* {{{ static int php_output_stack_pop(int discard, int shutdown TSRMLS_DC)
-       Pops an output handler off the stack, ignores whether the handler is 
removable if shutdown==1, discards the handlers output if discard==1 */
-static inline int php_output_stack_pop(int discard, int shutdown TSRMLS_DC)
+/* {{{ static int php_output_stack_pop(int flags TSRMLS_DC)
+       Pops an output handler off the stack */
+static inline int php_output_stack_pop(int flags TSRMLS_DC)
 {
        php_output_context context;
        php_output_handler **current, *orphan = OG(active);
        
        if (!orphan) {
-               php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed 
to %s buffer. No buffer to %s", discard?"discard":"send", 
discard?"discard":"send");
+               if (!(flags & PHP_OUTPUT_POP_SILENT)) {
+                       php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, 
"failed to %s buffer. No buffer to %s", 
(flags&PHP_OUTPUT_POP_DISCARD)?"discard":"send", 
(flags&PHP_OUTPUT_POP_DISCARD)?"discard":"send");
+               }
                return 0;
-       } else if (!shutdown && !(orphan->flags & 
PHP_OUTPUT_HANDLER_REMOVABLE)) {
-               php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed 
to %s buffer of %v (%d)", discard?"discard":"send", Z_UNIVAL_P(orphan->name), 
orphan->level);
+       } else if (!(flags & PHP_OUTPUT_POP_FORCE) && !(orphan->flags & 
PHP_OUTPUT_HANDLER_REMOVABLE)) {
+               if (!(flags & PHP_OUTPUT_POP_SILENT)) {
+                       php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, 
"failed to %s buffer of %v (%d)", 
(flags&PHP_OUTPUT_POP_DISCARD)?"discard":"send", Z_UNIVAL_P(orphan->name), 
orphan->level);
+               }
                return 0;
        } else {
                php_output_context_init(&context, PHP_OUTPUT_HANDLER_FINAL 
TSRMLS_CC);
@@ -1195,7 +1204,7 @@
                                context.op |= PHP_OUTPUT_HANDLER_START;
                        }
                        /* signal that we're cleaning up */
-                       if (discard) {
+                       if (flags & PHP_OUTPUT_POP_DISCARD) {
                                context.op |= PHP_OUTPUT_HANDLER_CLEAN;
                                orphan->buffer.used = 0;
                        }
@@ -1211,7 +1220,7 @@
                }
                
                /* pass output along */
-               if (context.out.data && context.out.used && !discard) {
+               if (context.out.data && context.out.used && !(flags & 
PHP_OUTPUT_POP_DISCARD)) {
                        php_output_write(context.out.data, context.out.used 
TSRMLS_CC);
                }
                
http://cvs.php.net/viewvc.cgi/php-src/main/php_output.h?r1=1.61&r2=1.62&diff_format=u
Index: php-src/main/php_output.h
diff -u php-src/main/php_output.h:1.61 php-src/main/php_output.h:1.62
--- php-src/main/php_output.h:1.61      Tue Aug 22 07:53:58 2006
+++ php-src/main/php_output.h   Wed Aug 30 07:39:09 2006
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: php_output.h,v 1.61 2006/08/22 07:53:58 mike Exp $ */
+/* $Id: php_output.h,v 1.62 2006/08/30 07:39:09 mike Exp $ */
 
 #ifndef PHP_OUTPUT_H
 #define PHP_OUTPUT_H
@@ -51,6 +51,12 @@
 #define PHP_OUTPUT_HANDLER_SUCCESS             1
 #define PHP_OUTPUT_HANDLER_NO_DATA             2
 
+/* php_output_stack_pop() flags */
+#define PHP_OUTPUT_POP_TRY                     0x000
+#define PHP_OUTPUT_POP_FORCE           0x001
+#define PHP_OUTPUT_POP_DISCARD         0x010
+#define PHP_OUTPUT_POP_SILENT          0x100
+
 /* real global flags */
 #define PHP_OUTPUT_IMPLICITFLUSH               0x01
 #define PHP_OUTPUT_DISABLED                            0x02
@@ -96,8 +102,12 @@
 typedef void (*php_output_handler_func_t)(char *output, uint output_len, char 
**handled_output, uint *handled_output_len, int mode TSRMLS_DC);
 /* new-style, opaque context callback */
 typedef int (*php_output_handler_context_func_t)(void **handler_context, 
php_output_context *output_context);
+/* output handler context dtor */
+typedef void (*php_output_handler_context_dtor_t)(void *opaq TSRMLS_DC);
 /* conflict check callback */
 typedef int (*php_output_handler_conflict_check_t)(zval *handler_name 
TSRMLS_DC);
+/* ctor for aliases */
+typedef struct _php_output_handler *(*php_output_handler_alias_ctor_t)(zval 
*handler_name TSRMLS_DC);
 
 typedef struct _php_output_handler {
        zval *name;
@@ -218,8 +228,41 @@
 PHPAPI int php_output_handler_conflict_register(zval *handler_name, 
php_output_handler_conflict_check_t check_func TSRMLS_DC);
 PHPAPI int php_output_handler_reverse_conflict_register(zval *handler_name, 
php_output_handler_conflict_check_t check_func TSRMLS_DC);
 
-PHPAPI php_output_handler_context_func_t *php_output_handler_alias(zval 
*handler_name TSRMLS_DC);
-PHPAPI int php_output_handler_alias_register(zval *handler_name, 
php_output_handler_context_func_t func TSRMLS_DC);
+#define PHP_OUTPUT_CONFLICT_REGISTER(name, func) \
+{ \
+       zval tmp_z; \
+       char *tmp_s = (name); \
+       INIT_PZVAL(&tmp_z); \
+       ZVAL_ASCII_STRING(&tmp_z, tmp_s, ZSTR_DUPLICATE); \
+       php_output_handler_conflict_register(&tmp_z, func TSRMLS_CC); \
+       zval_dtor(&tmp_z); \
+}
+
+#define PHP_OUTPUT_CONFLICT(check_name, action) \
+{ \
+       char *tmp_s = (check_name); \
+       zval tmp_z; \
+       INIT_PZVAL(&tmp_z); \
+       ZVAL_ASCII_STRING(&tmp_z, tmp_s, ZSTR_DUPLICATE); \
+       if (php_output_handler_conflict(handler_name, &tmp_z TSRMLS_CC)) { \
+               zval_dtor(&tmp_z); \
+               action; \
+       } \
+       zval_dtor(&tmp_z); \
+}
+
+PHPAPI php_output_handler_alias_ctor_t *php_output_handler_alias(zval 
*handler_name TSRMLS_DC);
+PHPAPI int php_output_handler_alias_register(zval *handler_name, 
php_output_handler_alias_ctor_t func TSRMLS_DC);
+
+#define PHP_OUTPUT_ALIAS_REGISTER(name, func) \
+{ \
+       zval tmp_z; \
+       char *tmp_s = (name); \
+       INIT_PZVAL(&tmp_z); \
+       ZVAL_ASCII_STRING(&tmp_z, tmp_s, ZSTR_DUPLICATE); \
+       php_output_handler_alias_register(&tmp_z, func TSRMLS_CC); \
+       zval_dtor(&tmp_z); \
+}
 
 END_EXTERN_C()
 
http://cvs.php.net/viewvc.cgi/php-src/README.NEW-OUTPUT-API?r1=1.2&r2=1.3&diff_format=u
Index: php-src/README.NEW-OUTPUT-API
diff -u php-src/README.NEW-OUTPUT-API:1.2 php-src/README.NEW-OUTPUT-API:1.3
--- php-src/README.NEW-OUTPUT-API:1.2   Sat Jun  3 11:22:59 2006
+++ php-src/README.NEW-OUTPUT-API       Wed Aug 30 07:39:09 2006
@@ -1,4 +1,4 @@
-$Id: README.NEW-OUTPUT-API,v 1.2 2006/06/03 11:22:59 mike Exp $
+$Id: README.NEW-OUTPUT-API,v 1.3 2006/08/30 07:39:09 mike Exp $
 
 
 API adjustment to the old output control code:
@@ -121,6 +121,9 @@
                        pointer to the opaque field of the output handler 
context
                PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS
                        pass a int* pointer as second arg to receive the flags 
set for the output handler
+               PHP_OUTPUT_HANDLER_HOOK_GET_LEVEL
+                       pass a int* pointer as second arg to receive the level 
of this output handler
+                       (starts with 0)
                PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE
                        the second arg is ignored; marks the output handler to 
be neither cleanable
                        nor removable

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to