Annotation of embedaddon/php/ext/dom/xpath.c, revision 1.1.1.5

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.5 ! misho       5:    | Copyright (c) 1997-2014 The PHP Group                                |
1.1       misho       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: 
1.1.1.2   misho      20: /* $Id$ */
1.1       misho      21: 
                     22: #ifdef HAVE_CONFIG_H
                     23: #include "config.h"
                     24: #endif
                     25: 
                     26: #include "php.h"
                     27: #if HAVE_LIBXML && HAVE_DOM
                     28: #include "php_dom.h"
                     29: 
                     30: #define PHP_DOM_XPATH_QUERY 0
                     31: #define PHP_DOM_XPATH_EVALUATE 1
                     32: 
                     33: /*
                     34: * class DOMXPath 
                     35: */
                     36: 
                     37: #if defined(LIBXML_XPATH_ENABLED)
                     38: 
                     39: /* {{{ arginfo */
                     40: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_construct, 0, 0, 1)
                     41:        ZEND_ARG_OBJ_INFO(0, doc, DOMDocument, 0)
                     42: ZEND_END_ARG_INFO();
                     43: 
                     44: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_register_ns, 0, 0, 2)
                     45:        ZEND_ARG_INFO(0, prefix)
                     46:        ZEND_ARG_INFO(0, uri)
                     47: ZEND_END_ARG_INFO();
                     48: 
                     49: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_query, 0, 0, 1)
                     50:        ZEND_ARG_INFO(0, expr)
                     51:        ZEND_ARG_OBJ_INFO(0, context, DOMNode, 1)
                     52:        ZEND_ARG_INFO(0, registerNodeNS)
                     53: ZEND_END_ARG_INFO();
                     54: 
                     55: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_evaluate, 0, 0, 1)
                     56:        ZEND_ARG_INFO(0, expr)
                     57:        ZEND_ARG_OBJ_INFO(0, context, DOMNode, 1)
                     58:        ZEND_ARG_INFO(0, registerNodeNS)
                     59: ZEND_END_ARG_INFO();
                     60: 
                     61: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_register_php_functions, 0, 0, 0)
                     62: ZEND_END_ARG_INFO();
                     63: /* }}} */
                     64: 
                     65: const zend_function_entry php_dom_xpath_class_functions[] = {
                     66:        PHP_ME(domxpath, __construct, arginfo_dom_xpath_construct, ZEND_ACC_PUBLIC)
                     67:        PHP_FALIAS(registerNamespace, dom_xpath_register_ns, arginfo_dom_xpath_register_ns)
                     68:        PHP_FALIAS(query, dom_xpath_query, arginfo_dom_xpath_query)
                     69:        PHP_FALIAS(evaluate, dom_xpath_evaluate, arginfo_dom_xpath_evaluate)
                     70:        PHP_FALIAS(registerPhpFunctions, dom_xpath_register_php_functions, arginfo_dom_xpath_register_php_functions)
                     71:        PHP_FE_END
                     72: };
                     73: 
                     74: 
                     75: static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */
                     76: {
1.1.1.4   misho      77:        zval **args = NULL;
1.1       misho      78:        zval *retval;
                     79:        int result, i, ret;
                     80:        int error = 0;
                     81:        zend_fcall_info fci;
                     82:        zval handler;
                     83:        xmlXPathObjectPtr obj;
                     84:        char *str;
                     85:        char *callable = NULL;
                     86:        dom_xpath_object *intern;
                     87:        
                     88:        TSRMLS_FETCH();
                     89: 
                     90:        if (! zend_is_executing(TSRMLS_C)) {
                     91:                xmlGenericError(xmlGenericErrorContext,
                     92:                "xmlExtFunctionTest: Function called from outside of PHP\n");
                     93:                error = 1;
                     94:        } else {
                     95:                intern = (dom_xpath_object *) ctxt->context->userData;
                     96:                if (intern == NULL) {
                     97:                        xmlGenericError(xmlGenericErrorContext,
                     98:                        "xmlExtFunctionTest: failed to get the internal object\n");
                     99:                        error = 1;
                    100:                }
                    101:                else if (intern->registerPhpFunctions == 0) {
                    102:                        xmlGenericError(xmlGenericErrorContext,
                    103:                        "xmlExtFunctionTest: PHP Object did not register PHP functions\n");
                    104:                        error = 1;
                    105:                }
                    106:        }
                    107:        
                    108:        if (error == 1) {
                    109:                for (i = nargs - 1; i >= 0; i--) {
                    110:                        obj = valuePop(ctxt);
                    111:                        xmlXPathFreeObject(obj);
                    112:                }
                    113:                return;
                    114:        }
                    115:                
                    116:        fci.param_count = nargs - 1;
                    117:        if (fci.param_count > 0) {
                    118:                fci.params = safe_emalloc(fci.param_count, sizeof(zval**), 0);
                    119:                args = safe_emalloc(fci.param_count, sizeof(zval *), 0);
                    120:        }
                    121:        /* Reverse order to pop values off ctxt stack */
                    122:        for (i = nargs - 2; i >= 0; i--) {
                    123:                obj = valuePop(ctxt);
                    124:                MAKE_STD_ZVAL(args[i]);
                    125:                switch (obj->type) {
                    126:                        case XPATH_STRING:
                    127:                                ZVAL_STRING(args[i],  (char *)obj->stringval, 1);
                    128:                                break;
                    129:                        case XPATH_BOOLEAN:
                    130:                                ZVAL_BOOL(args[i],  obj->boolval);
                    131:                                break;
                    132:                        case XPATH_NUMBER:
                    133:                                ZVAL_DOUBLE(args[i], obj->floatval);
                    134:                                break;
                    135:                        case XPATH_NODESET:
                    136:                                if (type == 1) {
                    137:                                        str = (char *)xmlXPathCastToString(obj);
                    138:                                        ZVAL_STRING(args[i], str, 1);
                    139:                                        xmlFree(str);
                    140:                                } else if (type == 2) {
                    141:                                        int j;
                    142:                                        array_init(args[i]);
                    143:                                        if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
                    144:                                                for (j = 0; j < obj->nodesetval->nodeNr; j++) {
                    145:                                                        xmlNodePtr node = obj->nodesetval->nodeTab[j];
                    146:                                                        zval *child;
                    147:                                                        MAKE_STD_ZVAL(child);
                    148:                                                        /* not sure, if we need this... it's copied from xpath.c */
                    149:                                                        if (node->type == XML_NAMESPACE_DECL) {
                    150:                                                                xmlNsPtr curns;
                    151:                                                                xmlNodePtr nsparent;
                    152:                                                                
                    153:                                                                nsparent = node->_private;
                    154:                                                                curns = xmlNewNs(NULL, node->name, NULL);
                    155:                                                                if (node->children) {
                    156:                                                                        curns->prefix = xmlStrdup((xmlChar *) node->children);
                    157:                                                                }
                    158:                                                                if (node->children) {
                    159:                                                                        node = xmlNewDocNode(node->doc, NULL, (xmlChar *) node->children, node->name);
                    160:                                                                } else {
                    161:                                                                        node = xmlNewDocNode(node->doc, NULL, (xmlChar *) "xmlns", node->name);
                    162:                                                                }
                    163:                                                                node->type = XML_NAMESPACE_DECL;
                    164:                                                                node->parent = nsparent;
                    165:                                                                node->ns = curns;
                    166:                                                        }
1.1.1.2   misho     167:                                                        child = php_dom_create_object(node, &ret, child, (dom_object *)intern TSRMLS_CC);
1.1       misho     168:                                                        add_next_index_zval(args[i], child);
                    169:                                                }
                    170:                                        }
                    171:                                }
                    172:                                break;
                    173:                        default:
                    174:                        ZVAL_STRING(args[i], (char *)xmlXPathCastToString(obj), 1);
                    175:                }
                    176:                xmlXPathFreeObject(obj);
                    177:                fci.params[i] = &args[i];
                    178:        }
                    179:        
                    180:        fci.size = sizeof(fci);
                    181:        fci.function_table = EG(function_table);
                    182:        
                    183:        obj = valuePop(ctxt);
                    184:        if (obj->stringval == NULL) {
                    185:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Handler name must be a string");
                    186:                xmlXPathFreeObject(obj);
                    187:                if (fci.param_count > 0) {
                    188:                        for (i = 0; i < nargs - 1; i++) {
                    189:                                zval_ptr_dtor(&args[i]);
                    190:                        }
                    191:                        efree(args);
                    192:                        efree(fci.params);
                    193:                }
                    194:                return; 
                    195:        }
                    196:        INIT_PZVAL(&handler);
                    197:        ZVAL_STRING(&handler, obj->stringval, 1);
                    198:        xmlXPathFreeObject(obj);
                    199: 
                    200:        fci.function_name = &handler;
                    201:        fci.symbol_table = NULL;
                    202:        fci.object_ptr = NULL;
                    203:        fci.retval_ptr_ptr = &retval;
                    204:        fci.no_separation = 0;
                    205: 
                    206:        if (!zend_make_callable(&handler, &callable TSRMLS_CC)) {
                    207:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", callable);
                    208:                
                    209:        } else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable, strlen(callable) + 1) == 0) { 
                    210:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not allowed to call handler '%s()'.", callable);
                    211:                /* Push an empty string, so that we at least have an xslt result... */
                    212:                valuePush(ctxt, xmlXPathNewString((xmlChar *)""));
                    213:        } else {
                    214:                result = zend_call_function(&fci, NULL TSRMLS_CC);
                    215:                if (result == FAILURE) {
                    216:                        if (Z_TYPE(handler) == IS_STRING) {
                    217:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", Z_STRVAL_P(&handler));
                    218:                        }
1.1.1.3   misho     219:                /* retval is == NULL, when an exception occurred, don't report anything, because PHP itself will handle that */
1.1       misho     220:                } else if (retval == NULL) {
                    221:                } else {
                    222:                        if (retval->type == IS_OBJECT && instanceof_function( Z_OBJCE_P(retval), dom_node_class_entry TSRMLS_CC)) {
                    223:                                xmlNode *nodep;
                    224:                                dom_object *obj;
                    225:                                if (intern->node_list == NULL) {
                    226:                                        ALLOC_HASHTABLE(intern->node_list);
                    227:                                        zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
                    228:                                }
                    229:                                zval_add_ref(&retval);
                    230:                                zend_hash_next_index_insert(intern->node_list, &retval, sizeof(zval *), NULL);
                    231:                                obj = (dom_object *)zend_object_store_get_object(retval TSRMLS_CC);
                    232:                                nodep = dom_object_get_node(obj);
                    233:                                valuePush(ctxt, xmlXPathNewNodeSet(nodep));
                    234:                        } else if (retval->type == IS_BOOL) {
                    235:                                valuePush(ctxt, xmlXPathNewBoolean(retval->value.lval));
                    236:                        } else if (retval->type == IS_OBJECT) {
                    237:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "A PHP Object cannot be converted to a XPath-string");
                    238:                                valuePush(ctxt, xmlXPathNewString((xmlChar *)""));
                    239:                        } else {
                    240:                                convert_to_string_ex(&retval);
                    241:                                valuePush(ctxt, xmlXPathNewString( Z_STRVAL_P(retval)));
                    242:                        }
                    243:                        zval_ptr_dtor(&retval);
                    244:                }
                    245:        }
                    246:        efree(callable);
                    247:        zval_dtor(&handler);
                    248:        if (fci.param_count > 0) {
                    249:                for (i = 0; i < nargs - 1; i++) {
                    250:                        zval_ptr_dtor(&args[i]);
                    251:                }
                    252:                efree(args);
                    253:                efree(fci.params);
                    254:        }
                    255: }
                    256: /* }}} */
                    257: 
                    258: static void dom_xpath_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */
                    259: {
                    260:        dom_xpath_ext_function_php(ctxt, nargs, 1);
                    261: }
                    262: /* }}} */
                    263: 
                    264: static void dom_xpath_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */
                    265: {
                    266:        dom_xpath_ext_function_php(ctxt, nargs, 2);
                    267: }
                    268: /* }}} */
                    269: 
                    270: /* {{{ proto void DOMXPath::__construct(DOMDocument doc) U */
                    271: PHP_METHOD(domxpath, __construct)
                    272: {
                    273:        zval *id, *doc;
                    274:        xmlDocPtr docp = NULL;
                    275:        dom_object *docobj;
                    276:        dom_xpath_object *intern;
                    277:        xmlXPathContextPtr ctx, oldctx;
                    278:        zend_error_handling error_handling;
                    279: 
                    280:        zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
                    281:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_xpath_class_entry, &doc, dom_document_class_entry) == FAILURE) {
                    282:                zend_restore_error_handling(&error_handling TSRMLS_CC);
                    283:                return;
                    284:        }
                    285: 
                    286:        zend_restore_error_handling(&error_handling TSRMLS_CC);
                    287:        DOM_GET_OBJ(docp, doc, xmlDocPtr, docobj);
                    288: 
                    289:        ctx = xmlXPathNewContext(docp);
                    290:        if (ctx == NULL) {
                    291:                php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
                    292:                RETURN_FALSE;
                    293:        }
                    294: 
                    295:        intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
                    296:        if (intern != NULL) {
                    297:                oldctx = (xmlXPathContextPtr)intern->ptr;
                    298:                if (oldctx != NULL) {
                    299:                        php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
                    300:                        xmlXPathFreeContext(oldctx);
                    301:                }
                    302: 
                    303:                xmlXPathRegisterFuncNS (ctx, (const xmlChar *) "functionString",
                    304:                                           (const xmlChar *) "http://php.net/xpath",
                    305:                                           dom_xpath_ext_function_string_php);
                    306:                xmlXPathRegisterFuncNS (ctx, (const xmlChar *) "function",
                    307:                                           (const xmlChar *) "http://php.net/xpath",
                    308:                                           dom_xpath_ext_function_object_php);
                    309: 
                    310:                intern->ptr = ctx;
                    311:                ctx->userData = (void *)intern;
                    312:                intern->document = docobj->document;
                    313:                php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp TSRMLS_CC);
                    314:        }
                    315: }
                    316: /* }}} end DOMXPath::__construct */
                    317: 
                    318: /* {{{ document DOMDocument*/
                    319: int dom_xpath_document_read(dom_object *obj, zval **retval TSRMLS_DC)
                    320: {
                    321:        xmlDoc *docp = NULL;
                    322:        xmlXPathContextPtr ctx;
                    323:        int ret;
1.1.1.3   misho     324:        zval *tmp;
1.1       misho     325: 
                    326:        ctx = (xmlXPathContextPtr) obj->ptr;
                    327: 
                    328:        if (ctx) {
                    329:                docp = (xmlDocPtr) ctx->doc;
                    330:        }
                    331: 
                    332:        ALLOC_ZVAL(*retval);
1.1.1.3   misho     333:        tmp = *retval;
                    334: 
1.1.1.2   misho     335:        if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, *retval, obj TSRMLS_CC))) {
1.1.1.3   misho     336:                FREE_ZVAL(tmp);
1.1       misho     337:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
                    338:                return FAILURE;
                    339:        }
