Exemplo n.º 1
0
/**
 * exsltStrReturnString:
 * @ctxt: an XPath parser context
 * @str: a string
 * @len: length of string
 *
 * Returns a string as a node set.
 */
static int
exsltStrReturnString(xmlXPathParserContextPtr ctxt, const xmlChar *str,
                     int len)
{
    xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt);
    xmlDocPtr container;
    xmlNodePtr text_node;
    xmlXPathObjectPtr ret;

    container = xsltCreateRVT(tctxt);
    if (container == NULL) {
        xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
        return(-1);
    }
    xsltRegisterLocalRVT(tctxt, container);

    text_node = xmlNewTextLen(str, len);
    if (text_node == NULL) {
        xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
        return(-1);
    }
    xmlAddChild((xmlNodePtr) container, text_node);

    ret = xmlXPathNewNodeSet(text_node);
    if (ret == NULL) {
        xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
        return(-1);
    }

    xsltExtensionInstructionResultRegister(tctxt, ret);
    valuePush(ctxt, ret);

    return(0);
}
Exemplo n.º 2
0
static void
exsltNodeSetFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    if (nargs != 1) {
	xmlXPathSetArityError(ctxt);
	return;
    }
    if (xmlXPathStackIsNodeSet (ctxt)) {
	xsltFunctionNodeSet (ctxt, nargs);
	return;
    } else {
	xmlDocPtr fragment;
	xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt);
	xmlNodePtr txt;
	xmlChar *strval;
	xmlXPathObjectPtr obj;
	/*
	* SPEC EXSLT:
	* "You can also use this function to turn a string into a text
	* node, which is helpful if you want to pass a string to a
	* function that only accepts a node-set."
	*/
	fragment = xsltCreateRVT(tctxt);
	if (fragment == NULL) {
	    xsltTransformError(tctxt, NULL, tctxt->inst,
		"exsltNodeSetFunction: Failed to create a tree fragment.\n");
	    tctxt->state = XSLT_STATE_STOPPED; 
	    return;
	}
	xsltRegisterLocalRVT(tctxt, fragment);

	strval = xmlXPathPopString (ctxt);
	
	txt = xmlNewDocText (fragment, strval);
	xmlAddChild((xmlNodePtr) fragment, txt);
	obj = xmlXPathNewNodeSet(txt);	
	if (obj == NULL) {
	    xsltTransformError(tctxt, NULL, tctxt->inst,
		"exsltNodeSetFunction: Failed to create a node set object.\n");
	    tctxt->state = XSLT_STATE_STOPPED;
	} else {
	    /*
	     * Mark it as a function result in order to avoid garbage
	     * collecting of tree fragments
	     */
	    xsltExtensionInstructionResultRegister(tctxt, obj);
	}
	if (strval != NULL)
	    xmlFree (strval);
	
	valuePush (ctxt, obj);
    }
}
Exemplo n.º 3
0
static void
xslt_yelp_input (xmlXPathParserContextPtr ctxt, int nargs)
{
    xsltTransformContextPtr tctxt;
    xmlXPathObjectPtr ret;
    YelpTransform *transform;

    tctxt = xsltXPathGetTransformContext (ctxt);
    transform = (YelpTransform *) tctxt->_private;

    /* FIXME: pretty sure this eats transform->input, memory corruption will follow */
    transform->input_xslt = xsltNewDocument (tctxt, transform->input);

    ret = xmlXPathNewNodeSet (xmlDocGetRootElement (transform->input));
    xsltExtensionInstructionResultRegister (tctxt, ret);
    valuePush (ctxt, ret);
}
Exemplo n.º 4
0
static void
xslt_yelp_aux (xmlXPathParserContextPtr ctxt, int nargs)
{
    xsltTransformContextPtr tctxt;
    xmlXPathObjectPtr ret;
    YelpTransform *transform;
    YelpTransformPrivate *priv;

    tctxt = xsltXPathGetTransformContext (ctxt);
    transform = YELP_TRANSFORM (tctxt->_private);
    priv = GET_PRIV (transform);

    priv->aux_xslt = xsltNewDocument (tctxt, priv->aux);

    ret = xmlXPathNewNodeSet (xmlDocGetRootElement (priv->aux));
    xsltExtensionInstructionResultRegister (tctxt, ret);
    valuePush (ctxt, ret);
}
Exemplo n.º 5
0
/**
 * exsltStrTokenizeFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * Splits up a string on the characters of the delimiter string and returns a
 * node set of token elements, each containing one token from the string.
 */
