Annotation of embedaddon/php/ext/dom/xpath.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: 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, ®ister_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>