1.1.1.3   misho     340:        if (tmp != *retval) {
                    341:                FREE_ZVAL(tmp);
                    342:        }
1.1       misho     343:        return SUCCESS;
                    344: }
                    345: /* }}} */
                    346: 
                    347: /* {{{ proto boolean dom_xpath_register_ns(string prefix, string uri); */
                    348: PHP_FUNCTION(dom_xpath_register_ns)
                    349: {
                    350:        zval *id;
                    351:        xmlXPathContextPtr ctxp;
                    352:        int prefix_len, ns_uri_len;
                    353:        dom_xpath_object *intern;
                    354:        unsigned char *prefix, *ns_uri;
                    355: 
                    356:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_xpath_class_entry, &prefix, &prefix_len, &ns_uri, &ns_uri_len) == FAILURE) {
                    357:                return;
                    358:        }
                    359: 
                    360:        intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
                    361: 
                    362:        ctxp = (xmlXPathContextPtr) intern->ptr;
                    363:        if (ctxp == NULL) {
                    364:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Context");
                    365:                RETURN_FALSE;
                    366:        }
                    367: 
                    368:        if (xmlXPathRegisterNs(ctxp, prefix, ns_uri) != 0) {
                    369:                RETURN_FALSE
                    370:        }
                    371:        RETURN_TRUE;
                    372: }
                    373: /* }}} */
                    374: 
                    375: static void dom_xpath_iter(zval *baseobj, dom_object *intern) /* {{{ */
                    376: {
                    377:        dom_nnodemap_object *mapptr;
                    378: 
                    379:        mapptr = (dom_nnodemap_object *)intern->ptr;
                    380:        mapptr->baseobjptr = baseobj;
                    381:        mapptr->nodetype = DOM_NODESET;
                    382: 
                    383: }
                    384: /* }}} */
                    385: 
                    386: static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
                    387: {
                    388:        zval *id, *retval, *context = NULL;
                    389:        xmlXPathContextPtr ctxp;
                    390:        xmlNodePtr nodep = NULL;
                    391:        xmlXPathObjectPtr xpathobjp;
                    392:        int expr_len, ret, nsnbr = 0, xpath_type;
                    393:        dom_xpath_object *intern;
                    394:        dom_object *nodeobj;
                    395:        char *expr;
                    396:        xmlDoc *docp = NULL;
                    397:        xmlNsPtr *ns = NULL;
                    398:        zend_bool register_node_ns = 1;
                    399: 
                    400:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|O!b", &id, dom_xpath_class_entry, &expr, &expr_len, &context, dom_node_class_entry, &register_node_ns) == FAILURE) {
                    401:                return;
                    402:        }
                    403: 
                    404:        intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
                    405: 
                    406:        ctxp = (xmlXPathContextPtr) intern->ptr;
                    407:        if (ctxp == NULL) {
                    408:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Context");
                    409:                RETURN_FALSE;
                    410:        }
                    411: 
                    412:        docp = (xmlDocPtr) ctxp->doc;
                    413:        if (docp == NULL) {
                    414:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Document Pointer");
                    415:                RETURN_FALSE;
                    416:        }
                    417: 
                    418:        if (context != NULL) {
                    419:                DOM_GET_OBJ(nodep, context, xmlNodePtr, nodeobj);
                    420:        }
                    421: 
                    422:        if (!nodep) {
                    423:                nodep = xmlDocGetRootElement(docp);
                    424:        }
                    425: 
                    426:        if (nodep && docp != nodep->doc) {
                    427:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node From Wrong Document");
                    428:                RETURN_FALSE;
                    429:        }
                    430: 
                    431:        ctxp->node = nodep;
                    432: 
                    433:        if (register_node_ns) {
                    434:                /* Register namespaces in the node */
                    435:                ns = xmlGetNsList(docp, nodep);
                    436: 
                    437:                if (ns != NULL) {
                    438:                        while (ns[nsnbr] != NULL)
                    439:                        nsnbr++;
                    440:                }
                    441:        }
                    442: 
                    443: 
                    444:     ctxp->namespaces = ns;
                    445:     ctxp->nsNr = nsnbr;
                    446: 
                    447:        xpathobjp = xmlXPathEvalExpression(expr, ctxp);
                    448:        ctxp->node = NULL;
                    449: 
                    450:        if (ns != NULL) {
                    451:                xmlFree(ns);
                    452:                ctxp->namespaces = NULL;
                    453:                ctxp->nsNr = 0;
                    454:        }
                    455: 
                    456:        if (! xpathobjp) {
                    457:                RETURN_FALSE;
                    458:        }
                    459: 
                    460:        if (type == PHP_DOM_XPATH_QUERY) {
                    461:                xpath_type = XPATH_NODESET;
                    462:        } else {
                    463:                xpath_type = xpathobjp->type;
                    464:        }
                    465: 
                    466:        switch (xpath_type) {
                    467: 
                    468:                case  XPATH_NODESET:
                    469:                {
                    470:                        int i;
                    471:                        xmlNodeSetPtr nodesetp;
                    472: 
                    473:                        MAKE_STD_ZVAL(retval);
                    474:                        array_init(retval);
                    475: 
                    476:                        if (xpathobjp->type == XPATH_NODESET && NULL != (nodesetp = xpathobjp->nodesetval)) {
                    477: 
                    478:                                for (i = 0; i < nodesetp->nodeNr; i++) {
                    479:                                        xmlNodePtr node = nodesetp->nodeTab[i];
                    480:                                        zval *child;
                    481: 
                    482:                                        MAKE_STD_ZVAL(child);
                    483:                                        
                    484:                                        if (node->type == XML_NAMESPACE_DECL) {
                    485:                                                xmlNsPtr curns;
                    486:                                                xmlNodePtr nsparent;
                    487: 
                    488:                                                nsparent = node->_private;
                    489:                                                curns = xmlNewNs(NULL, node->name, NULL);
                    490:                                                if (node->children) {
                    491:                                                        curns->prefix = xmlStrdup((char *) node->children);
                    492:                                                }
                    493:                                                if (node->children) {
                    494:                                                        node = xmlNewDocNode(docp, NULL, (char *) node->children, node->name);
                    495:                                                } else {
                    496:                                                        node = xmlNewDocNode(docp, NULL, "xmlns", node->name);
                    497:                                                }
                    498:                                                node->type = XML_NAMESPACE_DECL;
                    499:                                                node->parent = nsparent;
                    500:                                                node->ns = curns;
                    501:                                        }
1.1.1.2   misho     502:                                        child = php_dom_create_object(node, &ret, child, (dom_object *)intern TSRMLS_CC);
1.1       misho     503:                                        add_next_index_zval(retval, child);
                    504:                                }
                    505:                        }
                    506:                        php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
                    507:                        nodeobj = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
                    508:                        dom_xpath_iter(retval, nodeobj);
                    509:                        break;
                    510:                }
                    511: 
                    512:                case XPATH_BOOLEAN:
                    513:                        RETVAL_BOOL(xpathobjp->boolval);
                    514:                        break;
                    515: 
                    516:                case XPATH_NUMBER:
                    517:                        RETVAL_DOUBLE(xpathobjp->floatval)
                    518:                        break;
                    519: 
                    520:                case XPATH_STRING:
                    521:                        RETVAL_STRING(xpathobjp->stringval, 1);
                    522:                        break;
                    523: 
                    524:                default:
                    525:                        RETVAL_NULL();
                    526:                        break;
                    527:        }
                    528: 
                    529:        xmlXPathFreeObject(xpathobjp);
                    530: }
                    531: /* }}} */
                    532: 
                    533: /* {{{ proto DOMNodeList dom_xpath_query(string expr [,DOMNode context [, boolean registerNodeNS]]); */
                    534: PHP_FUNCTION(dom_xpath_query)
                    535: {
                    536:        php_xpath_eval(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_DOM_XPATH_QUERY);
                    537: }
                    538: /* }}} end dom_xpath_query */
                    539: 
                    540: /* {{{ proto mixed dom_xpath_evaluate(string expr [,DOMNode context [, boolean registerNodeNS]]); */
                    541: PHP_FUNCTION(dom_xpath_evaluate)
                    542: {
                    543:        php_xpath_eval(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_DOM_XPATH_EVALUATE);
                    544: }
                    545: /* }}} end dom_xpath_evaluate */
                    546: 
                    547: /* {{{ proto void dom_xpath_register_php_functions() */
                    548: PHP_FUNCTION(dom_xpath_register_php_functions)
                    549: {
                    550:        zval *id;
                    551:        dom_xpath_object *intern;
                    552:        zval *array_value, **entry, *new_string;
                    553:        int  name_len = 0;
                    554:        char *name;
                    555: 
                    556:        DOM_GET_THIS(id);
                    557:        
                    558:        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "a",  &array_value) == SUCCESS) {
                    559:                intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
                    560:                zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value));
                    561: 
                    562:                while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) {
                    563:                        SEPARATE_ZVAL(entry);
                    564:                        convert_to_string_ex(entry);
                    565: 
                    566:                        MAKE_STD_ZVAL(new_string);
                    567:                        ZVAL_LONG(new_string,1);
                    568:                
                    569:                        zend_hash_update(intern->registered_phpfunctions, Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &new_string, sizeof(zval*), NULL);
                    570:                        zend_hash_move_forward(Z_ARRVAL_P(array_value));
                    571:                }
                    572:                intern->registerPhpFunctions = 2;
                    573:                RETURN_TRUE;
                    574: 
                    575:        } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s",  &name, &name_len) == SUCCESS) {
                    576:                intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
                    577:                
                    578:                MAKE_STD_ZVAL(new_string);
                    579:                ZVAL_LONG(new_string,1);
                    580:                zend_hash_update(intern->registered_phpfunctions, name, name_len + 1, &new_string, sizeof(zval*), NULL);
                    581:                intern->registerPhpFunctions = 2;
                    582:                
                    583:        } else {
                    584:                intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
                    585:                intern->registerPhpFunctions = 1;
                    586:        }
                    587:        
                    588: }
                    589: /* }}} end dom_xpath_register_php_functions */
                    590: 
                    591: #endif /* LIBXML_XPATH_ENABLED */
                    592: 
                    593: #endif
                    594: 
                    595: /*
                    596:  * Local variables:
                    597:  * tab-width: 4
                    598:  * c-basic-offset: 4
                    599:  * End:
                    600:  * vim600: noet sw=4 ts=4 fdm=marker
                    601:  * vim<600: noet sw=4 ts=4
                    602:  */

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