static void
exsltStrTokenizeFunction(xmlXPathParserContextPtr ctxt, int nargs)
{
    xsltTransformContextPtr tctxt;
    xmlChar *str, *delimiters, *cur;
    const xmlChar *token, *delimiter;
    xmlNodePtr node;
    xmlDocPtr container;
    xmlXPathObjectPtr ret = NULL;
    int clen;

    if ((nargs < 1) || (nargs > 2)) {
        xmlXPathSetArityError(ctxt);
        return;
    }

    if (nargs == 2) {
        delimiters = xmlXPathPopString(ctxt);
        if (xmlXPathCheckError(ctxt))
            return;
    } else {
        delimiters = xmlStrdup((const xmlChar *) "\t\r\n ");
    }
    if (delimiters == NULL)
        return;

    str = xmlXPathPopString(ctxt);
    if (xmlXPathCheckError(ctxt) || (str == NULL)) {
        xmlFree(delimiters);
        return;
    }

    /* Return a result tree fragment */
    tctxt = xsltXPathGetTransformContext(ctxt);
    if (tctxt == NULL) {
        xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
	      "exslt:tokenize : internal error tctxt == NULL\n");
	goto fail;
    }

    container = xsltCreateRVT(tctxt);
    if (container != NULL) {
        xsltRegisterLocalRVT(tctxt, container);
        ret = xmlXPathNewNodeSet(NULL);
        if (ret != NULL) {
            for (cur = str, token = str; *cur != 0; cur += clen) {
	        clen = xmlUTF8Size(cur);
		if (*delimiters == 0) {	/* empty string case */
		    xmlChar ctmp;
		    ctmp = *(cur+clen);
		    *(cur+clen) = 0;
                    node = xmlNewDocRawNode(container, NULL,
                                       (const xmlChar *) "token", cur);
		    xmlAddChild((xmlNodePtr) container, node);
		    xmlXPathNodeSetAddUnique(ret->nodesetval, node);
                    *(cur+clen) = ctmp; /* restore the changed byte */
                    token = cur + clen;
                } else for (delimiter = delimiters; *delimiter != 0;
				delimiter += xmlUTF8Size(delimiter)) {
                    if (!xmlUTF8Charcmp(cur, delimiter)) {
                        if (cur == token) {
                            /* discard empty tokens */
                            token = cur + clen;
                            break;
                        }
                        *cur = 0;	/* terminate the token */
                        node = xmlNewDocRawNode(container, NULL,
                                           (const xmlChar *) "token", token);
			xmlAddChild((xmlNodePtr) container, node);
			xmlXPathNodeSetAddUnique(ret->nodesetval, node);
                        *cur = *delimiter; /* restore the changed byte */
                        token = cur + clen;
                        break;
                    }
                }
            }
            if (token != cur) {
		node = xmlNewDocRawNode(container, NULL,
				    (const xmlChar *) "token", token);
                xmlAddChild((xmlNodePtr) container, node);
	        xmlXPathNodeSetAddUnique(ret->nodesetval, node);
            }
	    /*
	     * Mark it as a function result in order to avoid garbage
	     * collecting of tree fragments
	     */
	    xsltExtensionInstructionResultRegister(tctxt, ret);
        }
    }

fail:
    if (str != NULL)
        xmlFree(str);
    if (delimiters != NULL)
        xmlFree(delimiters);
    if (ret != NULL)
        valuePush(ctxt, ret);
    else
        valuePush(ctxt, xmlXPathNewNodeSet(NULL));
}
Exemplo n.º 6
0
/**
 * exsltStrSplitFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * Splits up a string on a delimiting string and returns a node set of token
 * elements, each containing one token from the string.
 */
