Beispiel #1
0
static void
extBitCompare (xmlXPathParserContextPtr ctxt, int nargs)
{
    xmlChar *res1, *res2;
    xmlXPathObjectPtr xop;
    int width1, width2, off1, off2, rc, delta;

    if (nargs != 2) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    /* Pop args in reverse order */
    xop = valuePop(ctxt);
    if (xop == NULL || xmlXPathCheckError(ctxt))
	return;
    res2 = extBitStringVal(ctxt, xop);
    if (res2 == NULL)
	return;

    xop = valuePop(ctxt);
    if (xop == NULL || xmlXPathCheckError(ctxt))
	return;
    res1 = extBitStringVal(ctxt, xop);
    if (res1 == NULL)
	return;

    width1 = xmlStrlen(res1);
    width2 = xmlStrlen(res2);
    delta = width1 - width2;

    rc = 0;
    off1 = off2 = 0;
    if (delta < 0) {
	for ( ; delta < 0; delta++, off2++) {
	    if (res2[off2] != '0') {
		rc = -1;
		goto done;
	    }
	}

    } else if (delta > 0) {
	for ( ; delta > 0; delta--, off1++) {
	    if (res1[off1] != '0') {
		rc = 1;
		goto done;
	    }
	}
    }

    rc = xmlStrcmp(res1 + off1, res2 + off2);

 done:
    xmlFree(res1);
    xmlFree(res2);

    xmlXPathReturnNumber(ctxt, rc);
}
Beispiel #2
0
/**
 * xsltFormatNumberFunction:
 * @ctxt:  the XPath Parser context
 * @nargs:  the number of arguments
 *
 * Implement the format-number() XSLT function
 *   string format-number(number, string, string?)
 */
void
xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs)
{
    xmlXPathObjectPtr numberObj = NULL;
    xmlXPathObjectPtr formatObj = NULL;
    xmlXPathObjectPtr decimalObj = NULL;
    xsltStylesheetPtr sheet;
    xsltDecimalFormatPtr formatValues;
    xmlChar *result;
    xsltTransformContextPtr tctxt;

    tctxt = xsltXPathGetTransformContext(ctxt);
    if (tctxt == NULL)
	return;
    sheet = tctxt->style;
    if (sheet == NULL)
	return;
    formatValues = sheet->decimalFormat;

    switch (nargs) {
    case 3:
	CAST_TO_STRING;
	decimalObj = valuePop(ctxt);
	formatValues = xsltDecimalFormatGetByName(sheet, decimalObj->stringval);
	if (formatValues == NULL) {
	    xsltTransformError(tctxt, NULL, NULL,
		    "format-number() : undeclared decimal format '%s'\n",
		    decimalObj->stringval);
	}
	/* Intentional fall-through */
    case 2:
	CAST_TO_STRING;
	formatObj = valuePop(ctxt);
	CAST_TO_NUMBER;
	numberObj = valuePop(ctxt);
	break;
    default:
	XP_ERROR(XPATH_INVALID_ARITY);
    }

    if (formatValues != NULL) {
	if (xsltFormatNumberConversion(formatValues,
				       formatObj->stringval,
				       numberObj->floatval,
				       &result) == XPATH_EXPRESSION_OK) {
	    valuePush(ctxt, xmlXPathNewString(result));
	    xmlFree(result);
	}
    }

    xmlXPathFreeObject(numberObj);
    xmlXPathFreeObject(formatObj);
    xmlXPathFreeObject(decimalObj);
}
Beispiel #3
0
static void
gda_xslt_getnodeset_function (xmlXPathParserContextPtr ctxt, int nargs)
{
	GdaXsltIntCont *data;
	xsltTransformContextPtr tctxt;
	xmlXPathObjectPtr setname, nodeset;
	GdaXsltExCont *execc;
	if (nargs != 1) {
		xsltGenericError (xsltGenericErrorContext,
				  "gda_xslt_getnodeset_function: invalid number of arguments\n");
		return;
	}
	tctxt = xsltXPathGetTransformContext (ctxt);
	if (tctxt == NULL) {
		xsltGenericError (xsltGenericErrorContext,
				  "sqlxslt: failed to get the transformation context\n");
		return;
	}
	execc = (GdaXsltExCont *) tctxt->_private;
	data = (GdaXsltIntCont *) xsltGetExtData (tctxt,
						  BAD_CAST GDA_XSLT_EXTENSION_URI);
	if (data == NULL) {
		xsltGenericError (xsltGenericErrorContext,
				  "sqlxslt: failed to get module data\n");
		return;
	}
	setname = valuePop (ctxt);
	if (setname == NULL) {
		xsltGenericError (xsltGenericErrorContext,
				  "sqlxslt: internal error\n");
		return;
	}

	if (setname->type != XPATH_STRING) {
		valuePush (ctxt, setname);
		xmlXPathStringFunction (ctxt, 1);
		setname = valuePop (ctxt);
		if (setname == NULL) {
			xsltGenericError (xsltGenericErrorContext,
					  "sqlxslt: internal error\n");
			return;
		}
	}
	nodeset =
		_gda_xslt_bk_fun_getnodeset (setname->stringval, execc, data);
	if (nodeset == NULL) {
		xsltGenericError (xsltGenericErrorContext,
				  "exsltDynMapFunctoin: ret == NULL\n");
		return;
	}
	valuePush (ctxt, nodeset);
}
Beispiel #4
0
void
RXSLT_callNamedFunction(const char *name, xmlXPathParserContextPtr ctxt, int nargs, int leaveAsRObject)
{
  USER_OBJECT_ e, ans;
//  xmlXPathObjectPtr obj;
  int errorOccurred;
  int i, j;

#if 0
  PROTECT(e = allocVector(LANGSXP, 2));
  SETCAR(e, Rf_install((char *) name));
  SETCAR(CDR(e), tmp = NEW_CHARACTER(1));
  obj = valuePop(ctxt); 
  SET_STRING_ELT(tmp, 0, COPY_TO_USER_STRING(xmlXPathCastToString(obj)));
#else
  PROTECT(e = allocVector(LANGSXP, nargs+1));
  SETCAR(e, Rf_install((char *) name));

#if 0
  for(i = 0; i < nargs; i++) {
    ans = CDR(e);
    for(j = nargs-1; j > i ; j--) {
      ans = CDR(ans);
    }
    SETCAR(ans, tmp = NEW_CHARACTER(1));
    obj = valuePop(ctxt); 
    SET_STRING_ELT(tmp, 0, COPY_TO_USER_STRING(xmlXPathCastToString(obj)));
  }
#else
  for(i = 0; i < nargs; i++) {
    ans = CDR(e);
    for(j = nargs-1; j > i ; j--) {
      ans = CDR(ans);
    }
   SETCAR(ans, convertFromXPath(ctxt, valuePop(ctxt)));
  }

#endif
#endif  
  ans = R_tryEval(e, R_GlobalEnv, &errorOccurred);
  if(errorOccurred) {
      RXSLT_Error(ctxt, "error in call to R function"); 
  } else {
     PROTECT(ans);
     valuePush(ctxt, convertToXPath(ctxt, ans));
     UNPROTECT(1);
  }

  UNPROTECT(1);
  return;
}
Beispiel #5
0
static void
extBitOperation (xmlXPathParserContextPtr ctxt, int nargs,
		 slax_bit_callback_t func, const char *name)
{
    xmlChar *lv, *rv, *res;
    int llen, rlen, width, i;
    xmlXPathObjectPtr xop;

    if (nargs != 2) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    /* Pop args in reverse order */
    xop = valuePop(ctxt);
    if (xop == NULL || xmlXPathCheckError(ctxt))
	return;
    rv = extBitStringVal(ctxt, xop);
    if (rv == NULL)
	return;

    xop = valuePop(ctxt);
    if (xop == NULL || xmlXPathCheckError(ctxt))
	return;
    lv = extBitStringVal(ctxt, xop);
    if (lv == NULL) {
	xmlFree(rv);
	return;
    }

    llen = xmlStrlen(lv);
    rlen = xmlStrlen(rv);
    width = (llen > rlen) ? llen : rlen;

    res = xmlMalloc(width + 1);
    if (res) {
	res[width] = '\0';
	for (i = 0; i < width; i++) {
	    xmlChar lb = (i >= width - llen) ? lv[i - (width - llen)] : '0';
	    xmlChar rb = (i >= width - rlen) ? rv[i - (width - rlen)] : '0';
	    res[i] = (*func)(lb, rb);
	}
    }

    slaxLog("bit:%s:: %d [%s] -> [%s] == [%s]", name, width, lv, rv, res);

    xmlFree(lv);
    xmlFree(rv);

    xmlXPathReturnString(ctxt, res);
}
Beispiel #6
0
/**
 * xsltUnparsedEntityURIFunction:
 * @ctxt:  the XPath Parser context
 * @nargs:  the number of arguments
 *
 * Implement the unparsed-entity-uri() XSLT function
 *   string unparsed-entity-uri(string)
 */
