msopacua Sat Oct 5 19:51:00 2002 EDT Modified files: (Branch: PHP_4_3) /php4/ext/xslt php_sablot.h sablot.c xslt.c Log: (xslt) Introduce revised interaction with Sablotron backend. ATTENTION: interaction with Sablotron backend, now uses the API prefered by the Ginger Alliance. Test it for BC issues. It also changes internals of the abstraction, to resolve issues that would arrise with invalid argument or parameter arrays. New functions: * xslt_set_object, similar to xml_set_object * xslt_setopt, set global options for a processor instance. Introduces new constants, related to the xslt_setopt function. Removes a warning, when skipping argument array with NULL.
Index: php4/ext/xslt/php_sablot.h diff -u php4/ext/xslt/php_sablot.h:1.12 php4/ext/xslt/php_sablot.h:1.12.2.1 --- php4/ext/xslt/php_sablot.h:1.12 Fri Oct 4 19:06:09 2002 +++ php4/ext/xslt/php_sablot.h Sat Oct 5 19:50:59 2002 @@ -41,6 +41,7 @@ #define XSLT_ERROR(handle) ((handle)->handlers->error) #define XSLT_PROCESSOR(handle) ((handle)->processor.ptr) +#define XSLT_SITUATION(handle) ((handle)->processor.sit) #define XSLT_ERRNO(handle) ((handle)->err->no) #define XSLT_ERRSTR(handle) ((handle)->err->str) @@ -63,6 +64,7 @@ PHP_FUNCTION(xslt_errno); PHP_FUNCTION(xslt_free); PHP_FUNCTION(xslt_set_object); +PHP_FUNCTION(xslt_setopt); PHP_FUNCTION(xslt_backend_version); PHP_FUNCTION(xslt_backend_name); @@ -95,6 +97,7 @@ struct xslt_processor { SablotHandle ptr; + SablotSituation sit; long idx; }; Index: php4/ext/xslt/sablot.c diff -u php4/ext/xslt/sablot.c:1.56 php4/ext/xslt/sablot.c:1.56.2.1 --- php4/ext/xslt/sablot.c:1.56 Sat Oct 5 10:04:18 2002 +++ php4/ext/xslt/sablot.c Sat Oct 5 19:50:59 2002 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sablot.c,v 1.56 2002/10/05 14:04:18 msopacua Exp $ */ +/* $Id: sablot.c,v 1.56.2.1 2002/10/05 23:50:59 msopacua Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -90,6 +90,7 @@ PHP_FE(xslt_errno, NULL) PHP_FE(xslt_free, NULL) PHP_FE(xslt_set_object, second_args_force_ref) + PHP_FE(xslt_setopt, NULL) PHP_FE(xslt_backend_version, NULL) PHP_FE(xslt_backend_name, NULL) {NULL, NULL, NULL} @@ -155,6 +156,16 @@ PHP_MINIT_FUNCTION(xslt) { le_xslt = zend_register_list_destructors_ex(free_processor, NULL, le_xslt_name, module_number); + + /* Generic options, which can apply to 'all' xslt processors */ + REGISTER_LONG_CONSTANT("XSLT_SILENT", SAB_NO_ERROR_REPORTING, CONST_CS | +CONST_PERSISTENT); + + /* Sablotron specific options */ + REGISTER_LONG_CONSTANT("XSLT_SAB_PARSE_PUBLIC_ENTITIES", +SAB_PARSE_PUBLIC_ENTITIES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XSLT_SAB_DISABLE_ADDING_META", +SAB_DISABLE_ADDING_META, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XSLT_SAB_DISABLE_STRIPPING", SAB_DISABLE_STRIPPING, +CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XSLT_SAB_IGNORE_DOC_NOT_FOUND", +SAB_IGNORE_DOC_NOT_FOUND, CONST_CS | CONST_PERSISTENT); + return SUCCESS; } /* }}} */ @@ -179,6 +190,7 @@ { php_xslt *handle; /* The php -> sablotron handle */ SablotHandle processor; /* The sablotron processor */ + SablotSituation sit; /* The sablotron Situation handle */ int error; /* The error container */ /* Allocate the php-sablotron handle */ @@ -190,7 +202,8 @@ XSLT_LOG(handle).path = NULL; /* Allocate the actual processor itself, via sablotron */ - error = SablotCreateProcessor(&processor); + SablotCreateSituation(&sit); + error = SablotCreateProcessorForSituation(sit, &processor); if (error) { XSLT_ERRNO(handle) = error; RETURN_FALSE; @@ -198,6 +211,7 @@ /* Save the processor and set the default handlers */ XSLT_PROCESSOR(handle) = processor; + XSLT_SITUATION(handle) = sit; SablotRegHandler(XSLT_PROCESSOR(handle), HLR_SAX, (void *) &sax_handlers, (void *) handle); SablotRegHandler(XSLT_PROCESSOR(handle), HLR_MESSAGE, (void *) &message_handler, (void *) handle); SablotRegHandler(XSLT_PROCESSOR(handle), HLR_SCHEME, (void *) &scheme_handler, (void *) handle); @@ -483,6 +497,7 @@ char *result; /* The result file or argument buffer */ int argc = ZEND_NUM_ARGS(); /* The number of arguments given */ int error; /* Our error container */ + int i; /* iterator for Situation */ if (argc < 3 || argc > 6 || zend_get_parameters_ex(argc, &processor_p, &xml_p, &xslt_p, &result_p, &args_p, ¶ms_p) == FAILURE) { @@ -510,14 +525,33 @@ /* Translate a PHP array into a Sablotron array */ if (argc > 4) { xslt_make_array(args_p, &args); + /* Can return NULL */ + if (args) { + i=0; + while(args[i]) { + /* We can safely add args[i+1] since xslt_make_array +sets args[i] to NULL if + a key on the array is missing. */ + /* For now, we don't care about the error. So don't +store it. */ + SablotAddArgBuffer(XSLT_SITUATION(handle), +XSLT_PROCESSOR(handle), args[i], args[i+1]); + i+=2; + } + } } if (argc > 5) { xslt_make_array(params_p, ¶ms); + /* Can return NULL */ + if (params) { + i=0; + while(params[i]) { + SablotAddParam(XSLT_SITUATION(handle), +XSLT_PROCESSOR(handle), params[i], params[i+1]); + i+=2; + } + } } /* Perform transformation */ - error = SablotRunProcessor(XSLT_PROCESSOR(handle), xslt, xml, result, (const char**)params, (const char**)args); + error = SablotRunProcessorGen(XSLT_SITUATION(handle), XSLT_PROCESSOR(handle), +xslt, xml, result); if (error) { XSLT_ERRNO(handle) = error; @@ -633,6 +667,56 @@ } /* }}} */ +/* {{{ proto int xslt_setopt(resource processor, int bitmask) + Set options on a given xsl processor */ +PHP_FUNCTION(xslt_setopt) +{ + zval **processor_p; /* Resource pointer to a PHP-XSLT processor */ + zval **zbitmask; /* A bitmask created by through processor specific +constants */ + php_xslt *handle; /* A PHP-XSLT processor */ + int error; /* Error return codes */ + int bitmask; + + if (ZEND_NUM_ARGS() != 2 || + zend_get_parameters_ex(2, &processor_p, &zbitmask) == FAILURE) { + WRONG_PARAM_COUNT; + } + + ZEND_FETCH_RESOURCE(handle, php_xslt *, processor_p, -1, le_xslt_name, +le_xslt); + convert_to_long_ex(zbitmask); + + bitmask = Z_LVAL_PP(zbitmask); + if(bitmask < 0) { + php_error_docref("function.xslt-setopt" TSRMLS_CC, E_WARNING, "Invalid +bitmask: %i", bitmask); + RETURN_FALSE; + } + + error = SablotSetOptions(XSLT_SITUATION(handle), bitmask); + if(error) { + /* FIXME: Need to analyze the return code to give a more verbose error +description */ + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Failed to set options"); + } + + /* FIXME: + now returning TRUE/FALSE, but should return the previous bitmask, so +users can + temporarily set a certain option and restore the old value. + However - there's no API function in Sablotron to retrieve the current +option set. + If that becomes available, the second argument should become optional, +and if not + specified the function should return the current value. + This would allow for: + <?php + $current_settings = xslt_setopt($xh); + // Add public entity support, retaining any options set at present + xslt_setopt($xh, $current_settings & XSLT_SAB_PARSE_PUBLIC_ENTITIES); + ?> + */ + RETURN_TRUE; +} + +/* }}} */ + + + /* {{{ proto void xslt_backend_version() Returns the version number of Sablotron (if available) */ PHP_FUNCTION(xslt_backend_version) @@ -665,6 +749,7 @@ SablotUnregHandler(XSLT_PROCESSOR(handle), HLR_SAX, NULL, NULL); SablotUnregHandler(XSLT_PROCESSOR(handle), HLR_SCHEME, NULL, NULL); SablotDestroyProcessor(XSLT_PROCESSOR(handle)); + SablotDestroySituation(XSLT_SITUATION(handle)); } /* Free Scheme handlers */ @@ -1360,13 +1445,13 @@ Called when its time to log data */ static MH_ERROR error_log(void *user_data, SablotHandle proc, MH_ERROR code, MH_LEVEL level, char **fields) { - php_xslt *handle = (php_xslt *) user_data; /* A PHP-XSLT processor */ - char *errmsg = NULL; /* Error message*/ - char *errtype = NULL; /* Error type */ - char *errline = NULL; /* Error line */ - char *msgbuf = NULL; /* Message buffer */ + php_xslt *handle = (php_xslt *) user_data; + /* A PHP-XSLT processor */ + char *errmsg = NULL; + /* Error message*/ + char *errtype = NULL; + /* Error type */ + char *errline = NULL; + /* Error line */ + char *msgbuf = NULL; + /* Message buffer */ char msgformat[] = "Sablotron Message on line %s, level %s: %s\n"; /* Message format */ - int error = 0; /* Error container */ + int error = 0; + /* Error container */ if (!XSLT_LOG(handle).do_log) return 0; @@ -1407,6 +1492,12 @@ else if (!strcmp(key, "line")) { errline = estrndup(val, len - pos); } + /* Haven't seen this yet, but turning it on during dev, to see + what we can encounter -- MRS + else { + php_error(E_WARNING, "Got key %s with val %s", key, +val); + } + */ /* Cleanup */ if (key) efree(key); Index: php4/ext/xslt/xslt.c diff -u php4/ext/xslt/xslt.c:1.25 php4/ext/xslt/xslt.c:1.25.2.1 --- php4/ext/xslt/xslt.c:1.25 Fri Oct 4 19:06:09 2002 +++ php4/ext/xslt/xslt.c Sat Oct 5 19:50:59 2002 @@ -86,6 +86,10 @@ int idx = 0; TSRMLS_FETCH(); + /* Skip a warning, when 'NULL' is provided as argument */ + if ( Z_TYPE_PP(zarr) == IS_NULL) + return; + arr = HASH_OF(*zarr); if (! arr) { php_error(E_WARNING, "Invalid argument or parameter array to %s", @@ -107,8 +111,12 @@ type = zend_hash_get_current_key(arr, &string_key, &num_key, 0); if (type == HASH_KEY_IS_LONG) { - php_error(E_WARNING, "Invalid argument or parameter array to %s", + php_error(E_WARNING, "Invalid key value for argument or +parameter array to %s", get_active_function_name(TSRMLS_C)); + /* Make the next index NULL, so it signals the end of the array + this will protect against invalid arrays, like: + array('foo'=>'bar', 'foobarred', 'oops') */ + (*carr)[idx] = NULL; return; }
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php