Return to xpath.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / dom |
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: */