void
xsltUnparsedEntityURIFunction(xmlXPathParserContextPtr ctxt, int nargs){
    xmlXPathObjectPtr obj;
    xmlChar *str;

    if ((nargs != 1) || (ctxt->value == NULL)) {
        xsltGenericError(xsltGenericErrorContext,
		"unparsed-entity-uri() : expects one string arg\n");
	ctxt->error = XPATH_INVALID_ARITY;
	return;
    }
    obj = valuePop(ctxt);
    if (obj->type != XPATH_STRING) {
	obj = xmlXPathConvertString(obj);
    }

    str = obj->stringval;
    if (str == NULL) {
	valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
    } else {
	xmlEntityPtr entity;

	entity = xmlGetDocEntity(ctxt->context->doc, str);
	if (entity == NULL) {
	    valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
	} else {
	    if (entity->URI != NULL)
		valuePush(ctxt, xmlXPathNewString(entity->URI));
	    else
		valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
	}
    }
    xmlXPathFreeObject(obj);
}
Beispiel #7
0
static void
extBitNot (xmlXPathParserContextPtr ctxt, int nargs)
{
    xmlChar *res;
    int width, i;
    xmlXPathObjectPtr xop;

    if (nargs != 1) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    /* Pop args in reverse order */
    xop = valuePop(ctxt);
    if (xop == NULL || xmlXPathCheckError(ctxt))
	return;
    res = extBitStringVal(ctxt, xop);
    if (res == NULL)
	return;

    width = xmlStrlen(res);
    for (i = 0; i < width; i++) {
	xmlChar lb = res[i];
	res[i] = (lb == '0') ? '1' : '0';
    }

    xmlXPathReturnString(ctxt, res);
}
Beispiel #8
0
static void
extBitToInt (xmlXPathParserContextPtr ctxt, int nargs)
{
    xmlChar *res;
    xmlXPathObjectPtr xop;
    unsigned long long val;
    int i;

    if (nargs != 1) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    xop = valuePop(ctxt);
    if (xop == NULL || xmlXPathCheckError(ctxt))
	return;
    res = extBitStringVal(ctxt, xop);
    if (res == NULL)
	return;

    for (i = 0, val = 0; i <= 64 && res[i]; i++) {
	val <<= 1;
	if (res[i] == '1')
	    val += 1;
    }

    if (i > 64)
	xmlXPathReturnNumber(ctxt, (double) -1);
    else
	xmlXPathReturnNumber(ctxt, (double) val);
}
Beispiel #9
0
/**
 * xsltElementAvailableFunction:
 * @ctxt:  the XPath Parser context
 * @nargs:  the number of arguments
 *
 * Implement the element-available() XSLT function
 *   boolean element-available(string)
 */
void
xsltElementAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){
    xmlXPathObjectPtr obj;
    xmlChar *prefix, *name;
    const xmlChar *nsURI = NULL;
    xsltTransformContextPtr tctxt;

    if (nargs != 1) {
	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
		"element-available() : expects one string arg\n");
	ctxt->error = XPATH_INVALID_ARITY;
	return;
    }
    xmlXPathStringFunction(ctxt, 1);
    if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
	    "element-available() : invalid arg expecting a string\n");
	ctxt->error = XPATH_INVALID_TYPE;
	return;
    }
    obj = valuePop(ctxt);
    tctxt = xsltXPathGetTransformContext(ctxt);
    if (tctxt == NULL) {
	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
		"element-available() : internal error tctxt == NULL\n");
	xmlXPathFreeObject(obj);
	valuePush(ctxt, xmlXPathNewBoolean(0));
	return;
    }


    name = xmlSplitQName2(obj->stringval, &prefix);
    if (name == NULL) {
	xmlNsPtr ns;

	name = xmlStrdup(obj->stringval);
	ns = xmlSearchNs(tctxt->inst->doc, tctxt->inst, NULL);
	if (ns != NULL) nsURI = xmlStrdup(ns->href);
    } else {
	nsURI = xmlXPathNsLookup(ctxt->context, prefix);
	if (nsURI == NULL) {
	    xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
		"element-available() : prefix %s is not bound\n", prefix);
	}
    }

    if (xsltExtElementLookup(tctxt, name, nsURI) != NULL) {
	valuePush(ctxt, xmlXPathNewBoolean(1));
    } else {
	valuePush(ctxt, xmlXPathNewBoolean(0));
    }

    xmlXPathFreeObject(obj);
    if (name != NULL)
	xmlFree(name);
    if (prefix != NULL)
	xmlFree(prefix);
}
Beispiel #10
0
/**
 * @arg str the XPath expression
 * @arg ctxt the XPath context
 * @arg pctxt pointer to a XPath Parser context pointer
 *
 * Evaluate the XPath expression in the given context.  The XPath Parser
 * context is saved in pctxt, so that it can be accessed from another thread.
 * Especially the error state is interesting, since it can be used to stop a
 * never ending evaluation.
 *
 * Taken from xpath.c in libxml2-2.6.16.
 *
 * @return the xmlXPathObjectPtr resulting from the evaluation or NULL.
 *         The caller has to free the object.
 */
xmlXPathObjectPtr
my_xmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt, xmlXPathParserContextPtr *pctxt) {
    xmlXPathObjectPtr res, tmp;
    int stack = 0;

    xmlXPathInit();

    // it is nice that gcc gives no warning anymore,
    // but the bad thing is that *pctxt normally is still NULL at this point
    CHECK_CONTEXT(ctxt,*pctxt)

    g_mutex_lock(find_nodeset_pcontext_mutex);
    //g_printerr("Allocating parser context\n");
    *pctxt = xmlXPathNewParserContext(str, ctxt);
    g_mutex_unlock(find_nodeset_pcontext_mutex);

    xmlXPathEvalExpr(*pctxt);

    if (*(*pctxt)->cur != 0) {
        xmlXPatherror(*pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
        res = NULL;
    } else {
        res = valuePop(*pctxt);
    }
    do {
        tmp = valuePop(*pctxt);
        if (tmp != NULL) {
            xmlXPathFreeObject(tmp);
            stack++;
        }
    } while (tmp != NULL);
    if ((stack != 0) && (res != NULL)) {
        xmlGenericError(xmlGenericErrorContext,
                "xmlXPathEvalExpression: %d object left on the stack\n",
                stack);
    }

    g_mutex_lock(find_nodeset_pcontext_mutex);
    xmlXPathFreeParserContext(*pctxt);
    *pctxt = NULL;
    //g_printerr("Freed parser context\n");
    g_mutex_unlock(find_nodeset_pcontext_mutex);

    return(res);
}
Beispiel #11
0
void
RXSLT_source(xmlXPathParserContextPtr ctxt, int nargs)
{
   Rboolean ok;
   xmlXPathObjectPtr obj;

   obj = valuePop(ctxt); 
   ok = RXSLT_internalSource(xmlXPathCastToString(obj));
   valuePush(ctxt, xmlXPathNewBoolean(ok));
}
static void GDALGMLJP2XPathIf(xmlXPathParserContextPtr ctxt, int nargs)
{
    xmlXPathObjectPtr cond_val,then_val,else_val;

    CHECK_ARITY(3);
    else_val = valuePop(ctxt);
    then_val = valuePop(ctxt);
    CAST_TO_BOOLEAN
    cond_val = valuePop(ctxt);

    if( cond_val->boolval )
    {
        xmlXPathFreeObject(else_val);
        valuePush(ctxt, then_val);
    }
    else
    {
        xmlXPathFreeObject(then_val);
        valuePush(ctxt, else_val);
    }
    xmlXPathFreeObject(cond_val);
}
Beispiel #13
0
/**
 * xsltGenerateIdFunction:
 * @ctxt:  the XPath Parser context
 * @nargs:  the number of arguments
 *
 * Implement the generate-id() XSLT function
 *   string generate-id(node-set?)
 */
void
xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
    static char base_address;
    xmlNodePtr cur = NULL;
    xmlXPathObjectPtr obj = NULL;
    long val;
    xmlChar str[30];

    if (nargs == 0) {
	cur = ctxt->context->node;
    } else if (nargs == 1) {
	xmlNodeSetPtr nodelist;
	int i, ret;

	if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) {
	    ctxt->error = XPATH_INVALID_TYPE;
	    xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
		"generate-id() : invalid arg expecting a node-set\n");
	    return;
	}
	obj = valuePop(ctxt);
	nodelist = obj->nodesetval;
	if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) {
	    xmlXPathFreeObject(obj);
	    valuePush(ctxt, xmlXPathNewCString(""));
	    return;
	}
	cur = nodelist->nodeTab[0];
	for (i = 1;i < nodelist->nodeNr;i++) {
	    ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]);
	    if (ret == -1)
	        cur = nodelist->nodeTab[i];
	}
    } else {
	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
		"generate-id() : invalid number of args %d\n", nargs);
	ctxt->error = XPATH_INVALID_ARITY;
	return;
    }

    if (obj)
        xmlXPathFreeObject(obj);

    val = (long)((char *)cur - (char *)&base_address);
    if (val >= 0) {
      snprintf((char *)str, sizeof(str), "idp%ld", val);
    } else {
      snprintf((char *)str, sizeof(str), "idm%ld", -val);
    }
    valuePush(ctxt, xmlXPathNewString(str));
}
Beispiel #14
0
/**
 * xsltGenerateIdFunction:
 * @ctxt:  the XPath Parser context
 * @nargs:  the number of arguments
 *
 * Implement the generate-id() XSLT function
 *   string generate-id(node-set?)
 */
