Annotation of embedaddon/php/ext/dom/xpath.c, revision 1.1.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: xpath.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: #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: {
                     77:        zval **args;
                     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:                                                        }
                    167:                                                        child = php_dom_create_object(node, &ret, NULL, child, (dom_object *)intern TSRMLS_CC);
                    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:                        }
                    219:                /* retval is == NULL, when an exception occured, don't report anything, because PHP itself will handle that */
                    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;
                    324: 
                    325:        ctx = (xmlXPathContextPtr) obj->ptr;
                    326: 
                    327:        if (ctx) {
                    328:                docp = (xmlDocPtr) ctx->doc;
                    329:        }
                    330: 
                    331:        ALLOC_ZVAL(*retval);
                    332:        if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, NULL, *retval, obj TSRMLS_CC))) {
                    333:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
                    334:                return FAILURE;
                    335:        }
                    336:        return SUCCESS;
                    337: }
                    338: /* }}} */
                    339: 
                    340: /* {{{ proto boolean dom_xpath_register_ns(string prefix, string uri); */
                    341: PHP_FUNCTION(dom_xpath_register_ns)
                    342: {
                    343:        zval *id;
                    344:        xmlXPathContextPtr ctxp;
                    345:        int prefix_len, ns_uri_len;
                    346:        dom_xpath_object *intern;
                    347:        unsigned char *prefix, *ns_uri;
                    348: 
                    349:        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) {
                    350:                return;
                    351:        }
                    352: 
                    353:        intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
                    354: 
                    355:        ctxp = (xmlXPathContextPtr) intern->ptr;
                    356:        if (ctxp == NULL) {
                    357:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Context");
                    358:                RETURN_FALSE;
                    359:        }
                    360: 
                    361:        if (xmlXPathRegisterNs(ctxp, prefix, ns_uri) != 0) {
                    362:                RETURN_FALSE
                    363:        }
                    364:        RETURN_TRUE;
                    365: }
                    366: /* }}} */
                    367: 
                    368: static void dom_xpath_iter(zval *baseobj, dom_object *intern) /* {{{ */
                    369: {
                    370:        dom_nnodemap_object *mapptr;
                    371: 
                    372:        mapptr = (dom_nnodemap_object *)intern->ptr;
                    373:        mapptr->baseobjptr = baseobj;
                    374:        mapptr->nodetype = DOM_NODESET;
                    375: 
                    376: }
                    377: /* }}} */
                    378: 
                    379: static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
                    380: {
                    381:        zval *id, *retval, *context = NULL;
                    382:        xmlXPathContextPtr ctxp;
                    383:        xmlNodePtr nodep = NULL;
                    384:        xmlXPathObjectPtr xpathobjp;
                    385:        int expr_len, ret, nsnbr = 0, xpath_type;
                    386:        dom_xpath_object *intern;
                    387:        dom_object *nodeobj;
                    388:        char *expr;
                    389:        xmlDoc *docp = NULL;
                    390:        xmlNsPtr *ns = NULL;
                    391:        zend_bool register_node_ns = 1;
                    392: 
                    393:        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) {
                    394:                return;
                    395:        }
                    396: 
                    397:        intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
                    398: 
                    399:        ctxp = (xmlXPathContextPtr) intern->ptr;
                    400:        if (ctxp == NULL) {
                    401:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Context");
                    402:                RETURN_FALSE;
                    403:        }
                    404: 
                    405:        docp = (xmlDocPtr) ctxp->doc;
                    406:        if (docp == NULL) {
                    407:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Document Pointer");
                    408:                RETURN_FALSE;
                    409:        }
                    410: 
                    411:        if (context != NULL) {
                    412:                DOM_GET_OBJ(nodep, context, xmlNodePtr, nodeobj);
                    413:        }
                    414: 
                    415:        if (!nodep) {
                    416:                nodep = xmlDocGetRootElement(docp);
                    417:        }
                    418: 
                    419:        if (nodep && docp != nodep->doc) {
                    420:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node From Wrong Document");
                    421:                RETURN_FALSE;
                    422:        }
                    423: 
                    424:        ctxp->node = nodep;
                    425: 
                    426:        if (register_node_ns) {
                    427:                /* Register namespaces in the node */
                    428:                ns = xmlGetNsList(docp, nodep);
                    429: 
                    430:                if (ns != NULL) {
                    431:                        while (ns[nsnbr] != NULL)
                    432:                        nsnbr++;
                    433:                }
                    434:        }
                    435: 
                    436: 
                    437:     ctxp->namespaces = ns;
                    438:     ctxp->nsNr = nsnbr;
                    439: 
                    440:        xpathobjp = xmlXPathEvalExpression(expr, ctxp);
                    441:        ctxp->node = NULL;
                    442: 
                    443:        if (ns != NULL) {
                    444:                xmlFree(ns);
                    445:                ctxp->namespaces = NULL;
                    446:                ctxp->nsNr = 0;
                    447:        }
                    448: 
                    449:        if (! xpathobjp) {
                    450:                RETURN_FALSE;
                    451:        }
                    452: 
                    453:        if (type == PHP_DOM_XPATH_QUERY) {
                    454:                xpath_type = XPATH_NODESET;
                    455:        } else {
                    456:                xpath_type = xpathobjp->type;
                    457:        }
                    458: 
                    459:        switch (xpath_type) {
                    460: 
                    461:                case  XPATH_NODESET:
                    462:                {
                    463:                        int i;
                    464:                        xmlNodeSetPtr nodesetp;
                    465: 
                    466:                        MAKE_STD_ZVAL(retval);
                    467:                        array_init(retval);
                    468: 
                    469:                        if (xpathobjp->type == XPATH_NODESET && NULL != (nodesetp = xpathobjp->nodesetval)) {
                    470: 
                    471:                                for (i = 0; i < nodesetp->nodeNr; i++) {
                    472:                                        xmlNodePtr node = nodesetp->nodeTab[i];
                    473:                                        zval *child;
                    474: 
                    475:                                        MAKE_STD_ZVAL(child);
                    476:                                        
                    477:                                        if (node->type == XML_NAMESPACE_DECL) {
                    478:                                                xmlNsPtr curns;
                    479:                                                xmlNodePtr nsparent;
                    480: 
                    481:                                                nsparent = node->_private;
                    482:                                                curns = xmlNewNs(NULL, node->name, NULL);
                    483:                                                if (node->children) {
                    484:                                                        curns->prefix = xmlStrdup((char *) node->children);
                    485:                                                }
                    486:                                                if (node->children) {
                    487:                                                        node = xmlNewDocNode(docp, NULL, (char *) node->children, node->name);
                    488:                                                } else {
                    489:                                                        node = xmlNewDocNode(docp, NULL, "xmlns", node->name);
                    490:                                                }
                    491:                                                node->type = XML_NAMESPACE_DECL;
                    492:                                                node->parent = nsparent;
                    493:                                                node->ns = curns;
                    494:                                        }
                    495:                                        child = php_dom_create_object(node, &ret, NULL, child, (dom_object *)intern TSRMLS_CC);
                    496:                                        add_next_index_zval(retval, child);
                    497:                                }
                    498:                        }
                    499:                        php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
                    500:                        nodeobj = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
                    501:                        dom_xpath_iter(retval, nodeobj);
                    502:                        break;
                    503:                }
                    504: 
                    505:                case XPATH_BOOLEAN:
                    506:                        RETVAL_BOOL(xpathobjp->boolval);
                    507:                        break;
                    508: 
                    509:                case XPATH_NUMBER:
                    510:                        RETVAL_DOUBLE(xpathobjp->floatval)
                    511:                        break;
                    512: 
                    513:                case XPATH_STRING:
                    514:                        RETVAL_STRING(xpathobjp->stringval, 1);
                    515:                        break;
                    516: 
                    517:                default:
                    518:                        RETVAL_NULL();
                    519:                        break;
                    520:        }
                    521: 
                    522:        xmlXPathFreeObject(xpathobjp);
                    523: }
                    524: /* }}} */
                    525: 
                    526: /* {{{ proto DOMNodeList dom_xpath_query(string expr [,DOMNode context [, boolean registerNodeNS]]); */
                    527: PHP_FUNCTION(dom_xpath_query)
                    528: {
                    529:        php_xpath_eval(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_DOM_XPATH_QUERY);
                    530: }
                    531: /* }}} end dom_xpath_query */
                    532: 
                    533: /* {{{ proto mixed dom_xpath_evaluate(string expr [,DOMNode context [, boolean registerNodeNS]]); */
                    534: PHP_FUNCTION(dom_xpath_evaluate)
                    535: {
                    536:        php_xpath_eval(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_DOM_XPATH_EVALUATE);
                    537: }
                    538: /* }}} end dom_xpath_evaluate */
                    539: 
                    540: /* {{{ proto void dom_xpath_register_php_functions() */
                    541: PHP_FUNCTION(dom_xpath_register_php_functions)
                    542: {
                    543:        zval *id;
                    544:        dom_xpath_object *intern;
                    545:        zval *array_value, **entry, *new_string;
                    546:        int  name_len = 0;
                    547:        char *name;
                    548: 
                    549:        DOM_GET_THIS(id);
                    550:        
                    551:        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "a",  &array_value) == SUCCESS) {
                    552:                intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
                    553:                zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value));
                    554: 
                    555:                while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) {
                    556:                        SEPARATE_ZVAL(entry);
                    557:                        convert_to_string_ex(entry);
                    558: 
                    559:                        MAKE_STD_ZVAL(new_string);
                    560:                        ZVAL_LONG(new_string,1);
                    561:                
                    562:                        zend_hash_update(intern->registered_phpfunctions, Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &new_string, sizeof(zval*), NULL);
                    563:                        zend_hash_move_forward(Z_ARRVAL_P(array_value));
                    564:                }
                    565:                intern->registerPhpFunctions = 2;
                    566:                RETURN_TRUE;
                    567: 
                    568:        } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s",  &name, &name_len) == SUCCESS) {
                    569:                intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
                    570:                
                    571:                MAKE_STD_ZVAL(new_string);
                    572:                ZVAL_LONG(new_string,1);
                    573:                zend_hash_update(intern->registered_phpfunctions, name, name_len + 1, &new_string, sizeof(zval*), NULL);
                    574:                intern->registerPhpFunctions = 2;
                    575:                
                    576:        } else {
                    577:                intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
                    578:                intern->registerPhpFunctions = 1;
                    579:        }
                    580:        
                    581: }
                    582: /* }}} end dom_xpath_register_php_functions */
                    583: 
                    584: #endif /* LIBXML_XPATH_ENABLED */
                    585: 
                    586: #endif
                    587: 
                    588: /*
                    589:  * Local variables:
                    590:  * tab-width: 4
                    591:  * c-basic-offset: 4
                    592:  * End:
                    593:  * vim600: noet sw=4 ts=4 fdm=marker
                    594:  * vim<600: noet sw=4 ts=4
                    595:  */

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