static void
exsltStrSplitFunction(xmlXPathParserContextPtr ctxt, int nargs) {
    xsltTransformContextPtr tctxt;
    xmlChar *str, *delimiter, *cur;
    const xmlChar *token;
    xmlNodePtr node;
    xmlDocPtr container;
    xmlXPathObjectPtr ret = NULL;
    int delimiterLength;

    if ((nargs < 1) || (nargs > 2)) {
        xmlXPathSetArityError(ctxt);
        return;
    }

    if (nargs == 2) {
        delimiter = xmlXPathPopString(ctxt);
        if (xmlXPathCheckError(ctxt))
            return;
    } else {
        delimiter = xmlStrdup((const xmlChar *) " ");
    }
    if (delimiter == NULL)
        return;
    delimiterLength = xmlStrlen (delimiter);

    str = xmlXPathPopString(ctxt);
    if (xmlXPathCheckError(ctxt) || (str == NULL)) {
        xmlFree(delimiter);
        return;
    }

    /* Return a result tree fragment */
    tctxt = xsltXPathGetTransformContext(ctxt);
    if (tctxt == NULL) {
        xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
	      "exslt:tokenize : internal error tctxt == NULL\n");
	goto fail;
    }

    /*
    * OPTIMIZE TODO: We are creating an xmlDoc for every split!
    */
    container = xsltCreateRVT(tctxt);
    if (container != NULL) {
        xsltRegisterLocalRVT(tctxt, container);
        ret = xmlXPathNewNodeSet(NULL);
        if (ret != NULL) {
            for (cur = str, token = str; *cur != 0; cur++) {
		if (delimiterLength == 0) {
		    if (cur != token) {
			xmlChar tmp = *cur;
			*cur = 0;
                        node = xmlNewDocRawNode(container, NULL,
                                           (const xmlChar *) "token", token);
			xmlAddChild((xmlNodePtr) container, node);
			xmlXPathNodeSetAddUnique(ret->nodesetval, node);
			*cur = tmp;
			token++;
		    }
		}
		else if (!xmlStrncasecmp(cur, delimiter, delimiterLength)) {
		    if (cur == token) {
			/* discard empty tokens */
			cur = cur + delimiterLength - 1;
			token = cur + 1;
			continue;
		    }
		    *cur = 0;
		    node = xmlNewDocRawNode(container, NULL,
				       (const xmlChar *) "token", token);
		    xmlAddChild((xmlNodePtr) container, node);
		    xmlXPathNodeSetAddUnique(ret->nodesetval, node);
		    *cur = *delimiter;
		    cur = cur + delimiterLength - 1;
		    token = cur + 1;
                }
            }
	    if (token != cur) {
		node = xmlNewDocRawNode(container, NULL,
				   (const xmlChar *) "token", token);
		xmlAddChild((xmlNodePtr) container, node);
		xmlXPathNodeSetAddUnique(ret->nodesetval, node);
	    }
	    /*
	     * Mark it as a function result in order to avoid garbage
	     * collecting of tree fragments
	     */
	    xsltExtensionInstructionResultRegister(tctxt, ret);
        }
    }