void
xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
    xmlNodePtr cur = NULL;
    unsigned long val;
    xmlChar str[20];

    if (nargs == 0) {
	cur = ctxt->context->node;
    } else if (nargs == 1) {
	xmlXPathObjectPtr obj;
	xmlNodeSetPtr nodelist;
	int i, ret;

	if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) {
	    ctxt->error = XPATH_INVALID_TYPE;
	    xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt),
				  NULL, NULL);
	    xsltGenericError(xsltGenericErrorContext,
		"generate-id() : invalid arg expecting a node-set\n");
	    return;
	}
	obj = valuePop(ctxt);
	nodelist = obj->nodesetval;
	if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) {
	    xmlXPathFreeObject(obj);
	    valuePush(ctxt, xmlXPathNewCString(""));
	    return;
	}
	cur = nodelist->nodeTab[0];
	for (i = 1;i < nodelist->nodeNr;i++) {
	    ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]);
	    if (ret == -1)
	        cur = nodelist->nodeTab[i];
	}
	xmlXPathFreeObject(obj);
    } else {
	xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL);
        xsltGenericError(xsltGenericErrorContext,
		"generate-id() : invalid number of args %d\n", nargs);
	ctxt->error = XPATH_INVALID_ARITY;
	return;
    }
    /*
     * Okay this is ugly but should work, use the NodePtr address
     * to forge the ID
     */
    val = (unsigned long)((char *)cur - (char *)0);
    val /= sizeof(xmlNode);
    sprintf((char *)str, "id%ld", val);
    valuePush(ctxt, xmlXPathNewString(str));
}
Beispiel #15
0
void
RXSLT_init(xmlXPathParserContextPtr ctxt, int nargs)
{
    const char *defaultArgs[] = {"Rxsltproc", "--silent"};
    char **args;
    int argc, i;
    int mustFree;

    if(R_alreadyInitialized)
      return;

#ifdef XSLT_DEBUG
    fprintf(stderr, "in RXSLT_init %d\n", nargs);fflush(stderr);
#endif
    if(nargs == 0) {
       argc = sizeof(defaultArgs)/sizeof(defaultArgs[0]);   
       args = (char **)defaultArgs;
    } else {
	args = (char **) malloc((nargs+1) * sizeof(char*));
        args[0] = strdup("Rxsltproc");
        argc = nargs+1;
        for(i = 0; i < nargs; i++) {
            xmlXPathObjectPtr obj = valuePop(ctxt); 
            if(obj->type) {
		args[i+1] = strdup(xmlXPathCastToString(obj));
	    }
	}
        mustFree = TRUE;
    }

    Rf_initEmbeddedR(argc, args);
    loadXSLPackage();
    valuePush(ctxt, xmlXPathNewBoolean(1));
    if(mustFree) {
        for(i = 0; i < nargs+1; i++) {
	    free(args[i]);
	}      
        free(args);
    }


#if DEBUG_REGISTRATION
 xsltRegisterExtFunction(getTransformCtxt(), "foo", R_URI, RXSLT_genericFunctionCall);
 RXSLT_addFunction("foo", NULL_USER_OBJECT);
#endif

    R_alreadyInitialized = 1;
    return;
}
Beispiel #16
0
/**
 * xsltFunctionAvailableFunction:
 * @ctxt:  the XPath Parser context
 * @nargs:  the number of arguments
 *
 * Implement the function-available() XSLT function
 *   boolean function-available(string)
 */
void
xsltFunctionAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){
    xmlXPathObjectPtr obj;
    xmlChar *prefix, *name;
    const xmlChar *nsURI = NULL;

    if (nargs != 1) {
	xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL);
        xsltGenericError(xsltGenericErrorContext,
		"function-available() : expects one string arg\n");
	ctxt->error = XPATH_INVALID_ARITY;
	return;
    }
    if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
	xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL);
	xsltGenericError(xsltGenericErrorContext,
	    "function-available() : invalid arg expecting a string\n");
	ctxt->error = XPATH_INVALID_TYPE;
	return;
    }
    obj = valuePop(ctxt);

    name = xmlSplitQName2(obj->stringval, &prefix);
    if (name == NULL) {
	name = xmlStrdup(obj->stringval);
    } else {
	nsURI = xmlXPathNsLookup(ctxt->context, prefix);
	if (nsURI == NULL) {
	    xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt),
				  NULL, NULL);
	    xsltGenericError(xsltGenericErrorContext,
		"function-available() : prefix %s is not bound\n", prefix);
	}
    }

    if (xmlXPathFunctionLookupNS(ctxt->context, name, nsURI) != NULL) {
	valuePush(ctxt, xmlXPathNewBoolean(1));
    } else {
	valuePush(ctxt, xmlXPathNewBoolean(0));
    }

    xmlXPathFreeObject(obj);
    if (name != NULL)
	xmlFree(name);
    if (prefix != NULL)
	xmlFree(prefix);
}
Beispiel #17
0
static void
extBitClearOrSet (xmlXPathParserContextPtr ctxt, int nargs, xmlChar value)
{
    xmlChar *res;
    int width, bitnum = 0, delta;
    xmlXPathObjectPtr xop;

    if (nargs != 1 && nargs != 2) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    /* Pop args in reverse order */
    if (nargs == 2) {
	bitnum = xmlXPathPopNumber(ctxt);
	if (bitnum < 0 || xmlXPathCheckError(ctxt))
	    return;
    }

    xop = valuePop(ctxt);
    if (xop == NULL || xmlXPathCheckError(ctxt))
	return;
    res = extBitStringVal(ctxt, xop);
    if (res == NULL)
	return;

    width = xmlStrlen(res);
    delta = width - bitnum - 1;

    if (delta < 0) {
	xmlChar *newp = xmlRealloc(res, bitnum + 2);
	if (newp == NULL)
	    return;

	delta = -delta;
	memmove(newp + delta, newp, width + 1);
	newp[0] = value;
	memset(newp + 1, '0', delta - 1);
	res = newp;

    } else {
	res[delta] = value;
    }

    xmlXPathReturnString(ctxt, res);
}
Beispiel #18
0
static void
extBitToHex (xmlXPathParserContextPtr ctxt, int nargs)
{
    xmlChar *res;
    xmlXPathObjectPtr xop;
    unsigned long long val;
    int i, len1, len2;

    if (nargs != 1) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    /* Pop args in reverse order */
    xop = valuePop(ctxt);
    if (xop == NULL || xmlXPathCheckError(ctxt))
	return;
    res = extBitStringVal(ctxt, xop);
    if (res == NULL)
	return;

    for (i = 0, val = 0; i <= 64 && res[i]; i++) {
	val <<= 1;
	if (res[i] == '1')
	    val += 1;
    }

    if (i > 64)
	xmlXPathReturnNumber(ctxt, (double) -1);
    else {
	len1 = xmlStrlen(res);
	len2 = snprintf((char *) res, len1 + 1, "0x%qx", val);
	if (len2 > len1) {
	    res = xmlRealloc(res, len2 + 1);
	    if (res)
		snprintf((char *) res, len2 + 1, "0x%qx", val);
	}

	xmlXPathReturnString(ctxt, res);
    }
}
Beispiel #19
0
static void
exsltObjectTypeFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr obj, ret;

    if (nargs != 1) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    obj = valuePop(ctxt);

    switch (obj->type) {
    case XPATH_STRING:
	ret = xmlXPathNewCString("string");
	break;
    case XPATH_NUMBER:
	ret = xmlXPathNewCString("number");
	break;
    case XPATH_BOOLEAN:
	ret = xmlXPathNewCString("boolean");
	break;
    case XPATH_NODESET:
	ret = xmlXPathNewCString("node-set");
	break;
    case XPATH_XSLT_TREE:
	ret = xmlXPathNewCString("RTF");
	break;
    case XPATH_USERS:
	ret = xmlXPathNewCString("external");
	break;
    default:
	xsltGenericError(xsltGenericErrorContext,
		"object-type() invalid arg\n");
	ctxt->error = XPATH_INVALID_TYPE;
	xmlXPathFreeObject(obj);
	return;
    }
    xmlXPathFreeObject(obj);
    valuePush(ctxt, ret);
}
Beispiel #20
0
static void
extBitFromInt (xmlXPathParserContextPtr ctxt, int nargs)
{
    xmlChar *res;
    xmlXPathObjectPtr xop;
    int width = 0, len;

    if (nargs != 1 && nargs != 2) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    /* Pop args in reverse order */
    if (nargs == 2) {
	width = xmlXPathPopNumber(ctxt);
	if (width < 0 || xmlXPathCheckError(ctxt))
	    return;
    }

    xop = valuePop(ctxt);
    if (xop == NULL || xmlXPathCheckError(ctxt))
	return;
    res = extBitStringVal(ctxt, xop);
    if (res == NULL)
	return;

    len = xmlStrlen(res);
    if (width > len) {
	res = xmlRealloc(res, width + 1);
	if (res) {
	    int count = width - len;
	    memmove(res + count, res, len + 1);
	    memset(res, '0', count);
	}
    }

    xmlXPathReturnString(ctxt, res);
}
Beispiel #21
0
/**
 * exsltStrConcatFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * Takes a node set and returns the concatenation of the string values
 * of the nodes in that node set.  If the node set is empty, it
 * returns an empty string.
 */
