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