File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / dom / xpath.c
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:03:42 2014 UTC (10 years, 10 months ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

    1: /*
    2:    +----------------------------------------------------------------------+
    3:    | PHP Version 5                                                        |
    4:    +----------------------------------------------------------------------+
    5:    | Copyright (c) 1997-2014 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,v 1.1.1.5 2014/06/15 20:03:42 misho Exp $ */
   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 = NULL;
   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, 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 occurred, 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: 	zval *tmp;
  325: 
  326: 	ctx = (xmlXPathContextPtr) obj->ptr;
  327: 
  328: 	if (ctx) {
  329: 		docp = (xmlDocPtr) ctx->doc;
  330: 	}
  331: 
  332: 	ALLOC_ZVAL(*retval);
  333: 	tmp = *retval;
  334: 
  335: 	if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, *retval, obj TSRMLS_CC))) {
  336: 		FREE_ZVAL(tmp);
  337: 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
  338: 		return FAILURE;
  339: 	}
  340: 	if (tmp != *retval) {
  341: 		FREE_ZVAL(tmp);
  342: 	}
  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: 					}
  502: 					child = php_dom_create_object(node, &ret, child, (dom_object *)intern TSRMLS_CC);
  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>