static void
exsltStrConcatFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr obj;
    xmlChar *ret = NULL;
    int i;

    if (nargs  != 1) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    if (!xmlXPathStackIsNodeSet(ctxt)) {
	xmlXPathSetTypeError(ctxt);
	return;
    }

    obj = valuePop (ctxt);

    if (xmlXPathNodeSetIsEmpty(obj->nodesetval)) {
	xmlXPathReturnEmptyString(ctxt);
	return;
    }

    for (i = 0; i < obj->nodesetval->nodeNr; i++) {
	xmlChar *tmp;
	tmp = xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]);

	ret = xmlStrcat (ret, tmp);

	xmlFree(tmp);
    }

    xmlXPathFreeObject (obj);

    xmlXPathReturnString(ctxt, ret);
}
Beispiel #22
0
/**
 * xsltFunctionLocalTime:
 * @ctxt:  the XPath Parser context
 * @nargs:  the number of arguments
 *
 * Implement the localTime XSLT function used by NORM
 *   string localTime(???)
 *
 * This function is available in Norm's extension namespace
 * Code (and comments) contributed by Norm
 */
static void
xsltFunctionLocalTime(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr obj;
    char *str;
    char digits[5];
    char result[29];
    long int field;
    time_t gmt, lmt;
    struct tm gmt_tm;
    struct tm *local_tm;
 
    if (nargs != 1) {
       xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
                      "localTime() : invalid number of args %d\n", nargs);
       ctxt->error = XPATH_INVALID_ARITY;
       return;
    }
 
    obj = valuePop(ctxt);

    if (obj->type != XPATH_STRING) {
	obj = xmlXPathConvertString(obj);
    }
    if (obj == NULL) {
	valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
	return;
    }
    
    str = (char *) obj->stringval;

    /* str = "$Date: Tuesday, November 03, 2009 11:37:25 AM$" */
    memset(digits, 0, sizeof(digits));
    strncpy(digits, str+7, 4);
    field = strtol(digits, NULL, 10);
    gmt_tm.tm_year = field - 1900;

    memset(digits, 0, sizeof(digits));
    strncpy(digits, str+12, 2);
    field = strtol(digits, NULL, 10);
    gmt_tm.tm_mon = field - 1;

    memset(digits, 0, sizeof(digits));
    strncpy(digits, str+15, 2);
    field = strtol(digits, NULL, 10);
    gmt_tm.tm_mday = field;

    memset(digits, 0, sizeof(digits));
    strncpy(digits, str+18, 2);
    field = strtol(digits, NULL, 10);
    gmt_tm.tm_hour = field;

    memset(digits, 0, sizeof(digits));
    strncpy(digits, str+21, 2);
    field = strtol(digits, NULL, 10);
    gmt_tm.tm_min = field;

    memset(digits, 0, sizeof(digits));
    strncpy(digits, str+24, 2);
    field = strtol(digits, NULL, 10);
    gmt_tm.tm_sec = field;

    /* Now turn gmt_tm into a time. */
    gmt = mktime(&gmt_tm);


    /*
     * FIXME: it's been too long since I did manual memory management.
     * (I swore never to do it again.) Does this introduce a memory leak?
     */
    local_tm = localtime(&gmt);

    /*
     * Calling localtime() has the side-effect of setting timezone.
     * After we know the timezone, we can adjust for it
     */
    lmt = gmt - timezone;

    /*
     * FIXME: it's been too long since I did manual memory management.
     * (I swore never to do it again.) Does this introduce a memory leak?
     */
    local_tm = localtime(&lmt);

    /*
     * Now convert local_tm back into a string. This doesn't introduce
     * a memory leak, so says asctime(3).
     */

    str = asctime(local_tm);           /* "Tue Jun 26 05:02:16 2001" */
                                       /*  0123456789 123456789 123 */

    memset(result, 0, sizeof(result)); /* "Thu, 26 Jun 2001" */
                                       /*  0123456789 12345 */

    strncpy(result, str, 20);
    strcpy(result+20, "???");          /* tzname doesn't work, fake it */
    strncpy(result+23, str+19, 5);

    /* Ok, now result contains the string I want to send back. */
    valuePush(ctxt, xmlXPathNewString((xmlChar *)result));
}
Beispiel #23
0
/**
 * xsltDocumentFunction:
 * @ctxt:  the XPath Parser context
 * @nargs:  the number of arguments
 *
 * Implement the document() XSLT function
 *   node-set document(object, node-set?)
 */
void
xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs)
{
    xmlXPathObjectPtr obj, obj2 = NULL;
    xmlChar *base = NULL, *URI;


    if ((nargs < 1) || (nargs > 2)) {
        xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
                         "document() : invalid number of args %d\n",
                         nargs);
        ctxt->error = XPATH_INVALID_ARITY;
        return;
    }
    if (ctxt->value == NULL) {
        xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
                         "document() : invalid arg value\n");
        ctxt->error = XPATH_INVALID_TYPE;
        return;
    }

    if (nargs == 2) {
        if (ctxt->value->type != XPATH_NODESET) {
            xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
                             "document() : invalid arg expecting a nodeset\n");
            ctxt->error = XPATH_INVALID_TYPE;
            return;
        }

        obj2 = valuePop(ctxt);
    }

    if (ctxt->value->type == XPATH_NODESET) {
        int i;
        xmlXPathObjectPtr newobj, ret;

        obj = valuePop(ctxt);
        ret = xmlXPathNewNodeSet(NULL);

        if ((obj != NULL) && obj->nodesetval) {
            for (i = 0; i < obj->nodesetval->nodeNr; i++) {
                valuePush(ctxt,
                          xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i]));
                xmlXPathStringFunction(ctxt, 1);
                if (nargs == 2) {
                    valuePush(ctxt, xmlXPathObjectCopy(obj2));
                } else {
                    valuePush(ctxt,
                              xmlXPathNewNodeSet(obj->nodesetval->
                                                 nodeTab[i]));
                }
                xsltDocumentFunction(ctxt, 2);
                newobj = valuePop(ctxt);
                ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval,
                                                       newobj->nodesetval);
                xmlXPathFreeObject(newobj);
            }
        }

        if (obj != NULL)
            xmlXPathFreeObject(obj);
        if (obj2 != NULL)
            xmlXPathFreeObject(obj2);
        valuePush(ctxt, ret);
        return;
    }
    /*
     * Make sure it's converted to a string
     */
    xmlXPathStringFunction(ctxt, 1);
    if (ctxt->value->type != XPATH_STRING) {
        xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
                         "document() : invalid arg expecting a string\n");
        ctxt->error = XPATH_INVALID_TYPE;
        if (obj2 != NULL)
            xmlXPathFreeObject(obj2);
        return;
    }
    obj = valuePop(ctxt);
    if (obj->stringval == NULL) {
        valuePush(ctxt, xmlXPathNewNodeSet(NULL));
    } else {
        xsltTransformContextPtr tctxt;
        tctxt = xsltXPathGetTransformContext(ctxt);
        if ((obj2 != NULL) && (obj2->nodesetval != NULL) &&
            (obj2->nodesetval->nodeNr > 0) &&
            IS_XSLT_REAL_NODE(obj2->nodesetval->nodeTab[0])) {
            xmlNodePtr target;

            target = obj2->nodesetval->nodeTab[0];
            if ((target->type == XML_ATTRIBUTE_NODE) ||
	        (target->type == XML_PI_NODE)) {
                target = ((xmlAttrPtr) target)->parent;
            }
            base = xmlNodeGetBase(target->doc, target);
        } else {
            if ((tctxt != NULL) && (tctxt->inst != NULL)) {
                base = xmlNodeGetBase(tctxt->inst->doc, tctxt->inst);
            } else if ((tctxt != NULL) && (tctxt->style != NULL) &&
                       (tctxt->style->doc != NULL)) {
                base = xmlNodeGetBase(tctxt->style->doc,
                                      (xmlNodePtr) tctxt->style->doc);
            }
        }
        URI = xmlBuildURI(obj->stringval, base);
        if (base != NULL)
            xmlFree(base);
        if (URI == NULL) {
            if ((tctxt != NULL) && (tctxt->style != NULL) &&
                (tctxt->style->doc != NULL) &&
                (xmlStrEqual(URI, tctxt->style->doc->URL))) {
                /* This selects the stylesheet's doc itself. */
                valuePush(ctxt, xmlXPathNewNodeSet((xmlNodePtr) tctxt->style->doc));
            } else {
                valuePush(ctxt, xmlXPathNewNodeSet(NULL));
            }
        } else {
	    xsltDocumentFunctionLoadDocument( ctxt, URI );
	    xmlFree(URI);
	}
    }
    xmlXPathFreeObject(obj);
    if (obj2 != NULL)
        xmlXPathFreeObject(obj2);
}
Beispiel #24
0
/**
 * xsltKeyFunction:
 * @ctxt:  the XPath Parser context
 * @nargs:  the number of arguments
 *
 * Implement the key() XSLT function
 *   node-set key(string, object)
 */