fail:
    if (str != NULL)
        xmlFree(str);
    if (delimiter != NULL)
        xmlFree(delimiter);
    if (ret != NULL)
        valuePush(ctxt, ret);
    else
        valuePush(ctxt, xmlXPathNewNodeSet(NULL));
}
Exemplo n.º 7
0
static void
exsltDynMapFunction(xmlXPathParserContextPtr ctxt, int nargs)
{
    xmlChar *str = NULL;
    xmlNodeSetPtr nodeset = NULL;
    xsltTransformContextPtr tctxt;
    xmlXPathCompExprPtr comp = NULL;
    xmlXPathObjectPtr ret = NULL;
    xmlDocPtr oldDoc, container = NULL;
    xmlNodePtr oldNode;
    int oldContextSize;
    int oldProximityPosition;
    int i, j;


    if (nargs != 2) {
        xmlXPathSetArityError(ctxt);
        return;
    }
    str = xmlXPathPopString(ctxt);
    if (xmlXPathCheckError(ctxt)) {
        xmlXPathSetTypeError(ctxt);
        return;
    }

    nodeset = xmlXPathPopNodeSet(ctxt);
    if (xmlXPathCheckError(ctxt)) {
        xmlXPathSetTypeError(ctxt);
        return;
    }
    if (str == NULL || !xmlStrlen(str) || !(comp = xmlXPathCompile(str))) {
        if (nodeset != NULL)
            xmlXPathFreeNodeSet(nodeset);
        if (str != NULL)
            xmlFree(str);
        valuePush(ctxt, xmlXPathNewNodeSet(NULL));
        return;
    }

    ret = xmlXPathNewNodeSet(NULL);
    if (ret == NULL) {
        xsltGenericError(xsltGenericErrorContext,
                         "exsltDynMapFunction: ret == NULL\n");
        goto cleanup;
    }

    oldDoc = ctxt->context->doc;
    oldNode = ctxt->context->node;
    oldContextSize = ctxt->context->contextSize;
    oldProximityPosition = ctxt->context->proximityPosition;

    tctxt = xsltXPathGetTransformContext(ctxt);
    if (tctxt == NULL) {
	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
	      "dyn:map : internal error tctxt == NULL\n");
	goto cleanup;
    }
    container = xsltCreateRVT(tctxt);
    if (container == NULL) {
	xsltTransformError(tctxt, NULL, NULL,
	      "dyn:map : internal error container == NULL\n");
	goto cleanup;
    }
    xsltRegisterLocalRVT(tctxt, container);
    if (nodeset && nodeset->nodeNr > 0) {
        xmlXPathNodeSetSort(nodeset);
        ctxt->context->contextSize = nodeset->nodeNr;
        ctxt->context->proximityPosition = 0;
        for (i = 0; i < nodeset->nodeNr; i++) {
            xmlXPathObjectPtr subResult = NULL;

            ctxt->context->proximityPosition++;
            ctxt->context->node = nodeset->nodeTab[i];
            ctxt->context->doc = nodeset->nodeTab[i]->doc;

            subResult = xmlXPathCompiledEval(comp, ctxt->context);
            if (subResult != NULL) {
                switch (subResult->type) {
                    case XPATH_NODESET:
                        if (subResult->nodesetval != NULL)
                            for (j = 0; j < subResult->nodesetval->nodeNr;
                                 j++)
                                xmlXPathNodeSetAdd(ret->nodesetval,
                                                   subResult->nodesetval->
                                                   nodeTab[j]);
                        break;
                    case XPATH_BOOLEAN:
                        if (container != NULL) {
                            xmlNodePtr cur =
                                xmlNewChild((xmlNodePtr) container, NULL,
                                            BAD_CAST "boolean",
                                            BAD_CAST (subResult->
                                            boolval ? "true" : ""));
                            if (cur != NULL) {
                                cur->ns =
                                    xmlNewNs(cur,
                                             BAD_CAST
                                             "http://exslt.org/common",
                                             BAD_CAST "exsl");
                                xmlXPathNodeSetAddUnique(ret->nodesetval,
                                                         cur);
                            }
			    xsltExtensionInstructionResultRegister(tctxt, ret);
                        }
                        break;
                    case XPATH_NUMBER:
                        if (container != NULL) {
                            xmlChar *val =
                                xmlXPathCastNumberToString(subResult->
                                                           floatval);
                            xmlNodePtr cur =
                                xmlNewChild((xmlNodePtr) container, NULL,
                                            BAD_CAST "number", val);
                            if (val != NULL)
                                xmlFree(val);

                            if (cur != NULL) {
                                cur->ns =
                                    xmlNewNs(cur,
                                             BAD_CAST
                                             "http://exslt.org/common",
                                             BAD_CAST "exsl");
                                xmlXPathNodeSetAddUnique(ret->nodesetval,
                                                         cur);
                            }
			    xsltExtensionInstructionResultRegister(tctxt, ret);
                        }
                        break;
                    case XPATH_STRING:
                        if (container != NULL) {
                            xmlNodePtr cur =
                                xmlNewChild((xmlNodePtr) container, NULL,
                                            BAD_CAST "string",
                                            subResult->stringval);
                            if (cur != NULL) {
                                cur->ns =
                                    xmlNewNs(cur,
                                             BAD_CAST
                                             "http://exslt.org/common",
                                             BAD_CAST "exsl");
                                xmlXPathNodeSetAddUnique(ret->nodesetval,
                                                         cur);
                            }
			    xsltExtensionInstructionResultRegister(tctxt, ret);
                        }
                        break;
		    default:
                        break;
                }
                xmlXPathFreeObject(subResult);
            }
        }
    }
    ctxt->context->doc = oldDoc;
    ctxt->context->node = oldNode;
    ctxt->context->contextSize = oldContextSize;
    ctxt->context->proximityPosition = oldProximityPosition;


  cleanup:
    
    if (comp != NULL)
        xmlXPathFreeCompExpr(comp);
    if (nodeset != NULL)
        xmlXPathFreeNodeSet(nodeset);
    if (str != NULL)
        xmlFree(str);
    valuePush(ctxt, ret);
    return;
}