Annotation of embedaddon/php/ext/xsl/xsltprocessor.c, revision 1.1

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | PHP Version 5                                                        |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1997-2012 The PHP Group                                |
        !             6:    +----------------------------------------------------------------------+
        !             7:    | This source file is subject to version 3.01 of the PHP license,      |
        !             8:    | that is bundled with this package in the file LICENSE, and is        |
        !             9:    | available through the world-wide-web at the following url:           |
        !            10:    | http://www.php.net/license/3_01.txt                                  |
        !            11:    | If you did not receive a copy of the PHP license and are unable to   |
        !            12:    | obtain it through the world-wide-web, please send a note to          |
        !            13:    | license@php.net so we can mail you a copy immediately.               |
        !            14:    +----------------------------------------------------------------------+
        !            15:    | Authors: Christian Stocker <chregu@php.net>                          |
        !            16:    |          Rob Richards <rrichards@php.net>                            |
        !            17:    +----------------------------------------------------------------------+
        !            18: */
        !            19: 
        !            20: /* $Id: xsltprocessor.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            21: 
        !            22: #ifdef HAVE_CONFIG_H
        !            23: #include "config.h"
        !            24: #endif
        !            25: 
        !            26: #include "php.h"
        !            27: #include "php_xsl.h"
        !            28: #include "ext/libxml/php_libxml.h"
        !            29: 
        !            30: /* {{{ arginfo */
        !            31: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_import_stylesheet, 0, 0, 1)
        !            32:        ZEND_ARG_INFO(0, doc)
        !            33: ZEND_END_ARG_INFO();
        !            34: 
        !            35: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_transform_to_doc, 0, 0, 1)
        !            36:        ZEND_ARG_INFO(0, doc)
        !            37: ZEND_END_ARG_INFO();
        !            38: 
        !            39: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_transform_to_uri, 0, 0, 2)
        !            40:        ZEND_ARG_INFO(0, doc)
        !            41:        ZEND_ARG_INFO(0, uri)
        !            42: ZEND_END_ARG_INFO();
        !            43: 
        !            44: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_transform_to_xml, 0, 0, 1)
        !            45:        ZEND_ARG_INFO(0, doc)
        !            46: ZEND_END_ARG_INFO();
        !            47: 
        !            48: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_set_parameter, 0, 0, 2)
        !            49:        ZEND_ARG_INFO(0, namespace)
        !            50:        ZEND_ARG_INFO(0, name)
        !            51:        ZEND_ARG_INFO(0, value)
        !            52: ZEND_END_ARG_INFO();
        !            53: 
        !            54: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_get_parameter, 0, 0, 2)
        !            55:        ZEND_ARG_INFO(0, namespace)
        !            56:        ZEND_ARG_INFO(0, name)
        !            57: ZEND_END_ARG_INFO();
        !            58: 
        !            59: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_remove_parameter, 0, 0, 2)
        !            60:        ZEND_ARG_INFO(0, namespace)
        !            61:        ZEND_ARG_INFO(0, name)
        !            62: ZEND_END_ARG_INFO();
        !            63: 
        !            64: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_has_exslt_support, 0, 0, 0)
        !            65: ZEND_END_ARG_INFO();
        !            66: 
        !            67: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_register_php_functions, 0, 0, 0)
        !            68:        ZEND_ARG_INFO(0, restrict)
        !            69: ZEND_END_ARG_INFO();
        !            70: 
        !            71: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_set_profiling, 0, 0, 1)
        !            72:        ZEND_ARG_INFO(0, filename)
        !            73: ZEND_END_ARG_INFO();
        !            74: /* }}} */
        !            75: 
        !            76: /*
        !            77: * class xsl_xsltprocessor 
        !            78: *
        !            79: * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
        !            80: * Since: 
        !            81: */
        !            82: 
        !            83: const zend_function_entry php_xsl_xsltprocessor_class_functions[] = {
        !            84:        PHP_FALIAS(importStylesheet, xsl_xsltprocessor_import_stylesheet, arginfo_xsl_xsltprocessor_import_stylesheet)
        !            85:        PHP_FALIAS(transformToDoc, xsl_xsltprocessor_transform_to_doc, arginfo_xsl_xsltprocessor_transform_to_doc)
        !            86:        PHP_FALIAS(transformToUri, xsl_xsltprocessor_transform_to_uri, arginfo_xsl_xsltprocessor_transform_to_uri)
        !            87:        PHP_FALIAS(transformToXml, xsl_xsltprocessor_transform_to_xml, arginfo_xsl_xsltprocessor_transform_to_xml)
        !            88:        PHP_FALIAS(setParameter, xsl_xsltprocessor_set_parameter, arginfo_xsl_xsltprocessor_set_parameter)
        !            89:        PHP_FALIAS(getParameter, xsl_xsltprocessor_get_parameter, arginfo_xsl_xsltprocessor_get_parameter)
        !            90:        PHP_FALIAS(removeParameter, xsl_xsltprocessor_remove_parameter, arginfo_xsl_xsltprocessor_remove_parameter)
        !            91:        PHP_FALIAS(hasExsltSupport, xsl_xsltprocessor_has_exslt_support, arginfo_xsl_xsltprocessor_has_exslt_support)
        !            92:        PHP_FALIAS(registerPHPFunctions, xsl_xsltprocessor_register_php_functions, arginfo_xsl_xsltprocessor_register_php_functions)
        !            93:        PHP_FALIAS(setProfiling, xsl_xsltprocessor_set_profiling, arginfo_xsl_xsltprocessor_set_profiling)
        !            94:        {NULL, NULL, NULL}
        !            95: };
        !            96: 
        !            97: /* {{{ php_xsl_xslt_string_to_xpathexpr()
        !            98:    Translates a string to a XPath Expression */
        !            99: static char *php_xsl_xslt_string_to_xpathexpr(const char *str TSRMLS_DC)
        !           100: {
        !           101:        const xmlChar *string = (const xmlChar *)str;
        !           102: 
        !           103:        xmlChar *value;
        !           104:        int str_len;
        !           105:        
        !           106:        str_len = xmlStrlen(string) + 3;
        !           107:        
        !           108:        if (xmlStrchr(string, '"')) {
        !           109:                if (xmlStrchr(string, '\'')) {
        !           110:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create XPath expression (string contains both quote and double-quotes)");
        !           111:                        return NULL;
        !           112:                }
        !           113:                value = (xmlChar*) safe_emalloc (str_len, sizeof(xmlChar), 0);
        !           114:                snprintf(value, str_len, "'%s'", string);
        !           115:        } else {
        !           116:                value = (xmlChar*) safe_emalloc (str_len, sizeof(xmlChar), 0);
        !           117:                snprintf(value, str_len, "\"%s\"", string);
        !           118:        }
        !           119:        return (char *) value;
        !           120: }
        !           121: /* }}} */
        !           122: 
        !           123: /* {{{ php_xsl_xslt_make_params()
        !           124:    Translates a PHP array to a libxslt parameters array */
        !           125: static char **php_xsl_xslt_make_params(HashTable *parht, int xpath_params TSRMLS_DC)
        !           126: {
        !           127:        
        !           128:        int parsize;
        !           129:        zval **value;
        !           130:        char *xpath_expr, *string_key = NULL;
        !           131:        ulong num_key;
        !           132:        char **params = NULL;
        !           133:        int i = 0;
        !           134: 
        !           135:        parsize = (2 * zend_hash_num_elements(parht) + 1) * sizeof(char *);
        !           136:        params = (char **)safe_emalloc((2 * zend_hash_num_elements(parht) + 1), sizeof(char *), 0);
        !           137:        memset((char *)params, 0, parsize);
        !           138: 
        !           139:        for (zend_hash_internal_pointer_reset(parht);
        !           140:                zend_hash_get_current_data(parht, (void **)&value) == SUCCESS;
        !           141:                zend_hash_move_forward(parht)) {
        !           142: 
        !           143:                if (zend_hash_get_current_key(parht, &string_key, &num_key, 1) != HASH_KEY_IS_STRING) {
        !           144:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid argument or parameter array");
        !           145:                        efree(params);
        !           146:                        return NULL;
        !           147:                } else {
        !           148:                        if (Z_TYPE_PP(value) != IS_STRING) {
        !           149:                                SEPARATE_ZVAL(value);
        !           150:                                convert_to_string(*value);
        !           151:                        }
        !           152:                        
        !           153:                        if (!xpath_params) {
        !           154:                                xpath_expr = php_xsl_xslt_string_to_xpathexpr(Z_STRVAL_PP(value) TSRMLS_CC);
        !           155:                        } else {
        !           156:                                xpath_expr = estrndup(Z_STRVAL_PP(value), Z_STRLEN_PP(value));
        !           157:                        }
        !           158:                        if (xpath_expr) {
        !           159:                                params[i++] = string_key;
        !           160:                                params[i++] = xpath_expr;
        !           161:                        } else {
        !           162:                                efree(string_key);
        !           163:                        }
        !           164:                }
        !           165:        }
        !           166: 
        !           167:        params[i++] = NULL;
        !           168: 
        !           169:        return params;
        !           170: }
        !           171: /* }}} */
        !           172: 
        !           173: static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */
        !           174: {
        !           175:        xsltTransformContextPtr tctxt;
        !           176:        zval **args;
        !           177:        zval *retval;
        !           178:        int result, i, ret;
        !           179:        int error = 0;
        !           180:        zend_fcall_info fci;
        !           181:        zval handler;
        !           182:        xmlXPathObjectPtr obj;
        !           183:        char *str;
        !           184:        char *callable = NULL;
        !           185:        xsl_object *intern;
        !           186:        
        !           187:        TSRMLS_FETCH();
        !           188: 
        !           189:        if (! zend_is_executing(TSRMLS_C)) {
        !           190:                xsltGenericError(xsltGenericErrorContext,
        !           191:                "xsltExtFunctionTest: Function called from outside of PHP\n");
        !           192:                error = 1;
        !           193:        } else {
        !           194:                tctxt = xsltXPathGetTransformContext(ctxt);
        !           195:                if (tctxt == NULL) {
        !           196:                        xsltGenericError(xsltGenericErrorContext,
        !           197:                        "xsltExtFunctionTest: failed to get the transformation context\n");
        !           198:                        error = 1;
        !           199:                } else {
        !           200:                        intern = (xsl_object *) tctxt->_private;
        !           201:                        if (intern == NULL) {
        !           202:                                xsltGenericError(xsltGenericErrorContext,
        !           203:                                "xsltExtFunctionTest: failed to get the internal object\n");
        !           204:                                error = 1;
        !           205:                        }
        !           206:                        else if (intern->registerPhpFunctions == 0) {
        !           207:                                xsltGenericError(xsltGenericErrorContext,
        !           208:                                "xsltExtFunctionTest: PHP Object did not register PHP functions\n");
        !           209:                                error = 1;
        !           210:                        }
        !           211:                }
        !           212:        }
        !           213:        
        !           214:        if (error == 1) {
        !           215:                for (i = nargs - 1; i >= 0; i--) {
        !           216:                        obj = valuePop(ctxt);
        !           217:                        xmlXPathFreeObject(obj);
        !           218:                }
        !           219:                return;
        !           220:        }
        !           221:                
        !           222:        fci.param_count = nargs - 1;
        !           223:        if (fci.param_count > 0) {
        !           224:                fci.params = safe_emalloc(fci.param_count, sizeof(zval**), 0);
        !           225:                args = safe_emalloc(fci.param_count, sizeof(zval *), 0);
        !           226:        }
        !           227:        /* Reverse order to pop values off ctxt stack */
        !           228:        for (i = nargs - 2; i >= 0; i--) {
        !           229:                obj = valuePop(ctxt);
        !           230:                MAKE_STD_ZVAL(args[i]);
        !           231:                switch (obj->type) {
        !           232:                        case XPATH_STRING:
        !           233:                                ZVAL_STRING(args[i],  obj->stringval, 1);
        !           234:                                break;
        !           235:                        case XPATH_BOOLEAN:
        !           236:                                ZVAL_BOOL(args[i],  obj->boolval);
        !           237:                                break;
        !           238:                        case XPATH_NUMBER:
        !           239:                                ZVAL_DOUBLE(args[i], obj->floatval);
        !           240:                                break;
        !           241:                        case XPATH_NODESET:
        !           242:                                if (type == 1) {
        !           243:                                        str = xmlXPathCastToString(obj);
        !           244:                                        ZVAL_STRING(args[i], str, 1);
        !           245:                                        xmlFree(str);
        !           246:                                } else if (type == 2) {
        !           247:                                        int j;
        !           248:                                        dom_object *domintern = (dom_object *)intern->doc;
        !           249:                                        array_init(args[i]);
        !           250:                                        if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
        !           251:                                                for (j = 0; j < obj->nodesetval->nodeNr; j++) {
        !           252:                                                        xmlNodePtr node = obj->nodesetval->nodeTab[j];
        !           253:                                                        zval *child;
        !           254:                                                        MAKE_STD_ZVAL(child);
        !           255:                                                        /* not sure, if we need this... it's copied from xpath.c */
        !           256:                                                        if (node->type == XML_NAMESPACE_DECL) {
        !           257:                                                                xmlNsPtr curns;
        !           258:                                                                xmlNodePtr nsparent;
        !           259:                                                                
        !           260:                                                                nsparent = node->_private;
        !           261:                                                                curns = xmlNewNs(NULL, node->name, NULL);
        !           262:                                                                if (node->children) {
        !           263:                                                                        curns->prefix = xmlStrdup((char *) node->children);
        !           264:                                                                }
        !           265:                                                                if (node->children) {
        !           266:                                                                        node = xmlNewDocNode(node->doc, NULL, (char *) node->children, node->name);
        !           267:                                                                } else {
        !           268:                                                                        node = xmlNewDocNode(node->doc, NULL, "xmlns", node->name);
        !           269:                                                                }
        !           270:                                                                node->type = XML_NAMESPACE_DECL;
        !           271:                                                                node->parent = nsparent;
        !           272:                                                                node->ns = curns;
        !           273:                                                        }
        !           274:                                                        child = php_dom_create_object(node, &ret, NULL, child, domintern TSRMLS_CC);
        !           275:                                                        add_next_index_zval(args[i], child);
        !           276:                                                }
        !           277:                                        }
        !           278:                                }
        !           279:                                break;
        !           280:                        default:
        !           281:                                str = xmlXPathCastToString(obj);
        !           282:                                ZVAL_STRING(args[i], str, 1);
        !           283:                                xmlFree(str);
        !           284:                }
        !           285:                xmlXPathFreeObject(obj);
        !           286:                fci.params[i] = &args[i];
        !           287:        }
        !           288:        
        !           289:        fci.size = sizeof(fci);
        !           290:        fci.function_table = EG(function_table);
        !           291:        
        !           292:        obj = valuePop(ctxt);
        !           293:        if (obj->stringval == NULL) {
        !           294:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Handler name must be a string");
        !           295:                xmlXPathFreeObject(obj);
        !           296:                if (fci.param_count > 0) {
        !           297:                        for (i = 0; i < nargs - 1; i++) {
        !           298:                                zval_ptr_dtor(&args[i]);
        !           299:                        }
        !           300:                        efree(args);
        !           301:                        efree(fci.params);
        !           302:                }
        !           303:                return; 
        !           304:        }
        !           305:        INIT_PZVAL(&handler);
        !           306:        ZVAL_STRING(&handler, obj->stringval, 1);
        !           307:        xmlXPathFreeObject(obj);
        !           308:        
        !           309:        fci.function_name = &handler;
        !           310:        fci.symbol_table = NULL;
        !           311:        fci.object_ptr = NULL;
        !           312:        fci.retval_ptr_ptr = &retval;
        !           313:        fci.no_separation = 0;
        !           314:        /*fci.function_handler_cache = &function_ptr;*/
        !           315:        if (!zend_make_callable(&handler, &callable TSRMLS_CC)) {
        !           316:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", callable);
        !           317:                
        !           318:        } else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable, strlen(callable) + 1) == 0) { 
        !           319:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not allowed to call handler '%s()'", callable);
        !           320:                /* Push an empty string, so that we at least have an xslt result... */
        !           321:                valuePush(ctxt, xmlXPathNewString(""));
        !           322:        } else {
        !           323:                result = zend_call_function(&fci, NULL TSRMLS_CC);
        !           324:                if (result == FAILURE) {
        !           325:                        if (Z_TYPE(handler) == IS_STRING) {
        !           326:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", Z_STRVAL_P(&handler));
        !           327:                        }
        !           328:                /* retval is == NULL, when an exception occured, don't report anything, because PHP itself will handle that */
        !           329:                } else if (retval == NULL) {
        !           330:                } else {
        !           331:                        if (retval->type == IS_OBJECT && instanceof_function( Z_OBJCE_P(retval), dom_node_class_entry TSRMLS_CC)) {
        !           332:                                xmlNode *nodep;
        !           333:                                dom_object *obj;
        !           334:                                if (intern->node_list == NULL) {
        !           335:                                        ALLOC_HASHTABLE(intern->node_list);
        !           336:                                        zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
        !           337:                                }
        !           338:                                zval_add_ref(&retval);
        !           339:                                zend_hash_next_index_insert(intern->node_list, &retval, sizeof(zval *), NULL);
        !           340:                                obj = (dom_object *)zend_object_store_get_object(retval TSRMLS_CC);
        !           341:                                nodep = dom_object_get_node(obj);
        !           342:                                valuePush(ctxt, xmlXPathNewNodeSet(nodep));
        !           343:                        } else if (retval->type == IS_BOOL) {
        !           344:                                valuePush(ctxt, xmlXPathNewBoolean(retval->value.lval));
        !           345:                        } else if (retval->type == IS_OBJECT) {
        !           346:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "A PHP Object cannot be converted to a XPath-string");
        !           347:                                valuePush(ctxt, xmlXPathNewString(""));
        !           348:                        } else {
        !           349:                                convert_to_string_ex(&retval);
        !           350:                                valuePush(ctxt, xmlXPathNewString( Z_STRVAL_P(retval)));
        !           351:                        }
        !           352:                        zval_ptr_dtor(&retval);
        !           353:                }
        !           354:        }
        !           355:        efree(callable);
        !           356:        zval_dtor(&handler);
        !           357:        if (fci.param_count > 0) {
        !           358:                for (i = 0; i < nargs - 1; i++) {
        !           359:                        zval_ptr_dtor(&args[i]);
        !           360:                }
        !           361:                efree(args);
        !           362:                efree(fci.params);
        !           363:        }
        !           364: }
        !           365: /* }}} */
        !           366: 
        !           367: void xsl_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */
        !           368: {
        !           369:        xsl_ext_function_php(ctxt, nargs, 1);
        !           370: }
        !           371: /* }}} */
        !           372: 
        !           373: void xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */
        !           374: {
        !           375:        xsl_ext_function_php(ctxt, nargs, 2);
        !           376: }
        !           377: /* }}} */
        !           378: 
        !           379: /* {{{ proto void xsl_xsltprocessor_import_stylesheet(domdocument doc);
        !           380: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
        !           381: Since: 
        !           382: */
        !           383: PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
        !           384: {
        !           385:        zval *id, *docp = NULL;
        !           386:        xmlDoc *doc = NULL, *newdoc = NULL;
        !           387:        xsltStylesheetPtr sheetp, oldsheetp;
        !           388:        xsl_object *intern;
        !           389:        int prevSubstValue, prevExtDtdValue, clone_docu = 0;
        !           390:        xmlNode *nodep = NULL;
        !           391:        zend_object_handlers *std_hnd;
        !           392:        zval *cloneDocu, *member;
        !           393:        
        !           394:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oo", &id, xsl_xsltprocessor_class_entry, &docp) == FAILURE) {
        !           395:                RETURN_FALSE;
        !           396:        }
        !           397: 
        !           398:        nodep = php_libxml_import_node(docp TSRMLS_CC);
        !           399:        
        !           400:        if (nodep) {
        !           401:                doc = nodep->doc;
        !           402:        }
        !           403:        if (doc == NULL) {
        !           404:                php_error(E_WARNING, "Invalid Document");
        !           405:                RETURN_FALSE;
        !           406:        }
        !           407: 
        !           408:        /* libxslt uses _private, so we must copy the imported 
        !           409:        stylesheet document otherwise the node proxies will be a mess */
        !           410:        newdoc = xmlCopyDoc(doc, 1);
        !           411:        xmlNodeSetBase((xmlNodePtr) newdoc, (xmlChar *)doc->URL);
        !           412:        prevSubstValue = xmlSubstituteEntitiesDefault(1);
        !           413:        prevExtDtdValue = xmlLoadExtDtdDefaultValue;
        !           414:        xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
        !           415: 
        !           416:        sheetp = xsltParseStylesheetDoc(newdoc);
        !           417:        xmlSubstituteEntitiesDefault(prevSubstValue);
        !           418:        xmlLoadExtDtdDefaultValue = prevExtDtdValue;
        !           419: 
        !           420:        if (!sheetp) {
        !           421:                xmlFreeDoc(newdoc);
        !           422:                RETURN_FALSE;
        !           423:        }
        !           424: 
        !           425:        intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); 
        !           426: 
        !           427:        std_hnd = zend_get_std_object_handlers();
        !           428:        MAKE_STD_ZVAL(member);
        !           429:        ZVAL_STRING(member, "cloneDocument", 0);
        !           430:        cloneDocu = std_hnd->read_property(id, member, BP_VAR_IS TSRMLS_CC);
        !           431:        if (Z_TYPE_P(cloneDocu) != IS_NULL) {
        !           432:                convert_to_long(cloneDocu);
        !           433:                clone_docu = Z_LVAL_P(cloneDocu);
        !           434:        }
        !           435:        efree(member);
        !           436:        if (clone_docu == 0) {
        !           437:                /* check if the stylesheet is using xsl:key, if yes, we have to clone the document _always_ before a transformation */
        !           438:                nodep = xmlDocGetRootElement(sheetp->doc);
        !           439:                if (nodep && (nodep = nodep->children)) {
        !           440:                        while (nodep) {
        !           441:                                if (nodep->type == XML_ELEMENT_NODE && xmlStrEqual(nodep->name, "key") && xmlStrEqual(nodep->ns->href, XSLT_NAMESPACE)) {
        !           442:                                        intern->hasKeys = 1;
        !           443:                                        break;
        !           444:                                }
        !           445:                                nodep = nodep->next;
        !           446:                        }
        !           447:                }
        !           448:        } else {
        !           449:                intern->hasKeys = clone_docu;
        !           450:        }
        !           451: 
        !           452:        if ((oldsheetp = (xsltStylesheetPtr)intern->ptr)) { 
        !           453:                /* free wrapper */
        !           454:                if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) {
        !           455:                        ((xsltStylesheetPtr) intern->ptr)->_private = NULL;   
        !           456:                }
        !           457:                xsltFreeStylesheet((xsltStylesheetPtr) intern->ptr);
        !           458:                intern->ptr = NULL;
        !           459:        }
        !           460: 
        !           461:        php_xsl_set_object(id, sheetp TSRMLS_CC);
        !           462:        RETVAL_TRUE;
        !           463: }
        !           464: /* }}} end xsl_xsltprocessor_import_stylesheet */
        !           465: 
        !           466: static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStylesheetPtr style, zval *docp TSRMLS_DC) /* {{{ */
        !           467: {
        !           468:        xmlDocPtr newdocp;
        !           469:        xmlDocPtr doc = NULL;
        !           470:        xmlNodePtr node = NULL;
        !           471:        xsltTransformContextPtr ctxt;
        !           472:        php_libxml_node_object *object;
        !           473:        char **params = NULL;
        !           474:        int clone;
        !           475:        zval *doXInclude, *member;
        !           476:        zend_object_handlers *std_hnd;
        !           477:        FILE *f;
        !           478:        int secPrefsError = 0;
        !           479:        int secPrefsValue;
        !           480:        xsltSecurityPrefsPtr secPrefs = NULL;
        !           481: 
        !           482:        node = php_libxml_import_node(docp TSRMLS_CC);
        !           483:        
        !           484:        if (node) {
        !           485:                doc = node->doc;
        !           486:        }
        !           487:        if (doc == NULL) {
        !           488:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Document");
        !           489:                return NULL;
        !           490:        }
        !           491: 
        !           492:        if (style == NULL) {
        !           493:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "No stylesheet associated to this object");
        !           494:                return NULL;
        !           495:        }
        !           496:        
        !           497:        if (intern->profiling) {
        !           498:                if (php_check_open_basedir(intern->profiling TSRMLS_CC)) {
        !           499:                        f = NULL;
        !           500:                } else {
        !           501:                        f = VCWD_FOPEN(intern->profiling, "w");
        !           502:                }
        !           503:        } else {
        !           504:                f = NULL;
        !           505:        }
        !           506:        
        !           507:        if (intern->parameter) {
        !           508:                params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
        !           509:        }
        !           510: 
        !           511:        intern->doc = emalloc(sizeof(php_libxml_node_object));
        !           512:        memset(intern->doc, 0, sizeof(php_libxml_node_object));
        !           513: 
        !           514:        if (intern->hasKeys == 1) {
        !           515:                doc = xmlCopyDoc(doc, 1);
        !           516:        } else {
        !           517:                object = (php_libxml_node_object *)zend_object_store_get_object(docp TSRMLS_CC);
        !           518:                intern->doc->document = object->document;
        !           519:        }
        !           520: 
        !           521:        php_libxml_increment_doc_ref(intern->doc, doc TSRMLS_CC);
        !           522: 
        !           523:        ctxt = xsltNewTransformContext(style, doc);
        !           524:        ctxt->_private = (void *) intern;
        !           525: 
        !           526:        std_hnd = zend_get_std_object_handlers();
        !           527: 
        !           528:        MAKE_STD_ZVAL(member);
        !           529:        ZVAL_STRING(member, "doXInclude", 0);
        !           530:        doXInclude = std_hnd->read_property(id, member, BP_VAR_IS TSRMLS_CC);
        !           531:        if (Z_TYPE_P(doXInclude) != IS_NULL) {
        !           532:                convert_to_long(doXInclude);
        !           533:                ctxt->xinclude = Z_LVAL_P(doXInclude);
        !           534:        }
        !           535:        efree(member);
        !           536: 
        !           537:        
        !           538:        secPrefsValue = INI_INT("xsl.security_prefs");
        !           539:        
        !           540:        /* if securityPrefs is set to NONE, we don't have to do any checks, but otherwise... */
        !           541:        if (secPrefsValue != XSL_SECPREF_NONE) {
        !           542:                secPrefs = xsltNewSecurityPrefs(); 
        !           543:                if (secPrefsValue & XSL_SECPREF_READ_FILE ) { 
        !           544:                        if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid)) { 
        !           545:                                secPrefsError = 1;
        !           546:                        }
        !           547:                }
        !           548:                if (secPrefsValue & XSL_SECPREF_WRITE_FILE ) { 
        !           549:                        if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid)) { 
        !           550:                                secPrefsError = 1;
        !           551:                        }
        !           552:                }
        !           553:                if (secPrefsValue & XSL_SECPREF_CREATE_DIRECTORY ) { 
        !           554:                        if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid)) { 
        !           555:                                secPrefsError = 1;
        !           556:                        }
        !           557:                }
        !           558:                if (secPrefsValue & XSL_SECPREF_READ_NETWORK) { 
        !           559:                        if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid)) { 
        !           560:                                secPrefsError = 1;
        !           561:                        }
        !           562:                }
        !           563:                if (secPrefsValue & XSL_SECPREF_WRITE_NETWORK) { 
        !           564:                        if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid)) { 
        !           565:                                secPrefsError = 1;
        !           566:                        }
        !           567:                }
        !           568:        
        !           569:                if (0 != xsltSetCtxtSecurityPrefs(secPrefs, ctxt)) { 
        !           570:                        secPrefsError = 1;
        !           571:                }
        !           572:        }
        !           573:        
        !           574:        if (secPrefsError == 1) {
        !           575:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't set libxslt security properties, not doing transformation for security reasons");
        !           576:        } else {
        !           577:                newdocp = xsltApplyStylesheetUser(style, doc, (const char**) params,  NULL, f, ctxt);
        !           578:        }
        !           579:        if (f) {
        !           580:                fclose(f);
        !           581:        }
        !           582:        
        !           583:        xsltFreeTransformContext(ctxt);
        !           584:        if (secPrefs) {
        !           585:                xsltFreeSecurityPrefs(secPrefs);
        !           586:        }
        !           587: 
        !           588:        if (intern->node_list != NULL) {
        !           589:                zend_hash_destroy(intern->node_list);
        !           590:                FREE_HASHTABLE(intern->node_list);      
        !           591:                intern->node_list = NULL;
        !           592:        }
        !           593: 
        !           594:        php_libxml_decrement_doc_ref(intern->doc TSRMLS_CC);
        !           595:        efree(intern->doc);
        !           596:        intern->doc = NULL;
        !           597: 
        !           598:        if (params) {
        !           599:                clone = 0;
        !           600:                while(params[clone]) {
        !           601:                        efree(params[clone++]);
        !           602:                }
        !           603:                efree(params);
        !           604:        }
        !           605: 
        !           606:        return newdocp;
        !           607: 
        !           608: }
        !           609: /* }}} */
        !           610: 
        !           611: /* {{{ proto domdocument xsl_xsltprocessor_transform_to_doc(domnode doc);
        !           612: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
        !           613: Since: 
        !           614: */
        !           615: PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
        !           616: {
        !           617:        zval *id, *rv = NULL, *docp = NULL;
        !           618:        xmlDoc *newdocp;
        !           619:        xsltStylesheetPtr sheetp;
        !           620:        int ret, ret_class_len=0;
        !           621:        char *ret_class = NULL;
        !           622:        xsl_object *intern;
        !           623: 
        !           624:        id = getThis();
        !           625:        intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           626:        sheetp = (xsltStylesheetPtr) intern->ptr;
        !           627: 
        !           628:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|s!", &docp, &ret_class, &ret_class_len) == FAILURE) {
        !           629:                RETURN_FALSE;
        !           630:        }
        !           631: 
        !           632:        newdocp = php_xsl_apply_stylesheet(id, intern, sheetp, docp TSRMLS_CC);
        !           633: 
        !           634:        if (newdocp) {
        !           635:                if (ret_class) {
        !           636:                        int found;
        !           637:                        char *curclass_name;
        !           638:                        zend_class_entry *curce, **ce;
        !           639:                        php_libxml_node_object *interndoc;
        !           640: 
        !           641:                        curce = Z_OBJCE_P(docp);
        !           642:                        curclass_name = curce->name;
        !           643:                        while (curce->parent != NULL) {
        !           644:                                curce = curce->parent;
        !           645:                        }
        !           646: 
        !           647:                        found = zend_lookup_class(ret_class, ret_class_len, &ce TSRMLS_CC);
        !           648:                        if ((found != SUCCESS) || !instanceof_function(*ce, curce TSRMLS_CC)) {
        !           649:                                xmlFreeDoc(newdocp);
        !           650:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, 
        !           651:                                        "Expecting class compatible with %s, '%s' given", curclass_name, ret_class);
        !           652:                                RETURN_FALSE;
        !           653:                        }
        !           654: 
        !           655:                        object_init_ex(return_value, *ce);
        !           656:                
        !           657:                        interndoc = (php_libxml_node_object *)zend_objects_get_address(return_value TSRMLS_CC);
        !           658:                        php_libxml_increment_doc_ref(interndoc, newdocp TSRMLS_CC);
        !           659:                        php_libxml_increment_node_ptr(interndoc, (xmlNodePtr)newdocp, (void *)interndoc TSRMLS_CC);
        !           660:                } else {
        !           661:                        DOM_RET_OBJ(rv, (xmlNodePtr) newdocp, &ret, NULL);
        !           662:                }
        !           663:        } else {
        !           664:                RETURN_FALSE;
        !           665:        }
        !           666:        
        !           667: }
        !           668: /* }}} end xsl_xsltprocessor_transform_to_doc */
        !           669: 
        !           670: /* {{{ proto int xsl_xsltprocessor_transform_to_uri(domdocument doc, string uri);
        !           671: */
        !           672: PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
        !           673: {
        !           674:        zval *id, *docp = NULL;
        !           675:        xmlDoc *newdocp;
        !           676:        xsltStylesheetPtr sheetp;
        !           677:        int ret, uri_len;
        !           678:        char *uri;
        !           679:        xsl_object *intern;
        !           680:        
        !           681:        id = getThis();
        !           682:        intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           683:        sheetp = (xsltStylesheetPtr) intern->ptr;
        !           684: 
        !           685:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "os", &docp, &uri, &uri_len) == FAILURE) {
        !           686:                RETURN_FALSE;
        !           687:        }
        !           688: 
        !           689:        newdocp = php_xsl_apply_stylesheet(id, intern, sheetp, docp TSRMLS_CC);
        !           690: 
        !           691:        ret = -1;
        !           692:        if (newdocp) {
        !           693:                if (strlen(uri) != uri_len) {
        !           694:                        xmlFreeDoc(newdocp);
        !           695:                        RETURN_FALSE;
        !           696:                }
        !           697:                ret = xsltSaveResultToFilename(uri, newdocp, sheetp, 0);
        !           698:                xmlFreeDoc(newdocp);
        !           699:        }
        !           700: 
        !           701:        RETVAL_LONG(ret);
        !           702: }
        !           703: /* }}} end xsl_xsltprocessor_transform_to_uri */
        !           704: 
        !           705: /* {{{ proto string xsl_xsltprocessor_transform_to_xml(domdocument doc);
        !           706: */
        !           707: PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
        !           708: {
        !           709:        zval *id, *docp = NULL;
        !           710:        xmlDoc *newdocp;
        !           711:        xsltStylesheetPtr sheetp;
        !           712:        int ret;
        !           713:        xmlChar *doc_txt_ptr;
        !           714:        int doc_txt_len;
        !           715:        xsl_object *intern;
        !           716:        
        !           717:        id = getThis();
        !           718:        intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           719:        sheetp = (xsltStylesheetPtr) intern->ptr;
        !           720: 
        !           721:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
        !           722:                RETURN_FALSE;
        !           723:        }
        !           724: 
        !           725:        newdocp = php_xsl_apply_stylesheet(id, intern, sheetp, docp TSRMLS_CC);
        !           726: 
        !           727:        ret = -1;
        !           728:        if (newdocp) {
        !           729:                ret = xsltSaveResultToString(&doc_txt_ptr, &doc_txt_len, newdocp, sheetp);
        !           730:                if (doc_txt_ptr && doc_txt_len) {
        !           731:                        RETVAL_STRINGL(doc_txt_ptr, doc_txt_len, 1);
        !           732:                        xmlFree(doc_txt_ptr);
        !           733:                }
        !           734:                xmlFreeDoc(newdocp);
        !           735:        }
        !           736: 
        !           737:        if (ret < 0) {
        !           738:                RETURN_FALSE;
        !           739:        }
        !           740: }
        !           741: /* }}} end xsl_xsltprocessor_transform_to_xml */
        !           742: 
        !           743: /* {{{ proto bool xsl_xsltprocessor_set_parameter(string namespace, mixed name [, string value]);
        !           744: */
        !           745: PHP_FUNCTION(xsl_xsltprocessor_set_parameter)
        !           746: {
        !           747:  
        !           748:        zval *id;
        !           749:        zval *array_value, **entry, *new_string;
        !           750:        xsl_object *intern;
        !           751:        char *string_key, *name, *value, *namespace;
        !           752:        ulong idx;
        !           753:        int string_key_len, namespace_len, name_len, value_len;
        !           754:        DOM_GET_THIS(id);
        !           755: 
        !           756:        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "sa", &namespace, &namespace_len, &array_value) == SUCCESS) {
        !           757:                intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           758:                zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value));
        !           759: 
        !           760:                while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) {
        !           761:                        SEPARATE_ZVAL(entry);
        !           762:                        convert_to_string_ex(entry);
        !           763:                        
        !           764:                        if (zend_hash_get_current_key_ex(Z_ARRVAL_P(array_value), &string_key, &string_key_len, &idx, 0, NULL) != HASH_KEY_IS_STRING) {
        !           765:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter array");
        !           766:                                RETURN_FALSE;
        !           767:                        }
        !           768:                        
        !           769:                        ALLOC_ZVAL(new_string);
        !           770:                        Z_ADDREF_PP(entry);
        !           771:                        COPY_PZVAL_TO_ZVAL(*new_string, *entry);
        !           772:                        
        !           773:                        zend_hash_update(intern->parameter, string_key, string_key_len, &new_string, sizeof(zval*), NULL);
        !           774:                        zend_hash_move_forward(Z_ARRVAL_P(array_value));
        !           775:                }
        !           776:                RETURN_TRUE;
        !           777: 
        !           778:        } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "sss", &namespace, &namespace_len, &name, &name_len, &value, &value_len) == SUCCESS) {
        !           779:                
        !           780:                intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           781:                
        !           782:                MAKE_STD_ZVAL(new_string);
        !           783:                ZVAL_STRING(new_string, value, 1);
        !           784:                
        !           785:                zend_hash_update(intern->parameter, name, name_len + 1, &new_string, sizeof(zval*), NULL);
        !           786:                RETURN_TRUE;
        !           787:        } else {
        !           788:                WRONG_PARAM_COUNT;
        !           789:        }
        !           790:        
        !           791: }
        !           792: /* }}} end xsl_xsltprocessor_set_parameter */
        !           793: 
        !           794: /* {{{ proto string xsl_xsltprocessor_get_parameter(string namespace, string name);
        !           795: */
        !           796: PHP_FUNCTION(xsl_xsltprocessor_get_parameter)
        !           797: {
        !           798:        zval *id;
        !           799:        int name_len = 0, namespace_len = 0;
        !           800:        char *name, *namespace;
        !           801:        zval **value;
        !           802:        xsl_object *intern;
        !           803: 
        !           804:        DOM_GET_THIS(id);
        !           805:        
        !           806:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &namespace, &namespace_len, &name, &name_len) == FAILURE) {
        !           807:                RETURN_FALSE;
        !           808:        }
        !           809:        intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           810:        if ( zend_hash_find(intern->parameter, name, name_len + 1,  (void**) &value) == SUCCESS) {
        !           811:                convert_to_string_ex(value);
        !           812:                RETVAL_STRING(Z_STRVAL_PP(value),1);
        !           813:        } else {
        !           814:                RETURN_FALSE;
        !           815:        }
        !           816: }
        !           817: /* }}} end xsl_xsltprocessor_get_parameter */
        !           818: 
        !           819: /* {{{ proto bool xsl_xsltprocessor_remove_parameter(string namespace, string name);
        !           820: */
        !           821: PHP_FUNCTION(xsl_xsltprocessor_remove_parameter)
        !           822: {
        !           823:        zval *id;
        !           824:        int name_len = 0, namespace_len = 0;
        !           825:        char *name, *namespace;
        !           826:        xsl_object *intern;
        !           827: 
        !           828:        DOM_GET_THIS(id);
        !           829:        
        !           830:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &namespace, &namespace_len, &name, &name_len) == FAILURE) {
        !           831:                RETURN_FALSE;
        !           832:        }
        !           833:        intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           834:        if ( zend_hash_del(intern->parameter, name, name_len + 1) == SUCCESS) {
        !           835:                RETURN_TRUE;
        !           836:        } else {
        !           837:                RETURN_FALSE;
        !           838:        }
        !           839: }
        !           840: /* }}} end xsl_xsltprocessor_remove_parameter */
        !           841: 
        !           842: /* {{{ proto void xsl_xsltprocessor_register_php_functions([mixed $restrict]);
        !           843: */
        !           844: PHP_FUNCTION(xsl_xsltprocessor_register_php_functions)
        !           845: {
        !           846:        zval *id;
        !           847:        xsl_object *intern;
        !           848:        zval *array_value, **entry, *new_string;
        !           849:        int  name_len = 0;
        !           850:        char *name;
        !           851: 
        !           852:        DOM_GET_THIS(id);
        !           853:        
        !           854:        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "a",  &array_value) == SUCCESS) {
        !           855:                intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           856:                zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value));
        !           857: 
        !           858:                while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) {
        !           859:                        SEPARATE_ZVAL(entry);
        !           860:                        convert_to_string_ex(entry);
        !           861:                        
        !           862:                        MAKE_STD_ZVAL(new_string);
        !           863:                        ZVAL_LONG(new_string,1);
        !           864:                
        !           865:                        zend_hash_update(intern->registered_phpfunctions, Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &new_string, sizeof(zval*), NULL);
        !           866:                        zend_hash_move_forward(Z_ARRVAL_P(array_value));
        !           867:                }
        !           868:                intern->registerPhpFunctions = 2;
        !           869: 
        !           870:        } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s",  &name, &name_len) == SUCCESS) {
        !           871:                intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           872:                
        !           873:                MAKE_STD_ZVAL(new_string);
        !           874:                ZVAL_LONG(new_string,1);
        !           875:                zend_hash_update(intern->registered_phpfunctions, name, name_len + 1, &new_string, sizeof(zval*), NULL);
        !           876:                intern->registerPhpFunctions = 2;
        !           877:                
        !           878:        } else {
        !           879:                intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           880:                intern->registerPhpFunctions = 1;
        !           881:        }
        !           882:        
        !           883: }
        !           884: /* }}} end xsl_xsltprocessor_register_php_functions(); */
        !           885: 
        !           886: /* {{{ proto bool xsl_xsltprocessor_set_profiling(string filename) */
        !           887: PHP_FUNCTION(xsl_xsltprocessor_set_profiling)
        !           888: {
        !           889:        zval *id;
        !           890:        xsl_object *intern;
        !           891:        char *filename = NULL;
        !           892:        int filename_len;
        !           893:        DOM_GET_THIS(id);
        !           894: 
        !           895:        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s!", &filename, &filename_len) == SUCCESS) {
        !           896:                intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           897:                if (intern->profiling) {
        !           898:                        efree(intern->profiling);
        !           899:                }
        !           900:                if (filename != NULL && strlen(filename) == filename_len) {
        !           901:                        intern->profiling = estrndup(filename,filename_len);
        !           902:                } else {
        !           903:                        intern->profiling = NULL;
        !           904:                }
        !           905:                RETURN_TRUE;
        !           906:        } else {
        !           907:                WRONG_PARAM_COUNT;
        !           908:        }
        !           909: }
        !           910: /* }}} end xsl_xsltprocessor_set_profiling */
        !           911: 
        !           912: /* {{{ proto bool xsl_xsltprocessor_has_exslt_support();
        !           913: */
        !           914: PHP_FUNCTION(xsl_xsltprocessor_has_exslt_support)
        !           915: {
        !           916: #if HAVE_XSL_EXSLT
        !           917:        RETURN_TRUE;
        !           918: #else
        !           919:        RETURN_FALSE;
        !           920: #endif
        !           921: }
        !           922: /* }}} end xsl_xsltprocessor_has_exslt_support(); */
        !           923: 
        !           924: /*
        !           925:  * Local variables:
        !           926:  * tab-width: 4
        !           927:  * c-basic-offset: 4
        !           928:  * End:
        !           929:  * vim600: sw=4 ts=4 fdm=marker
        !           930:  * vim<600: sw=4 ts=4
        !           931:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>