void
xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){
    xmlXPathObjectPtr obj1, obj2;

    if (nargs != 2) {
	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
		"key() : expects two arguments\n");
	ctxt->error = XPATH_INVALID_ARITY;
	return;
    }

    /*
    * Get the key's value.
    */
    obj2 = valuePop(ctxt);
    xmlXPathStringFunction(ctxt, 1);
    if ((obj2 == NULL) ||
	(ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
	    "key() : invalid arg expecting a string\n");
	ctxt->error = XPATH_INVALID_TYPE;
	xmlXPathFreeObject(obj2);

	return;
    }
    /*
    * Get the key's name.
    */
    obj1 = valuePop(ctxt);

    if ((obj2->type == XPATH_NODESET) || (obj2->type == XPATH_XSLT_TREE)) {
	int i;
	xmlXPathObjectPtr newobj, ret;

	ret = xmlXPathNewNodeSet(NULL);

	if (obj2->nodesetval != NULL) {
	    for (i = 0; i < obj2->nodesetval->nodeNr; i++) {
		valuePush(ctxt, xmlXPathObjectCopy(obj1));
		valuePush(ctxt,
			  xmlXPathNewNodeSet(obj2->nodesetval->nodeTab[i]));
		xmlXPathStringFunction(ctxt, 1);
		xsltKeyFunction(ctxt, 2);
		newobj = valuePop(ctxt);
		ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval,
						       newobj->nodesetval);
		xmlXPathFreeObject(newobj);
	    }
	}
	valuePush(ctxt, ret);
    } else {
	xmlNodeSetPtr nodelist = NULL;
	xmlChar *key = NULL, *value;
	const xmlChar *keyURI;
	xsltTransformContextPtr tctxt;
	xmlChar *qname, *prefix;
	xmlXPathContextPtr xpctxt = ctxt->context;
	xmlNodePtr tmpNode = NULL;
	xsltDocumentPtr oldDocInfo;

	tctxt = xsltXPathGetTransformContext(ctxt);

	oldDocInfo = tctxt->document;

	if (xpctxt->node == NULL) {
	    xsltTransformError(tctxt, NULL, tctxt->inst,
		"Internal error in xsltKeyFunction(): "
		"The context node is not set on the XPath context.\n");
	    tctxt->state = XSLT_STATE_STOPPED;
	    goto error;
	}
	/*
	 * Get the associated namespace URI if qualified name
	 */
	qname = obj1->stringval;
	key = xmlSplitQName2(qname, &prefix);
	if (key == NULL) {
	    key = xmlStrdup(obj1->stringval);
	    keyURI = NULL;
	    if (prefix != NULL)
		xmlFree(prefix);
	} else {
	    if (prefix != NULL) {
		keyURI = xmlXPathNsLookup(xpctxt, prefix);
		if (keyURI == NULL) {
		    xsltTransformError(tctxt, NULL, tctxt->inst,
			"key() : prefix %s is not bound\n", prefix);
		    /*
		    * TODO: Shouldn't we stop here?
		    */
		}
		xmlFree(prefix);
	    } else {
		keyURI = NULL;
	    }
	}

	/*
	 * Force conversion of first arg to string
	 */
	valuePush(ctxt, obj2);
	xmlXPathStringFunction(ctxt, 1);
	if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
	    xsltTransformError(tctxt, NULL, tctxt->inst,
		"key() : invalid arg expecting a string\n");
	    ctxt->error = XPATH_INVALID_TYPE;
	    goto error;
	}
	obj2 = valuePop(ctxt);
	value = obj2->stringval;

	/*
	* We need to ensure that ctxt->document is available for
	* xsltGetKey().
	* First find the relevant doc, which is the context node's
	* owner doc; using context->doc is not safe, since
	* the doc could have been acquired via the document() function,
	* or the doc might be a Result Tree Fragment.
	* FUTURE INFO: In XSLT 2.0 the key() function takes an additional
	* argument indicating the doc to use.
	*/
	if (xpctxt->node->type == XML_NAMESPACE_DECL) {
	    /*
	    * REVISIT: This is a libxml hack! Check xpath.c for details.
	    * The XPath module sets the owner element of a ns-node on
	    * the ns->next field.
	    */
	    if ((((xmlNsPtr) xpctxt->node)->next != NULL) &&
		(((xmlNsPtr) xpctxt->node)->next->type == XML_ELEMENT_NODE))
	    {
		tmpNode = (xmlNodePtr) ((xmlNsPtr) xpctxt->node)->next;
	    }
	} else
	    tmpNode = xpctxt->node;

	if ((tmpNode == NULL) || (tmpNode->doc == NULL)) {
	    xsltTransformError(tctxt, NULL, tctxt->inst,
		"Internal error in xsltKeyFunction(): "
		"Couldn't get the doc of the XPath context node.\n");
	    goto error;
	}

	if ((tctxt->document == NULL) ||
	    (tctxt->document->doc != tmpNode->doc))
	{
	    if (tmpNode->doc->name && (tmpNode->doc->name[0] == ' ')) {
		/*
		* This is a Result Tree Fragment.
		*/
		if (tmpNode->doc->_private == NULL) {
		    tmpNode->doc->_private = xsltNewDocument(tctxt, tmpNode->doc);
		    if (tmpNode->doc->_private == NULL)
			goto error;
		}
		tctxt->document = (xsltDocumentPtr) tmpNode->doc->_private;
	    } else {
		/*
		* May be the initial source doc or a doc acquired via the
		* document() function.
		*/
		tctxt->document = xsltFindDocument(tctxt, tmpNode->doc);
	    }
	    if (tctxt->document == NULL) {
		xsltTransformError(tctxt, NULL, tctxt->inst,
		    "Internal error in xsltKeyFunction(): "
		    "Could not get the document info of a context doc.\n");
		tctxt->state = XSLT_STATE_STOPPED;
		goto error;
	    }
	}
	/*
	* Get/compute the key value.
	*/
	nodelist = xsltGetKey(tctxt, key, keyURI, value);

