Diff for /XML/xpath.c between versions 1.83 and 1.84

version 1.83, 2000/10/25 19:26:53 version 1.84, 2000/10/26 13:05:44
Line 72  double xmlXPathStringEvalNumber(const xm Line 72  double xmlXPathStringEvalNumber(const xm
  */   */
 double xmlXPathNAN = 0;  double xmlXPathNAN = 0;
 double xmlXPathPINF = 1;  double xmlXPathPINF = 1;
 double xmlXPathMINF = -1;  double xmlXPathNINF = -1;
   
 #ifndef isinf  #ifndef isinf
 #ifndef HAVE_ISINF  #ifndef HAVE_ISINF
Line 162  xmlXPathInit(void) { Line 162  xmlXPathInit(void) {
     xmlXPathPINF = 1;      xmlXPathPINF = 1;
     xmlXPathPINF /= 0;      xmlXPathPINF /= 0;
   
     xmlXPathMINF = -1;      xmlXPathNINF = -1;
     xmlXPathMINF /= 0;      xmlXPathNINF /= 0;
   
     initialized = 1;      initialized = 1;
 }  }
Line 2721  xmlXPathIdFunction(xmlXPathParserContext Line 2721  xmlXPathIdFunction(xmlXPathParserContext
     obj = valuePop(ctxt);      obj = valuePop(ctxt);
     if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND);      if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
     if (obj->type == XPATH_NODESET) {      if (obj->type == XPATH_NODESET) {
         TODO /* ID function in case of NodeSet */          xmlXPathObjectPtr newobj;
           int i;
   
           ret = xmlXPathNewNodeSet(NULL);
   
           for (i = 0; i < obj->nodesetval->nodeNr; i++) {
               valuePush(ctxt,
                         xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i]));
               xmlXPathStringFunction(ctxt, 1);
               xmlXPathIdFunction(ctxt, 1);
               newobj = valuePop(ctxt);
               ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval,
                                                      newobj->nodesetval);
               xmlXPathFreeObject(newobj);
           }
   
           xmlXPathFreeObject(obj);
           valuePush(ctxt, ret);
           return;
     }      }
     if (obj->type != XPATH_STRING) {      if (obj->type != XPATH_STRING) {
         valuePush(ctxt, obj);          valuePush(ctxt, obj);
Line 2771  xmlXPathIdFunction(xmlXPathParserContext Line 2789  xmlXPathIdFunction(xmlXPathParserContext
 }  }
   
 /**  /**
  * xmlXPathLocalPartFunction:   * xmlXPathLocalNameFunction:
  * @ctxt:  the XPath Parser context   * @ctxt:  the XPath Parser context
  *   *
  * Implement the local-part() XPath function   * Implement the local-name() XPath function
  * The local-part function returns a string containing the local part   * The local-name function returns a string containing the local part
  * of the name of the node in the argument node-set that is first in   * of the name of the node in the argument node-set that is first in
  * document order. If the node-set is empty or the first node has no   * document order. If the node-set is empty or the first node has no
  * name, an empty string is returned. If the argument is omitted it   * name, an empty string is returned. If the argument is omitted it
  * defaults to the context node.   * defaults to the context node.
  */   */
 void  void
 xmlXPathLocalPartFunction(xmlXPathParserContextPtr ctxt, int nargs) {  xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     xmlXPathObjectPtr cur;      xmlXPathObjectPtr cur;
   
       if (nargs == 0) {
           valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
           nargs = 1;
       }
   
     CHECK_ARITY(1);      CHECK_ARITY(1);
     CHECK_TYPE(XPATH_NODESET);      CHECK_TYPE(XPATH_NODESET);
     cur = valuePop(ctxt);      cur = valuePop(ctxt);
Line 2799  xmlXPathLocalPartFunction(xmlXPathParser Line 2822  xmlXPathLocalPartFunction(xmlXPathParser
 }  }
   
 /**  /**
  * xmlXPathNamespaceFunction:   * xmlXPathNamespaceURIFunction:
  * @ctxt:  the XPath Parser context   * @ctxt:  the XPath Parser context
  *   *
  * Implement the namespace() XPath function   * Implement the namespace-uri() XPath function
  * The namespace function returns a string containing the namespace URI   * The namespace-uri function returns a string containing the
  * of the expanded name of the node in the argument node-set that is   * namespace URI of the expanded name of the node in the argument
  * first in document order. If the node-set is empty, the first node has   * node-set that is first in document order. If the node-set is empty,
  * no name, or the expanded name has no namespace URI, an empty string   * the first node has no name, or the expanded name has no namespace
  * is returned. If the argument is omitted it defaults to the context node.   * URI, an empty string is returned. If the argument is omitted it
    * defaults to the context node.
  */   */
 void  void
 xmlXPathNamespaceFunction(xmlXPathParserContextPtr ctxt, int nargs) {  xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     xmlXPathObjectPtr cur;      xmlXPathObjectPtr cur;
   
     if (nargs == 0) {      if (nargs == 0) {
Line 2859  void Line 2883  void
 xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {  xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     xmlXPathObjectPtr cur;      xmlXPathObjectPtr cur;
   
       if (nargs == 0) {
           valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
           nargs = 1;
       }
   
     CHECK_ARITY(1);      CHECK_ARITY(1);
     CHECK_TYPE(XPATH_NODESET);      CHECK_TYPE(XPATH_NODESET);
     cur = valuePop(ctxt);      cur = valuePop(ctxt);
Line 2920  xmlXPathNameFunction(xmlXPathParserConte Line 2949  xmlXPathNameFunction(xmlXPathParserConte
  *        number from all other IEEE 754 numeric values.   *        number from all other IEEE 754 numeric values.
  *    - The boolean false value is converted to the string false.   *    - The boolean false value is converted to the string false.
  *      The boolean true value is converted to the string true.   *      The boolean true value is converted to the string true.
    *
    * If the argument is omitted, it defaults to a node-set with the
    * context node as its only member.
  */   */
 void  void
 xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {  xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     xmlXPathObjectPtr cur;      xmlXPathObjectPtr cur;
   
       if (nargs == 0) {
           valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
           nargs = 1;
       }
   
     CHECK_ARITY(1);      CHECK_ARITY(1);
     cur = valuePop(ctxt);      cur = valuePop(ctxt);
     if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);      if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
Line 3302  xmlXPathNormalizeFunction(xmlXPathParser Line 3339  xmlXPathNormalizeFunction(xmlXPathParser
   xmlBufferPtr target;    xmlBufferPtr target;
   xmlChar blank;    xmlChar blank;
       
   if (nargs < 1) {    if (nargs == 0) {
     /* Use current context node */      /* Use current context node */
     CHECK_ARITY(0);      valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
     TODO /* source = xmlNodeGetContent(ctxt->context->node); */      xmlXPathStringFunction(ctxt, 1);
   } else if (nargs >= 1) {      nargs = 1;
     /* Use argument */  
     CHECK_ARITY(1);  
     obj = valuePop(ctxt);  
     if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND);  
     source = obj->stringval;  
   }    }
   
     CHECK_ARITY(1);
     CHECK_TYPE(XPATH_STRING);
     obj = valuePop(ctxt);
     source = obj->stringval;
   
   target = xmlBufferCreate();    target = xmlBufferCreate();
   if (target && source) {    if (target && source) {
           
Line 3338  xmlXPathNormalizeFunction(xmlXPathParser Line 3376  xmlXPathNormalizeFunction(xmlXPathParser
     valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));      valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
     xmlBufferFree(target);      xmlBufferFree(target);
   }    }
   if (obj)    xmlXPathFreeObject(obj);
     xmlXPathFreeObject(obj);  
 }  }
   
 /**  /**
Line 3530  not_equal: Line 3567  not_equal:
  * @ctxt:  the XPath Parser context   * @ctxt:  the XPath Parser context
  *   *
  * Implement the number() XPath function   * Implement the number() XPath function
    *
    * BUG: since we directly call xmlXPathStringEvalNumber(),
    *      number("-1") isn't evaluated in -1.0 but in NaN.
  */   */
 void  void
 xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {  xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     xmlXPathObjectPtr cur;      xmlXPathObjectPtr cur;
     double res;      double res;
   
       if (nargs == 0) {
           if (ctxt->context->node == NULL) {
               valuePush(ctxt, xmlXPathNewFloat(0.0));
           } else {
               xmlChar* content = xmlNodeGetContent(ctxt->context->node);
   
               res = xmlXPathStringEvalNumber(content);
               valuePush(ctxt, xmlXPathNewFloat(res));
               xmlFree(content);
           }
           return;
       }
   
     CHECK_ARITY(1);      CHECK_ARITY(1);
     cur = valuePop(ctxt);      cur = valuePop(ctxt);
     switch (cur->type) {      switch (cur->type) {
Line 3583  xmlXPathNumberFunction(xmlXPathParserCon Line 3636  xmlXPathNumberFunction(xmlXPathParserCon
  */   */
 void  void
 xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {  xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
       xmlXPathObjectPtr cur;
       int i;
   
     CHECK_ARITY(1);      CHECK_ARITY(1);
     TODO /* BUG Sum : don't understand the definition */      CHECK_TYPE(XPATH_NODESET);
       cur = valuePop(ctxt);
   
       if (cur->nodesetval->nodeNr == 0) {
           valuePush(ctxt, xmlXPathNewFloat(0.0));
       } else {
           valuePush(ctxt,
                     xmlXPathNewNodeSet(cur->nodesetval->nodeTab[0]));
           for (i = 1; i < cur->nodesetval->nodeNr; i++) {
               valuePush(ctxt,
                         xmlXPathNewNodeSet(cur->nodesetval->nodeTab[i]));
               xmlXPathAddValues(ctxt);
           }
       }
       xmlXPathFreeObject(cur);
 }  }
   
 /**  /**
Line 3599  void Line 3669  void
 xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) {  xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     CHECK_ARITY(1);      CHECK_ARITY(1);
     CHECK_TYPE(XPATH_NUMBER);      CHECK_TYPE(XPATH_NUMBER);
   #if 0
       ctxt->value->floatval = floor(ctxt->value->floatval);
   #else
     /* floor(0.999999999999) => 1.0 !!!!!!!!!!! */      /* floor(0.999999999999) => 1.0 !!!!!!!!!!! */
     ctxt->value->floatval = (double)((int) ctxt->value->floatval);      ctxt->value->floatval = (double)((int) ctxt->value->floatval);
   #endif
 }  }
   
 /**  /**
Line 3617  xmlXPathCeilingFunction(xmlXPathParserCo Line 3691  xmlXPathCeilingFunction(xmlXPathParserCo
   
     CHECK_ARITY(1);      CHECK_ARITY(1);
     CHECK_TYPE(XPATH_NUMBER);      CHECK_TYPE(XPATH_NUMBER);
   
   #if 0
       ctxt->value->floatval = ceil(ctxt->value->floatval);
   #else
     f = (double)((int) ctxt->value->floatval);      f = (double)((int) ctxt->value->floatval);
     if (f != ctxt->value->floatval)      if (f != ctxt->value->floatval)
         ctxt->value->floatval = f + 1;          ctxt->value->floatval = f + 1;
   #endif
 }  }
   
 /**  /**
Line 3637  xmlXPathRoundFunction(xmlXPathParserCont Line 3716  xmlXPathRoundFunction(xmlXPathParserCont
   
     CHECK_ARITY(1);      CHECK_ARITY(1);
     CHECK_TYPE(XPATH_NUMBER);      CHECK_TYPE(XPATH_NUMBER);
     /* round(0.50000001) => 0  !!!!! */  
       if ((ctxt->value->floatval == xmlXPathNAN) ||
           (ctxt->value->floatval == xmlXPathPINF) ||
           (ctxt->value->floatval == xmlXPathNINF) ||
           (ctxt->value->floatval == 0.0))
           return;
   
   #if 0
       f = floor(ctxt->value->floatval);
   #else
     f = (double)((int) ctxt->value->floatval);      f = (double)((int) ctxt->value->floatval);
   #endif
     if (ctxt->value->floatval < f + 0.5)      if (ctxt->value->floatval < f + 0.5)
         ctxt->value->floatval = f;          ctxt->value->floatval = f;
     else if (ctxt->value->floatval == f + 0.5)  
         ctxt->value->floatval = f; /* !!!! Not following the spec here */  
     else       else 
         ctxt->value->floatval = f + 1;          ctxt->value->floatval = f + 1;
 }  }
Line 3766  xmlXPathParseName(xmlXPathParserContextP Line 3853  xmlXPathParseName(xmlXPathParserContextP
  * xmlXPathStringEvalNumber:   * xmlXPathStringEvalNumber:
  * @str:  A string to scan   * @str:  A string to scan
  *   *
  *  [30]   Number ::=   Digits ('.' Digits)?   *  [30]   Number ::=   Digits ('.' Digits?)?
  *                    | '.' Digits    *                    | '.' Digits 
  *  [31]   Digits ::=   [0-9]+   *  [31]   Digits ::=   [0-9]+
  *   *
  * Parse and evaluate a Number in the string   * Parse and evaluate a Number in the string
  *   *
  * BUG: "1.' is not valid ... James promised correction  
  *       as Digits ('.' Digits?)?  
  *  
  * Returns the double value.   * Returns the double value.
  */   */
 double  double
Line 3813  xmlXPathStringEvalNumber(const xmlChar * Line 3897  xmlXPathStringEvalNumber(const xmlChar *
  * xmlXPathEvalNumber:   * xmlXPathEvalNumber:
  * @ctxt:  the XPath Parser context   * @ctxt:  the XPath Parser context
  *   *
  *  [30]   Number ::=   Digits ('.' Digits)?   *  [30]   Number ::=   Digits ('.' Digits?)?
  *                    | '.' Digits    *                    | '.' Digits 
  *  [31]   Digits ::=   [0-9]+   *  [31]   Digits ::=   [0-9]+
  *   *
  * Parse and evaluate a Number, then push it on the stack   * Parse and evaluate a Number, then push it on the stack
  *   *
  * BUG: "1.' is not valid ... James promised correction  
  *       as Digits ('.' Digits?)?  
  */   */
 void  void
 xmlXPathEvalNumber(xmlXPathParserContextPtr ctxt) {  xmlXPathEvalNumber(xmlXPathParserContextPtr ctxt) {
Line 5302  xmlXPathRegisterAllFunctions(xmlXPathCon Line 5384  xmlXPathRegisterAllFunctions(xmlXPathCon
                          xmlXPathLastFunction);                           xmlXPathLastFunction);
     xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang",      xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang",
                          xmlXPathLangFunction);                           xmlXPathLangFunction);
     xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-part",      xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-name",
                          xmlXPathLocalPartFunction);                           xmlXPathLocalNameFunction);
     xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not",      xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not",
                          xmlXPathNotFunction);                           xmlXPathNotFunction);
     xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name",      xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name",
                          xmlXPathNameFunction);                           xmlXPathNameFunction);
     xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace",      xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace-uri",
                          xmlXPathNamespaceFunction);                           xmlXPathNamespaceURIFunction);
     xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space",      xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space",
                          xmlXPathNormalizeFunction);                           xmlXPathNormalizeFunction);
     xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize",      xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize",

Removed from v.1.83  
changed lines
  Added in v.1.84


Webmaster