Exemple #1
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);
}
Exemple #2
0
/**
 * exsltMathMinFunction:
 * @ctxt:  an XPath parser context
 * @nargs:  the number of arguments
 *
 * Wraps #exsltMathMin for use by the XPath processor.
 */
static void
exsltMathMinFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    xmlNodeSetPtr ns;
    double ret;
    void *user = NULL;

    if (nargs != 1) {
	xsltGenericError(xsltGenericErrorContext,
			 "math:min: invalid number of arguments\n");
	ctxt->error = XPATH_INVALID_ARITY;
	return;
    }
    /* We need to delay the freeing of value->user */
    if ((ctxt->value != NULL) && (ctxt->value->boolval != 0)) {
        user = ctxt->value->user;
	ctxt->value->boolval = 0;
	ctxt->value->user = NULL;
    }
    ns = xmlXPathPopNodeSet(ctxt);
    if (xmlXPathCheckError(ctxt))
	return;

    ret = exsltMathMin(ns);

    xmlXPathFreeNodeSet(ns);
    if (user != NULL)
        xmlFreeNodeList((xmlNodePtr)user);

    xmlXPathReturnNumber(ctxt, ret);
}
Exemple #3
0
static void XSLPattern_index(xmlXPathParserContextPtr pctx, int nargs)
{
    XSLPATTERN_CHECK_ARGS(0);

    xmlXPathPositionFunction(pctx, 0);
    xmlXPathReturnNumber(pctx, xmlXPathPopNumber(pctx) - 1.0);
}
Exemple #4
0
/**
 * exsltMathMaxFunction:
 * @ctxt:  an XPath parser context
 * @nargs:  the number of arguments
 *
 * Wraps #exsltMathMax for use by the XPath processor.
 */
static void
exsltMathMaxFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    xmlNodeSetPtr ns;
    double ret;
    void *user = NULL;

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

    /* We need to delay the freeing of value->user */
    if ((ctxt->value != NULL) && (ctxt->value->boolval != 0)) {
	user = ctxt->value->user;
	ctxt->value->boolval = 0;
	ctxt->value->user = 0;
    }
    ns = xmlXPathPopNodeSet(ctxt);
    if (xmlXPathCheckError(ctxt))
	return;

    ret = exsltMathMax(ns);

    xmlXPathFreeNodeSet(ns);

    if (user != NULL)
        xmlFreeNodeList((xmlNodePtr)user);
    xmlXPathReturnNumber(ctxt, ret);
}
Exemple #5
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);
}
Exemple #6
0
/**
 * exsltMathRandomFunction:
 * @ctxt:  an XPath parser context
 * @nargs:  the number of arguments
 *
 * Wraps #exsltMathRandom for use by the XPath processor.
 */
static void
exsltMathRandomFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    double ret;

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

    ret = exsltMathRandom();

    xmlXPathReturnNumber(ctxt, ret);
}
Exemple #7
0
/**
 * exsltMathAtanFunction:
 * @ctxt:  an XPath parser context
 * @nargs:  the number of arguments
 *
 * Wraps #exsltMathAtan for use by the XPath processor.
 */
static void
exsltMathAtanFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    double ret;

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

    ret = exsltMathAtan(ret);

    xmlXPathReturnNumber(ctxt, ret);
}
Exemple #8
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);
    }
}
Exemple #9
0
/**
 * exsltMathPower:
 * @ctxt:  an XPath parser context
 * @nargs:  the number of arguments
 *
 * Wraps #exsltMathPower for use by the XPath processor.
 */
static void
exsltMathPowerFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    double ret, base;

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

    /* power */
    base = xmlXPathPopNumber(ctxt);
    if (xmlXPathCheckError(ctxt))
	return;

    ret = exsltMathPower(base, ret);

    xmlXPathReturnNumber(ctxt, ret);
}
Exemple #10
0
/**
 * exsltMathConstantFunction:
 * @ctxt:  an XPath parser context
 * @nargs:  the number of arguments
 *
 * Wraps #exsltMathConstant for use by the XPath processor.
 */
static void
exsltMathConstantFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    double   ret;
    xmlChar *name;

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

    name = xmlXPathPopString(ctxt);
    if (xmlXPathCheckError(ctxt))
	return;

    ret = exsltMathConstant(name, ret);

    xmlXPathReturnNumber(ctxt, ret);
}
Exemple #11
0
static void XSLPattern_nodeType(xmlXPathParserContextPtr pctx, int nargs)
{
    XSLPATTERN_CHECK_ARGS(0);
    xmlXPathReturnNumber(pctx, pctx->context->node->type);
}
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");
  }
}
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");
    }
}