error:
	tctxt->document = oldDocInfo;
	valuePush(ctxt, xmlXPathWrapNodeSet(
	    xmlXPathNodeSetMerge(NULL, nodelist)));
	if (key != NULL)
	    xmlFree(key);
    }

    if (obj1 != NULL)
	xmlXPathFreeObject(obj1);
    if (obj2 != NULL)
	xmlXPathFreeObject(obj2);
}
Beispiel #25
0
static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */
{
	xsltTransformContextPtr tctxt;
	zval *args;
	zval retval;
	int result, i;
	int error = 0;
	zend_fcall_info fci;
	zval handler;
	xmlXPathObjectPtr obj;
	char *str;
	xsl_object *intern;
	zend_string *callable = NULL;


	if (! zend_is_executing()) {
		xsltGenericError(xsltGenericErrorContext,
		"xsltExtFunctionTest: Function called from outside of PHP\n");
		error = 1;
	} else {
		tctxt = xsltXPathGetTransformContext(ctxt);
		if (tctxt == NULL) {
			xsltGenericError(xsltGenericErrorContext,
			"xsltExtFunctionTest: failed to get the transformation context\n");
			error = 1;
		} else {
			intern = (xsl_object*)tctxt->_private;
			if (intern == NULL) {
				xsltGenericError(xsltGenericErrorContext,
				"xsltExtFunctionTest: failed to get the internal object\n");
				error = 1;
			}
			else if (intern->registerPhpFunctions == 0) {
				xsltGenericError(xsltGenericErrorContext,
				"xsltExtFunctionTest: PHP Object did not register PHP functions\n");
				error = 1;
			}
		}
	}

	if (error == 1) {
		for (i = nargs - 1; i >= 0; i--) {
			obj = valuePop(ctxt);
			xmlXPathFreeObject(obj);
		}
		return;
	}

	fci.param_count = nargs - 1;
	if (fci.param_count > 0) {
		args = safe_emalloc(fci.param_count, sizeof(zval), 0);
	}
	/* Reverse order to pop values off ctxt stack */
	for (i = nargs - 2; i >= 0; i--) {
		obj = valuePop(ctxt);
		switch (obj->type) {
			case XPATH_STRING:
				ZVAL_STRING(&args[i], (char *)obj->stringval);
				break;
			case XPATH_BOOLEAN:
				ZVAL_BOOL(&args[i],  obj->boolval);
				break;
			case XPATH_NUMBER:
				ZVAL_DOUBLE(&args[i], obj->floatval);
				break;
			case XPATH_NODESET:
				if (type == 1) {
					str = (char*)xmlXPathCastToString(obj);
					ZVAL_STRING(&args[i], str);
					xmlFree(str);
				} else if (type == 2) {
					int j;
					dom_object *domintern = (dom_object *)intern->doc;
					array_init(&args[i]);
					if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
						for (j = 0; j < obj->nodesetval->nodeNr; j++) {
							xmlNodePtr node = obj->nodesetval->nodeTab[j];
							zval child;
							/* not sure, if we need this... it's copied from xpath.c */
							if (node->type == XML_NAMESPACE_DECL) {
								xmlNsPtr curns;
								xmlNodePtr nsparent;

								nsparent = node->_private;
								curns = xmlNewNs(NULL, node->name, NULL);
								if (node->children) {
									curns->prefix = xmlStrdup((char *)node->children);
								}
								if (node->children) {
									node = xmlNewDocNode(node->doc, NULL, (char *) node->children, node->name);
								} else {
									node = xmlNewDocNode(node->doc, NULL, (const xmlChar *) "xmlns", node->name);
								}
								node->type = XML_NAMESPACE_DECL;
								node->parent = nsparent;
								node->ns = curns;
							} else {
								node = xmlDocCopyNodeList(domintern->document->ptr, node);
							}

							php_dom_create_object(node, &child, domintern);
							add_next_index_zval(&args[i], &child);
						}
					}
				}
				break;
			default:
				str = (char *) xmlXPathCastToString(obj);
				ZVAL_STRING(&args[i], str);
				xmlFree(str);
		}
		xmlXPathFreeObject(obj);
	}

	fci.size = sizeof(fci);
	fci.function_table = EG(function_table);
	if (fci.param_count > 0) {
		fci.params = args;
	} else {
		fci.params = NULL;
	}


	obj = valuePop(ctxt);
	if (obj->stringval == NULL) {
		php_error_docref(NULL, E_WARNING, "Handler name must be a string");
		xmlXPathFreeObject(obj);
		valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
		if (fci.param_count > 0) {
			for (i = 0; i < nargs - 1; i++) {
				zval_ptr_dtor(&args[i]);
			}
			efree(args);
		}
		return;
	}
	ZVAL_STRING(&handler, (char *) obj->stringval);
	xmlXPathFreeObject(obj);

	ZVAL_COPY_VALUE(&fci.function_name, &handler);
	fci.symbol_table = NULL;
	fci.object = NULL;
	fci.retval = &retval;
	fci.no_separation = 0;
	/*fci.function_handler_cache = &function_ptr;*/
	if (!zend_make_callable(&handler, &callable)) {
		php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", ZSTR_VAL(callable));
		valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
	} else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable) == 0) {
		php_error_docref(NULL, E_WARNING, "Not allowed to call handler '%s()'", ZSTR_VAL(callable));
		/* Push an empty string, so that we at least have an xslt result... */
		valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
	} else {
		result = zend_call_function(&fci, NULL);
		if (result == FAILURE) {
			if (Z_TYPE(handler) == IS_STRING) {
				php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", Z_STRVAL(handler));
				valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
			}
		/* retval is == NULL, when an exception occurred, don't report anything, because PHP itself will handle that */
		} else if (Z_ISUNDEF(retval)) {
		} else {
			if (Z_TYPE(retval) == IS_OBJECT && instanceof_function(Z_OBJCE(retval), dom_node_class_entry)) {
				xmlNode *nodep;
				dom_object *obj;
				if (intern->node_list == NULL) {
					ALLOC_HASHTABLE(intern->node_list);
					zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
				}
				Z_ADDREF(retval);
				zend_hash_next_index_insert(intern->node_list, &retval);
				obj = Z_DOMOBJ_P(&retval);
				nodep = dom_object_get_node(obj);
				valuePush(ctxt, xmlXPathNewNodeSet(nodep));
			} else if (Z_TYPE(retval) == IS_TRUE || Z_TYPE(retval) == IS_FALSE) {
				valuePush(ctxt, xmlXPathNewBoolean(Z_LVAL(retval)));
			} else if (Z_TYPE(retval) == IS_OBJECT) {
				php_error_docref(NULL, E_WARNING, "A PHP Object cannot be converted to a XPath-string");
				valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
			} else {
				convert_to_string_ex(&retval);
				valuePush(ctxt, xmlXPathNewString((xmlChar *) Z_STRVAL(retval)));
			}
			zval_ptr_dtor(&retval);
		}
	}
	zend_string_release(callable);
	zval_ptr_dtor(&handler);
	if (fci.param_count > 0) {
		for (i = 0; i < nargs - 1; i++) {
			zval_ptr_dtor(&args[i]);
		}
		efree(args);
	}
}
static void ruby_funcall(xmlXPathParserContextPtr ctx, int nargs)
{
  VALUE xpath_handler = Qnil;
  VALUE result;
  VALUE *argv;
  VALUE doc;
  VALUE node_set = Qnil;
  xmlNodeSetPtr xml_node_set = NULL;
  xmlXPathObjectPtr obj;
  int i;
  nokogiriNodeSetTuple *node_set_tuple;

  assert(ctx);
  assert(ctx->context);
  assert(ctx->context->userData);
  assert(ctx->context->doc);
  assert(DOC_RUBY_OBJECT_TEST(ctx->context->doc));

  xpath_handler = (VALUE)(ctx->context->userData);

  argv = (VALUE *)calloc((size_t)nargs, sizeof(VALUE));
  for (i = 0 ; i < nargs ; ++i) {
    rb_gc_register_address(&argv[i]);
  }

  doc = DOC_RUBY_OBJECT(ctx->context->doc);

  if (nargs > 0) {
    i = nargs - 1;
    do {
      obj = valuePop(ctx);
      switch(obj->type) {
        case XPATH_STRING:
          argv[i] = NOKOGIRI_STR_NEW2(obj->stringval);
          break;
        case XPATH_BOOLEAN:
          argv[i] = obj->boolval == 1 ? Qtrue : Qfalse;
          break;
        case XPATH_NUMBER:
          argv[i] = rb_float_new(obj->floatval);
          break;
        case XPATH_NODESET:
          argv[i] = Nokogiri_wrap_xml_node_set(obj->nodesetval, doc);
          break;
        default:
          argv[i] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(obj));
      }
      xmlXPathFreeNodeSetList(obj);
    } while(i-- > 0);
  }

  result = rb_funcall2(
      xpath_handler,
      rb_intern((const char *)ctx->context->function),
      nargs,
      argv
  );

  for (i = 0 ; i < nargs ; ++i) {
    rb_gc_unregister_address(&argv[i]);
  }
  free(argv);

  switch(TYPE(result)) {
    case T_FLOAT:
    case T_BIGNUM:
    case T_FIXNUM:
      xmlXPathReturnNumber(ctx, NUM2DBL(result));
      break;
    case T_STRING:
      xmlXPathReturnString(
          ctx,
          (xmlChar *)xmlXPathWrapCString(StringValuePtr(result))
      );
      break;
    case T_TRUE:
      xmlXPathReturnTrue(ctx);
      break;
    case T_FALSE:
      xmlXPathReturnFalse(ctx);
      break;
    case T_NIL:
      break;
    case T_ARRAY:
      {
        VALUE args[2];
	args[0] = doc;
	args[1] = result;
        node_set = rb_class_new_instance(2, args, cNokogiriXmlNodeSet);
        Data_Get_Struct(node_set, nokogiriNodeSetTuple, node_set_tuple);
	xml_node_set = node_set_tuple->node_set;
        xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
      }
      break;
    case T_DATA:
      if(rb_obj_is_kind_of(result, cNokogiriXmlNodeSet)) {
        Data_Get_Struct(result, nokogiriNodeSetTuple, node_set_tuple);
	xml_node_set = node_set_tuple->node_set;
        /* Copy the node set, otherwise it will get GC'd. */
        xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
        break;
      }
    default:
      rb_raise(rb_eRuntimeError, "Invalid return type");
  }
}
Beispiel #27
0
static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */
{
	zval retval;
	int result, i;
	int error = 0;
	zend_fcall_info fci;
	xmlXPathObjectPtr obj;
	char *str;
	zend_string *callable = NULL;
	dom_xpath_object *intern;


	if (! zend_is_executing()) {
		xmlGenericError(xmlGenericErrorContext,
		"xmlExtFunctionTest: Function called from outside of PHP\n");
		error = 1;
	} else {
		intern = (dom_xpath_object *) ctxt->context->userData;
		if (intern == NULL) {
			xmlGenericError(xmlGenericErrorContext,
			"xmlExtFunctionTest: failed to get the internal object\n");
			error = 1;
		}
		else if (intern->registerPhpFunctions == 0) {
			xmlGenericError(xmlGenericErrorContext,
			"xmlExtFunctionTest: PHP Object did not register PHP functions\n");
			error = 1;
		}
	}

	if (error == 1) {
		for (i = nargs - 1; i >= 0; i--) {
			obj = valuePop(ctxt);
			xmlXPathFreeObject(obj);
		}
		return;
	}

	fci.param_count = nargs - 1;
	if (fci.param_count > 0) {
		fci.params = safe_emalloc(fci.param_count, sizeof(zval), 0);
	}
	/* Reverse order to pop values off ctxt stack */
	for (i = nargs - 2; i >= 0; i--) {
		obj = valuePop(ctxt);
		switch (obj->type) {
			case XPATH_STRING:
				ZVAL_STRING(&fci.params[i],  (char *)obj->stringval);
				break;
			case XPATH_BOOLEAN:
				ZVAL_BOOL(&fci.params[i],  obj->boolval);
				break;
			case XPATH_NUMBER:
				ZVAL_DOUBLE(&fci.params[i], obj->floatval);
				break;
			case XPATH_NODESET:
				if (type == 1) {
					str = (char *)xmlXPathCastToString(obj);
					ZVAL_STRING(&fci.params[i], str);
					xmlFree(str);
				} else if (type == 2) {
					int j;
					array_init(&fci.params[i]);
					if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
						for (j = 0; j < obj->nodesetval->nodeNr; j++) {
							xmlNodePtr node = obj->nodesetval->nodeTab[j];
							zval child;
							/* not sure, if we need this... it's copied from xpath.c */
							if (node->type == XML_NAMESPACE_DECL) {
								xmlNsPtr curns;
								xmlNodePtr nsparent;

								nsparent = node->_private;
								curns = xmlNewNs(NULL, node->name, NULL);
								if (node->children) {
									curns->prefix = xmlStrdup((xmlChar *) node->children);
								}
								if (node->children) {
									node = xmlNewDocNode(node->doc, NULL, (xmlChar *) node->children, node->name);
								} else {
									node = xmlNewDocNode(node->doc, NULL, (xmlChar *) "xmlns", node->name);
								}
								node->type = XML_NAMESPACE_DECL;
								node->parent = nsparent;
								node->ns = curns;
							}
							php_dom_create_object(node, &child, &intern->dom);
							add_next_index_zval(&fci.params[i], &child);
						}
					}
				}
				break;
			default:
			ZVAL_STRING(&fci.params[i], (char *)xmlXPathCastToString(obj));
		}
		xmlXPathFreeObject(obj);
	}

	fci.size = sizeof(fci);
	fci.function_table = EG(function_table);

	obj = valuePop(ctxt);
	if (obj->stringval == NULL) {
		php_error_docref(NULL, E_WARNING, "Handler name must be a string");
		xmlXPathFreeObject(obj);
		if (fci.param_count > 0) {
			for (i = 0; i < nargs - 1; i++) {
				zval_ptr_dtor(&fci.params[i]);
			}
			efree(fci.params);
		}
		return;
	}
	ZVAL_STRING(&fci.function_name, (char *) obj->stringval);
	xmlXPathFreeObject(obj);

	fci.symbol_table = NULL;
	fci.object = NULL;
	fci.retval = &retval;
	fci.no_separation = 0;

	if (!zend_make_callable(&fci.function_name, &callable)) {
		php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", callable->val);
	} else if (intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable) == 0) {
		php_error_docref(NULL, E_WARNING, "Not allowed to call handler '%s()'.", callable->val);
		/* Push an empty string, so that we at least have an xslt result... */
		valuePush(ctxt, xmlXPathNewString((xmlChar *)""));
	} else {
		result = zend_call_function(&fci, NULL);
		if (result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
			if (Z_TYPE(retval) == IS_OBJECT && instanceof_function(Z_OBJCE(retval), dom_node_class_entry)) {
				xmlNode *nodep;
				dom_object *obj;
				if (intern->node_list == NULL) {
					ALLOC_HASHTABLE(intern->node_list);
					zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
				}
				GC_REFCOUNT(&retval)++;
				zend_hash_next_index_insert(intern->node_list, &retval);
				obj = Z_DOMOBJ_P(&retval);
				nodep = dom_object_get_node(obj);
				valuePush(ctxt, xmlXPathNewNodeSet(nodep));
			} else if (Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE) {
				valuePush(ctxt, xmlXPathNewBoolean(Z_TYPE(retval) == IS_TRUE));
			} else if (Z_TYPE(retval) == IS_OBJECT) {
				php_error_docref(NULL, E_WARNING, "A PHP Object cannot be converted to a XPath-string");
				valuePush(ctxt, xmlXPathNewString((xmlChar *)""));
			} else {
				zend_string *str = zval_get_string(&retval);
				valuePush(ctxt, xmlXPathNewString((xmlChar *) str->val));
				zend_string_release(str);
			}
			zval_ptr_dtor(&retval);
		}
	}
	zend_string_release(callable);
	zval_dtor(&fci.function_name);
	if (fci.param_count > 0) {
		for (i = 0; i < nargs - 1; i++) {
			zval_ptr_dtor(&fci.params[i]);
		}
		efree(fci.params);
	}
}
static void method_caller(xmlXPathParserContextPtr ctxt, int nargs)
{
    const xmlChar * function;
    const xmlChar * functionURI;
    size_t i, count;

    xsltTransformContextPtr transform;
    xmlXPathObjectPtr xpath;
    VALUE obj;
    VALUE *args;
    VALUE result;

    transform = xsltXPathGetTransformContext(ctxt);

    function = ctxt->context->function;
    functionURI = ctxt->context->functionURI;
    obj = (VALUE)xsltGetExtData(transform, functionURI);

    count = (size_t)ctxt->valueNr;
    args = calloc(count, sizeof(VALUE *));

    for(i = 0; i < count; i++) {
	VALUE thing;

	xpath = valuePop(ctxt);
	switch(xpath->type) {
	    case XPATH_STRING:
		thing = NOKOGIRI_STR_NEW2(xpath->stringval);
		break;
	    case XPATH_NODESET:
		if(NULL == xpath->nodesetval) {
		    thing = Nokogiri_wrap_xml_node_set(
			    xmlXPathNodeSetCreate(NULL),
			    DOC_RUBY_OBJECT(ctxt->context->doc));
		} else {
		    thing = Nokogiri_wrap_xml_node_set(xpath->nodesetval,
			    DOC_RUBY_OBJECT(ctxt->context->doc));
		}
		break;
	    default:
		rb_raise(rb_eRuntimeError, "do not handle type: %d", xpath->type);
	}
	args[i] = thing;
	xmlFree(xpath);
    }
    result = rb_funcall3(obj, rb_intern((const char *)function), (int)count, args);
    free(args);
    switch(TYPE(result)) {
	case T_FLOAT:
	case T_BIGNUM:
	case T_FIXNUM:
	    xmlXPathReturnNumber(ctxt, NUM2DBL(result));
	    break;
	case T_STRING:
	    xmlXPathReturnString(
		    ctxt,
		    xmlStrdup((xmlChar *)StringValuePtr(result))
		    );
	    break;
	case T_TRUE:
	    xmlXPathReturnTrue(ctxt);
	    break;
	case T_FALSE:
	    xmlXPathReturnFalse(ctxt);
	    break;
	case T_NIL:
	    break;
	default:
	    rb_raise(rb_eRuntimeError, "Invalid return type");
    }
}
Beispiel #29
0
static void xslt_ext_function_php(xmlXPathParserContextPtr ctxt,
                                  int nargs,
                                  int type) {
  XSLTProcessorData *intern = nullptr;
  int error = 0;

  xsltTransformContextPtr tctxt = xsltXPathGetTransformContext (ctxt);
  if (tctxt == nullptr) {
    xsltGenericError(xsltGenericErrorContext,
      "xsltExtFunctionTest: failed to get the transformation context\n"
    );
    error = 1;
  } else {
    intern = (XSLTProcessorData*)tctxt->_private;
    if (intern == nullptr) {
      xsltGenericError(xsltGenericErrorContext,
        "xsltExtFunctionTest: failed to get the internal object\n"
      );
      error = 1;
    } else {
      if (intern->m_registerPhpFunctions == 0) {
        xsltGenericError(xsltGenericErrorContext,
          "xsltExtFunctionTest: PHP Object did not register PHP functions\n"
        );
        error = 1;
      }
    }
  }

  xmlXPathObjectPtr obj;
  if (error == 1) {
    for (int i = nargs - 1; i >= 0; i--) {
      obj = valuePop(ctxt);
      xmlXPathFreeObject(obj);
    }
    return;
  }

  Array args;
  // Reverse order to pop values off ctxt stack
  for (int i = nargs - 2; i >= 0; i--) {
    Variant arg;
    obj = valuePop(ctxt);
    switch (obj->type) {
    case XPATH_STRING:
      arg = String((char*)obj->stringval, CopyString);
      break;
    case XPATH_BOOLEAN:
      arg = (bool)obj->boolval;
      break;
    case XPATH_NUMBER:
      arg = (double)obj->floatval;
      break;
    case XPATH_NODESET:
      if (type == 1) {
        char *str = (char*)xmlXPathCastToString(obj);
        arg = String(str, CopyString);
        xmlFree(str);
      } else if (type == 2) {
        arg = Array::Create();
        if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
          for (int j = 0; j < obj->nodesetval->nodeNr; j++) {
            // TODO: not sure this is the right thing to do.
            xmlNodePtr node = obj->nodesetval->nodeTab[j];

            if (node->type == XML_ELEMENT_NODE) {
              Object element = newNode(s_DOMElement,
                                       xmlCopyNode(node, /*extended*/ 1));
              arg.toArrRef().append(element);
            } else if (node->type == XML_ATTRIBUTE_NODE) {
              Object attribute =
                newNode(s_DOMAttr,
                        (xmlNodePtr)xmlCopyProp(nullptr, (xmlAttrPtr)node));
              arg.toArrRef().append(attribute);
            } else if (node->type == XML_TEXT_NODE) {
              Object text =
                newNode(s_DOMText,
                        (xmlNodePtr)xmlNewText(xmlNodeGetContent(node)));
              arg.toArrRef().append(text);
            } else {
              raise_warning("Unhandled node type '%d'", node->type);
              // Use a generic DOMNode as fallback for now.
              Object nodeobj = newNode(s_DOMNode,
                                       xmlCopyNode(node, /*extended*/ 1));
              arg.toArrRef().append(nodeobj);
            }
          }
        }
      }
      break;
    default:
      arg = String((char*)xmlXPathCastToString(obj), CopyString);
    }
    xmlXPathFreeObject(obj);
    args.prepend(arg);
  }

  obj = valuePop(ctxt);
  if (obj->stringval == nullptr) {
    raise_warning("Handler name must be a string");
    xmlXPathFreeObject(obj);
    // Push an empty string to get an xslt result.
    valuePush(ctxt, xmlXPathNewString((xmlChar*)""));
    return;
  }
  String handler((char*)obj->stringval, CopyString);
  xmlXPathFreeObject(obj);

  if (!HHVM_FN(is_callable)(handler)) {
    raise_warning("Unable to call handler %s()", handler.data());
    // Push an empty string to get an xslt result.
    valuePush(ctxt, xmlXPathNewString((xmlChar*)""));
  } else if (intern->m_registerPhpFunctions == 2 &&
             !intern->m_registered_phpfunctions.exists(handler)) {
    raise_warning("Not allowed to call handler '%s()'", handler.data());
    // Push an empty string to get an xslt result.
    valuePush(ctxt, xmlXPathNewString((xmlChar*)""));
  } else {
    Variant retval = vm_call_user_func(handler, args);
    if (retval.isObject() &&
        retval.getObjectData()->instanceof(s_DOMNode)) {
      ObjectData *retval_data = retval.asCObjRef().get();
      xmlNode* nodep = Native::data<DOMNode>(retval_data)->nodep();
      valuePush(ctxt, xmlXPathNewNodeSet(nodep));
      intern->m_usedElements.prepend(retval);
    } else if (retval.is(KindOfBoolean)) {
      valuePush(ctxt, xmlXPathNewBoolean(retval.toBoolean()));
    } else if (retval.isObject()) {
      raise_warning("A PHP Object cannot be converted to an XPath-string");
      // Push an empty string to get an xslt result.
      valuePush(ctxt, xmlXPathNewString((xmlChar*)""));
    } else {
      String sretval = retval.toString();
      valuePush(ctxt, xmlXPathNewString((xmlChar*)sretval.data()));
    }
  }
}
Beispiel #30
0
/**
 * xsltSystemPropertyFunction:
 * @ctxt:  the XPath Parser context
 * @nargs:  the number of arguments
 *
 * Implement the system-property() XSLT function
 *   object system-property(string)
 */
void
xsltSystemPropertyFunction(xmlXPathParserContextPtr ctxt, int nargs){
    xmlXPathObjectPtr obj;
    xmlChar *prefix, *name;
    const xmlChar *nsURI = NULL;

    if (nargs != 1) {
	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
		"system-property() : expects one string arg\n");
	ctxt->error = XPATH_INVALID_ARITY;
	return;
    }
    if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
	    "system-property() : invalid arg expecting a string\n");
	ctxt->error = XPATH_INVALID_TYPE;
	return;
    }
    obj = valuePop(ctxt);
    if (obj->stringval == NULL) {
	valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
    } else {
	name = xmlSplitQName2(obj->stringval, &prefix);
	if (name == NULL) {
	    name = xmlStrdup(obj->stringval);
	} else {
	    nsURI = xmlXPathNsLookup(ctxt->context, prefix);
	    if (nsURI == NULL) {
		xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
		    "system-property() : prefix %s is not bound\n", prefix);
	    }
	}

	if (xmlStrEqual(nsURI, XSLT_NAMESPACE)) {
#ifdef DOCBOOK_XSL_HACK
	    if (xmlStrEqual(name, (const xmlChar *)"vendor")) {
		xsltStylesheetPtr sheet;
		xsltTransformContextPtr tctxt;

		tctxt = xsltXPathGetTransformContext(ctxt);
		if ((tctxt != NULL) && (tctxt->inst != NULL) &&
		    (xmlStrEqual(tctxt->inst->name, BAD_CAST "variable")) &&
		    (tctxt->inst->parent != NULL) &&
		    (xmlStrEqual(tctxt->inst->parent->name,
				 BAD_CAST "template")))
		    sheet = tctxt->style;
		else
		    sheet = NULL;
		if ((sheet != NULL) && (sheet->doc != NULL) &&
		    (sheet->doc->URL != NULL) &&
		    (xmlStrstr(sheet->doc->URL,
			       (const xmlChar *)"chunk") != NULL)) {
		    valuePush(ctxt, xmlXPathNewString(
			(const xmlChar *)"libxslt (SAXON 6.2 compatible)"));

		} else {
		    valuePush(ctxt, xmlXPathNewString(
			(const xmlChar *)XSLT_DEFAULT_VENDOR));
		}
	    } else
#else
	    if (xmlStrEqual(name, (const xmlChar *)"vendor")) {
		valuePush(ctxt, xmlXPathNewString(
			  (const xmlChar *)XSLT_DEFAULT_VENDOR));
	    } else
#endif
	    if (xmlStrEqual(name, (const xmlChar *)"version")) {
		valuePush(ctxt, xmlXPathNewString(
		    (const xmlChar *)XSLT_DEFAULT_VERSION));
	    } else if (xmlStrEqual(name, (const xmlChar *)"vendor-url")) {
		valuePush(ctxt, xmlXPathNewString(
		    (const xmlChar *)XSLT_DEFAULT_URL));
	    } else {
		valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
	    }
	} else {
	    valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
        }
	if (name != NULL)
	    xmlFree(name);
	if (prefix != NULL)
	    xmlFree(prefix);
    }
    xmlXPathFreeObject(obj);
}