Diff for /embedaddon/libxml2/xmlregexp.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2013/07/22 01:22:22 version 1.1.1.3, 2014/06/15 19:53:28
Line 1 Line 1
 /*  /*
  * regexp.c: generic and extensible Regular Expression engine   * regexp.c: generic and extensible Regular Expression engine
  *   *
 * Basically designed with the purpose of compiling regexps for  * Basically designed with the purpose of compiling regexps for
  * the variety of validation/shemas mechanisms now available in   * the variety of validation/shemas mechanisms now available in
  * XML related specifications these include:   * XML related specifications these include:
  *    - XML-1.0 DTD validation   *    - XML-1.0 DTD validation
Line 68 Line 68
  *   *
  * macro to flag unimplemented blocks   * macro to flag unimplemented blocks
  */   */
#define TODO                                                            \#define TODO                                                            \
     xmlGenericError(xmlGenericErrorContext,                             \      xmlGenericError(xmlGenericErrorContext,                             \
             "Unimplemented block at %s:%d\n",                           \              "Unimplemented block at %s:%d\n",                           \
             __FILE__, __LINE__);              __FILE__, __LINE__);
   
 /************************************************************************  /************************************************************************
 *                                                                      * *                                                                        *
 *                      Datatypes and structures                        * *                      Datatypes and structures                        *
 *                                                                      * *                                                                      *
  ************************************************************************/   ************************************************************************/
   
 /*  /*
Line 222  struct _xmlRegTrans { Line 222  struct _xmlRegTrans {
 struct _xmlAutomataState {  struct _xmlAutomataState {
     xmlRegStateType type;      xmlRegStateType type;
     xmlRegMarkedType mark;      xmlRegMarkedType mark;
       xmlRegMarkedType markd;
     xmlRegMarkedType reached;      xmlRegMarkedType reached;
     int no;      int no;
     int maxTrans;      int maxTrans;
Line 364  void xmlAutomataSetFlags(xmlAutomataPtr am, int flags) Line 365  void xmlAutomataSetFlags(xmlAutomataPtr am, int flags)
   
 /************************************************************************  /************************************************************************
  *                                                                      *   *                                                                      *
 *              Regexp memory error handler                             * *                Regexp memory error handler                             *
  *                                                                      *   *                                                                      *
  ************************************************************************/   ************************************************************************/
 /**  /**
Line 411  xmlRegexpErrCompile(xmlRegParserCtxtPtr ctxt, const ch Line 412  xmlRegexpErrCompile(xmlRegParserCtxtPtr ctxt, const ch
 }  }
   
 /************************************************************************  /************************************************************************
 *                                                                      * *                                                                        *
 *                      Allocation/Deallocation                         * *                      Allocation/Deallocation                         *
 *                                                                      * *                                                                      *
  ************************************************************************/   ************************************************************************/
   
 static int xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt);  static int xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt);
Line 934  xmlRegFreeParserCtxt(xmlRegParserCtxtPtr ctxt) { Line 935  xmlRegFreeParserCtxt(xmlRegParserCtxtPtr ctxt) {
 }  }
   
 /************************************************************************  /************************************************************************
 *                                                                      * *                                                                        *
 *                      Display of Data structures                      * *                      Display of Data structures                      *
 *                                                                      * *                                                                      *
  ************************************************************************/   ************************************************************************/
   
 static void  static void
Line 1143  xmlRegPrintTrans(FILE *output, xmlRegTransPtr trans) { Line 1144  xmlRegPrintTrans(FILE *output, xmlRegTransPtr trans) {
         fprintf(output, "char %c ", trans->atom->codepoint);          fprintf(output, "char %c ", trans->atom->codepoint);
     fprintf(output, "atom %d, to %d\n", trans->atom->no, trans->to);      fprintf(output, "atom %d, to %d\n", trans->atom->no, trans->to);
 }  }
    
 static void  static void
 xmlRegPrintState(FILE *output, xmlRegStatePtr state) {  xmlRegPrintState(FILE *output, xmlRegStatePtr state) {
     int i;      int i;
Line 1157  xmlRegPrintState(FILE *output, xmlRegStatePtr state) { Line 1158  xmlRegPrintState(FILE *output, xmlRegStatePtr state) {
         fprintf(output, "START ");          fprintf(output, "START ");
     if (state->type == XML_REGEXP_FINAL_STATE)      if (state->type == XML_REGEXP_FINAL_STATE)
         fprintf(output, "FINAL ");          fprintf(output, "FINAL ");
    
     fprintf(output, "%d, %d transitions:\n", state->no, state->nbTrans);      fprintf(output, "%d, %d transitions:\n", state->no, state->nbTrans);
     for (i = 0;i < state->nbTrans; i++) {      for (i = 0;i < state->nbTrans; i++) {
         xmlRegPrintTrans(output, &(state->trans[i]));          xmlRegPrintTrans(output, &(state->trans[i]));
Line 1207  xmlRegPrintCtxt(FILE *output, xmlRegParserCtxtPtr ctxt Line 1208  xmlRegPrintCtxt(FILE *output, xmlRegParserCtxtPtr ctxt
 #endif  #endif
   
 /************************************************************************  /************************************************************************
 *                                                                      * *                                                                        *
  *               Finite Automata structures manipulations               *   *               Finite Automata structures manipulations               *
 *                                                                      * *                                                                        *
  ************************************************************************/   ************************************************************************/
   
static void static void
 xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom,  xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom,
                    int neg, xmlRegAtomType type, int start, int end,                     int neg, xmlRegAtomType type, int start, int end,
                    xmlChar *blockName) {                     xmlChar *blockName) {
Line 1252  xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAto Line 1253  xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAto
         return;          return;
     range->blockName = blockName;      range->blockName = blockName;
     atom->ranges[atom->nbRanges++] = range;      atom->ranges[atom->nbRanges++] = range;
    
 }  }
   
 static int  static int
Line 1283  xmlRegGetCounter(xmlRegParserCtxtPtr ctxt) { Line 1284  xmlRegGetCounter(xmlRegParserCtxtPtr ctxt) {
     return(ctxt->nbCounters++);      return(ctxt->nbCounters++);
 }  }
   
static int static int
 xmlRegAtomPush(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) {  xmlRegAtomPush(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) {
     if (atom == NULL) {      if (atom == NULL) {
         ERROR("atom push: atom is NULL");          ERROR("atom push: atom is NULL");
Line 1315  xmlRegAtomPush(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr Line 1316  xmlRegAtomPush(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr
     return(0);      return(0);
 }  }
   
static void static void
 xmlRegStateAddTransTo(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr target,  xmlRegStateAddTransTo(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr target,
                       int from) {                        int from) {
     if (target->maxTransTo == 0) {      if (target->maxTransTo == 0) {
Line 1343  xmlRegStateAddTransTo(xmlRegParserCtxtPtr ctxt, xmlReg Line 1344  xmlRegStateAddTransTo(xmlRegParserCtxtPtr ctxt, xmlReg
     target->nbTransTo++;      target->nbTransTo++;
 }  }
   
static void static void
 xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,  xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
                     xmlRegAtomPtr atom, xmlRegStatePtr target,                      xmlRegAtomPtr atom, xmlRegStatePtr target,
                     int counter, int count) {                      int counter, int count) {
Line 1409  xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegSt Line 1410  xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegSt
         printf("counted %d\n", counter);          printf("counted %d\n", counter);
     else if (atom == NULL)      else if (atom == NULL)
         printf("epsilon transition\n");          printf("epsilon transition\n");
    else if (atom != NULL)     else if (atom != NULL)
         xmlRegPrintAtom(stdout, atom);          xmlRegPrintAtom(stdout, atom);
 #endif  #endif
   
Line 1563  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml Line 1564  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml
              */               */
             xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to);              xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to);
 #ifdef DV  #ifdef DV
        } else if ((to == NULL) && (atom->quant != XML_REGEXP_QUANT_RANGE) &&         } else if ((to == NULL) && (atom->quant != XML_REGEXP_QUANT_RANGE) &&
                    (atom->quant != XML_REGEXP_QUANT_ONCE)) {                     (atom->quant != XML_REGEXP_QUANT_ONCE)) {
             to = xmlRegNewState(ctxt);              to = xmlRegNewState(ctxt);
             xmlRegStatePush(ctxt, to);              xmlRegStatePush(ctxt, to);
Line 1577  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml Line 1578  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml
                 /*                  /*
                  * transition done to the state after end of atom.                   * transition done to the state after end of atom.
                  *      1. set transition from atom start to new state                   *      1. set transition from atom start to new state
                 *      2. set transition from atom end to this state.                  *      2. set transition from atom end to this state.
                  */                   */
                 if (to == NULL) {                  if (to == NULL) {
                     xmlFAGenerateEpsilonTransition(ctxt, atom->start, 0);                      xmlFAGenerateEpsilonTransition(ctxt, atom->start, 0);
Line 1621  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml Line 1622  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml
                     /*                      /*
                      * duplicate a transition based on atom to count next                       * duplicate a transition based on atom to count next
                      * occurences after 1. We cannot loop to atom->start                       * occurences after 1. We cannot loop to atom->start
                     * directly because we need an epsilon transition to                      * directly because we need an epsilon transition to
                      * newstate.                       * newstate.
                      */                       */
                      /* ???? For some reason it seems we never reach that                       /* ???? For some reason it seems we never reach that
Line 1680  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml Line 1681  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml
                 break;                  break;
         }          }
         return(0);          return(0);
    }     }
     if ((atom->min == 0) && (atom->max == 0) &&      if ((atom->min == 0) && (atom->max == 0) &&
                (atom->quant == XML_REGEXP_QUANT_RANGE)) {                 (atom->quant == XML_REGEXP_QUANT_RANGE)) {
         /*          /*
Line 1706  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml Line 1707  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml
         else {          else {
             return(-1);              return(-1);
         }          }
    }     }
     end = to;      end = to;
    if ((atom->quant == XML_REGEXP_QUANT_MULT) ||     if ((atom->quant == XML_REGEXP_QUANT_MULT) ||
         (atom->quant == XML_REGEXP_QUANT_PLUS)) {          (atom->quant == XML_REGEXP_QUANT_PLUS)) {
         /*          /*
          * Do not pollute the target state by adding transitions from           * Do not pollute the target state by adding transitions from
Line 1716  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml Line 1717  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml
          * So isolate with an epsilon transition.           * So isolate with an epsilon transition.
          */           */
         xmlRegStatePtr tmp;          xmlRegStatePtr tmp;
        
         tmp = xmlRegNewState(ctxt);          tmp = xmlRegNewState(ctxt);
         if (tmp != NULL)          if (tmp != NULL)
             xmlRegStatePush(ctxt, tmp);              xmlRegStatePush(ctxt, tmp);
Line 1745  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml Line 1746  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml
             atom->quant = XML_REGEXP_QUANT_ONCE;              atom->quant = XML_REGEXP_QUANT_ONCE;
             xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1);              xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1);
             break;              break;
        case XML_REGEXP_QUANT_RANGE:         case XML_REGEXP_QUANT_RANGE:
 #if DV_test  #if DV_test
             if (atom->min == 0) {              if (atom->min == 0) {
                 xmlFAGenerateEpsilonTransition(ctxt, from, to);                  xmlFAGenerateEpsilonTransition(ctxt, from, to);
Line 1762  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml Line 1763  xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xml
  * xmlFAReduceEpsilonTransitions:   * xmlFAReduceEpsilonTransitions:
  * @ctxt:  a regexp parser context   * @ctxt:  a regexp parser context
  * @fromnr:  the from state   * @fromnr:  the from state
 * @tonr:  the to state  * @tonr:  the to state
  * @counter:  should that transition be associated to a counted   * @counter:  should that transition be associated to a counted
  *   *
  */   */
Line 1806  xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt Line 1807  xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt
                     int newto = to->trans[transnr].to;                      int newto = to->trans[transnr].to;
   
                     xmlRegStateAddTrans(ctxt, from, NULL,                      xmlRegStateAddTrans(ctxt, from, NULL,
                                        ctxt->states[newto],                                         ctxt->states[newto],
                                         -1, to->trans[transnr].count);                                          -1, to->trans[transnr].count);
                 } else {                  } else {
 #ifdef DEBUG_REGEXP_GRAPH  #ifdef DEBUG_REGEXP_GRAPH
Line 1828  xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt Line 1829  xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt
             int newto = to->trans[transnr].to;              int newto = to->trans[transnr].to;
   
             if (to->trans[transnr].counter >= 0) {              if (to->trans[transnr].counter >= 0) {
                xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom,                 xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom,
                                    ctxt->states[newto],                                     ctxt->states[newto],
                                     to->trans[transnr].counter, -1);                                      to->trans[transnr].counter, -1);
             } else {              } else {
                xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom,                 xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom,
                                     ctxt->states[newto], counter, -1);                                      ctxt->states[newto], counter, -1);
             }              }
         }          }
Line 1844  xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt Line 1845  xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt
  * xmlFAEliminateSimpleEpsilonTransitions:   * xmlFAEliminateSimpleEpsilonTransitions:
  * @ctxt:  a regexp parser context   * @ctxt:  a regexp parser context
  *   *
 * Eliminating general epsilon transitions can get costly in the general  * Eliminating general epsilon transitions can get costly in the general
  * algorithm due to the large amount of generated new transitions and   * algorithm due to the large amount of generated new transitions and
  * associated comparisons. However for simple epsilon transition used just   * associated comparisons. However for simple epsilon transition used just
  * to separate building blocks when generating the automata this can be   * to separate building blocks when generating the automata this can be
Line 1880  xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtx Line 1881  xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtx
 #ifdef DEBUG_REGEXP_GRAPH  #ifdef DEBUG_REGEXP_GRAPH
                 printf("Found simple epsilon trans from start %d to %d\n",                  printf("Found simple epsilon trans from start %d to %d\n",
                        statenr, newto);                         statenr, newto);
#endif     #endif
             } else {              } else {
 #ifdef DEBUG_REGEXP_GRAPH  #ifdef DEBUG_REGEXP_GRAPH
                 printf("Found simple epsilon trans from %d to %d\n",                  printf("Found simple epsilon trans from %d to %d\n",
                        statenr, newto);                         statenr, newto);
#endif     #endif
                 for (i = 0;i < state->nbTransTo;i++) {                  for (i = 0;i < state->nbTransTo;i++) {
                     tmp = ctxt->states[state->transTo[i]];                      tmp = ctxt->states[state->transTo[i]];
                     for (j = 0;j < tmp->nbTrans;j++) {                      for (j = 0;j < tmp->nbTrans;j++) {
Line 1893  xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtx Line 1894  xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtx
 #ifdef DEBUG_REGEXP_GRAPH  #ifdef DEBUG_REGEXP_GRAPH
                             printf("Changed transition %d on %d to go to %d\n",                              printf("Changed transition %d on %d to go to %d\n",
                                    j, tmp->no, newto);                                     j, tmp->no, newto);
#endif     #endif
                             tmp->trans[j].to = -1;                              tmp->trans[j].to = -1;
                             xmlRegStateAddTrans(ctxt, tmp, tmp->trans[j].atom,                              xmlRegStateAddTrans(ctxt, tmp, tmp->trans[j].atom,
                                                ctxt->states[newto],                                                ctxt->states[newto],
                                                 tmp->trans[j].counter,                                                  tmp->trans[j].counter,
                                                 tmp->trans[j].count);                                                  tmp->trans[j].count);
                         }                          }
Line 1910  xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtx Line 1911  xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtx
                 state->type = XML_REGEXP_UNREACH_STATE;                  state->type = XML_REGEXP_UNREACH_STATE;
   
             }              }
            
         }          }
     }      }
 }  }
Line 2112  xmlFACompareRanges(xmlRegRangePtr range1, xmlRegRangeP Line 2113  xmlFACompareRanges(xmlRegRangePtr range1, xmlRegRangeP
         /*          /*
          * just check all codepoints in the range for acceptance,           * just check all codepoints in the range for acceptance,
          * this is usually way cheaper since done only once at           * this is usually way cheaper since done only once at
         * compilation than testing over and over at runtime or          * compilation than testing over and over at runtime or
          * pushing too many states when evaluating.           * pushing too many states when evaluating.
          */           */
         if (((range1->neg == 0) && (range2->neg != 0)) ||          if (((range1->neg == 0) && (range2->neg != 0)) ||
Line 2589  xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlR Line 2590  xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlR
   
     if (state == NULL)      if (state == NULL)
         return(ret);          return(ret);
       if (state->markd == XML_REGEXP_MARK_VISITED)
           return(ret);
   
     if (ctxt->flags & AM_AUTOMATA_RNG)      if (ctxt->flags & AM_AUTOMATA_RNG)
         deep = 0;          deep = 0;
Line 2606  xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlR Line 2609  xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlR
         if (t1->atom == NULL) {          if (t1->atom == NULL) {
             if (t1->to < 0)              if (t1->to < 0)
                 continue;                  continue;
               state->markd = XML_REGEXP_MARK_VISITED;
             res = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to],              res = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to],
                                            to, atom);                                             to, atom);
               state->markd = 0;
             if (res == 0) {              if (res == 0) {
                 ret = 0;                  ret = 0;
                 /* t1->nd = 1; */                  /* t1->nd = 1; */
Line 2776  xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) { Line 2781  xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) {
 }  }
   
 /************************************************************************  /************************************************************************
 *                                                                      * *                                                                        *
  *      Routines to check input against transition atoms                *   *      Routines to check input against transition atoms                *
 *                                                                      * *                                                                        *
  ************************************************************************/   ************************************************************************/
   
 static int  static int
Line 2807  xmlRegCheckCharacterRange(xmlRegAtomType type, int cod Line 2812  xmlRegCheckCharacterRange(xmlRegAtomType type, int cod
         case XML_REGEXP_NOTINITNAME:          case XML_REGEXP_NOTINITNAME:
             neg = !neg;              neg = !neg;
         case XML_REGEXP_INITNAME:          case XML_REGEXP_INITNAME:
            ret = (IS_LETTER(codepoint) ||             ret = (IS_LETTER(codepoint) ||
                    (codepoint == '_') || (codepoint == ':'));                     (codepoint == '_') || (codepoint == ':'));
             break;              break;
         case XML_REGEXP_NOTNAMECHAR:          case XML_REGEXP_NOTNAMECHAR:
Line 3055  xmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint Line 3060  xmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint
 }  }
   
 /************************************************************************  /************************************************************************
 *                                                                      * *                                                                        *
  *      Saving and restoring state of an execution context              *   *      Saving and restoring state of an execution context              *
 *                                                                      * *                                                                        *
  ************************************************************************/   ************************************************************************/
   
 #ifdef DEBUG_REGEXP_EXEC  #ifdef DEBUG_REGEXP_EXEC
Line 3168  xmlFARegExecRollBack(xmlRegExecCtxtPtr exec) { Line 3173  xmlFARegExecRollBack(xmlRegExecCtxtPtr exec) {
 }  }
   
 /************************************************************************  /************************************************************************
 *                                                                      * *                                                                        *
  *      Verifier, running an input against a compiled regexp            *   *      Verifier, running an input against a compiled regexp            *
 *                                                                      * *                                                                        *
  ************************************************************************/   ************************************************************************/
   
 static int  static int
Line 3202  xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content Line 3207  xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content
         memset(exec->counts, 0, comp->nbCounters * sizeof(int));          memset(exec->counts, 0, comp->nbCounters * sizeof(int));
     } else      } else
         exec->counts = NULL;          exec->counts = NULL;
    while ((exec->status == 0) &&    while ((exec->status == 0) && (exec->state != NULL) &&
            ((exec->inputString[exec->index] != 0) ||             ((exec->inputString[exec->index] != 0) ||
             ((exec->state != NULL) &&              ((exec->state != NULL) &&
              (exec->state->type != XML_REGEXP_FINAL_STATE)))) {               (exec->state->type != XML_REGEXP_FINAL_STATE)))) {
Line 3456  error: Line 3461  error:
         }          }
         xmlFree(exec->rollbacks);          xmlFree(exec->rollbacks);
     }      }
       if (exec->state == NULL)
           return(-1);
     if (exec->counts != NULL)      if (exec->counts != NULL)
         xmlFree(exec->counts);          xmlFree(exec->counts);
     if (exec->status == 0)      if (exec->status == 0)
Line 3469  error: Line 3476  error:
 }  }
   
 /************************************************************************  /************************************************************************
 *                                                                      * *                                                                        *
  *      Progressive interface to the verifier one atom at a time        *   *      Progressive interface to the verifier one atom at a time        *
 *                                                                      * *                                                                        *
  ************************************************************************/   ************************************************************************/
 #ifdef DEBUG_ERR  #ifdef DEBUG_ERR
 static void testerr(xmlRegExecCtxtPtr exec);  static void testerr(xmlRegExecCtxtPtr exec);
Line 3588  xmlFARegExecSaveInputString(xmlRegExecCtxtPtr exec, co Line 3595  xmlFARegExecSaveInputString(xmlRegExecCtxtPtr exec, co
 #endif  #endif
     if (exec->inputStackMax == 0) {      if (exec->inputStackMax == 0) {
         exec->inputStackMax = 4;          exec->inputStackMax = 4;
        exec->inputStack = (xmlRegInputTokenPtr)         exec->inputStack = (xmlRegInputTokenPtr)
             xmlMalloc(exec->inputStackMax * sizeof(xmlRegInputToken));              xmlMalloc(exec->inputStackMax * sizeof(xmlRegInputToken));
         if (exec->inputStack == NULL) {          if (exec->inputStack == NULL) {
             xmlRegexpErrMemory(NULL, "pushing input string");              xmlRegexpErrMemory(NULL, "pushing input string");
Line 3617  xmlFARegExecSaveInputString(xmlRegExecCtxtPtr exec, co Line 3624  xmlFARegExecSaveInputString(xmlRegExecCtxtPtr exec, co
   
 /**  /**
  * xmlRegStrEqualWildcard:   * xmlRegStrEqualWildcard:
 * @expStr:  the string to be evaluated  * @expStr:  the string to be evaluated
  * @valStr:  the validation string   * @valStr:  the validation string
  *   *
  * Checks if both strings are equal or have the same content. "*"   * Checks if both strings are equal or have the same content. "*"
 * can be used as a wildcard in @valStr; "|" is used as a seperator of  * can be used as a wildcard in @valStr; "|" is used as a seperator of
  * substrings in both @expStr and @valStr.   * substrings in both @expStr and @valStr.
  *   *
  * Returns 1 if the comparison is satisfied and the number of substrings   * Returns 1 if the comparison is satisfied and the number of substrings
Line 3687  xmlRegCompactPushString(xmlRegExecCtxtPtr exec, Line 3694  xmlRegCompactPushString(xmlRegExecCtxtPtr exec,
   
     if ((comp == NULL) || (comp->compact == NULL) || (comp->stringMap == NULL))      if ((comp == NULL) || (comp->compact == NULL) || (comp->stringMap == NULL))
         return(-1);          return(-1);
    
     if (value == NULL) {      if (value == NULL) {
         /*          /*
          * are we at a final state ?           * are we at a final state ?
Line 3708  xmlRegCompactPushString(xmlRegExecCtxtPtr exec, Line 3715  xmlRegCompactPushString(xmlRegExecCtxtPtr exec,
     for (i = 0;i < comp->nbstrings;i++) {      for (i = 0;i < comp->nbstrings;i++) {
         target = comp->compact[state * (comp->nbstrings + 1) + i + 1];          target = comp->compact[state * (comp->nbstrings + 1) + i + 1];
         if ((target > 0) && (target <= comp->nbstates)) {          if ((target > 0) && (target <= comp->nbstates)) {
            target--; /* to avoid 0 */                target--; /* to avoid 0 */
             if (xmlRegStrEqualWildcard(comp->stringMap[i], value)) {              if (xmlRegStrEqualWildcard(comp->stringMap[i], value)) {
                exec->index = target;                           exec->index = target;
                 if ((exec->callback != NULL) && (comp->transdata != NULL)) {                  if ((exec->callback != NULL) && (comp->transdata != NULL)) {
                     exec->callback(exec->data, value,                      exec->callback(exec->data, value,
                           comp->transdata[state * comp->nbstrings + i], data);                            comp->transdata[state * comp->nbstrings + i], data);
Line 3844  xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, c Line 3851  xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, c
                             continue;                              continue;
                         counter = &exec->comp->counters[t->counter];                          counter = &exec->comp->counters[t->counter];
                         count = exec->counts[t->counter];                          count = exec->counts[t->counter];
                        if ((count < counter->max) &&                         if ((count < counter->max) &&
                             (t->atom != NULL) &&                              (t->atom != NULL) &&
                             (xmlStrEqual(value, t->atom->valuep))) {                              (xmlStrEqual(value, t->atom->valuep))) {
                             ret = 0;                              ret = 0;
Line 4202  xmlRegExecGetValues(xmlRegExecCtxtPtr exec, int err, Line 4209  xmlRegExecGetValues(xmlRegExecCtxtPtr exec, int err,
     int maxval;      int maxval;
     int nb = 0;      int nb = 0;
   
    if ((exec == NULL) || (nbval == NULL) || (nbneg == NULL) ||     if ((exec == NULL) || (nbval == NULL) || (nbneg == NULL) ||
         (values == NULL) || (*nbval <= 0))          (values == NULL) || (*nbval <= 0))
         return(-1);          return(-1);
   
Line 4308  xmlRegExecGetValues(xmlRegExecCtxtPtr exec, int err, Line 4315  xmlRegExecGetValues(xmlRegExecCtxtPtr exec, int err,
                         values[nb++] = (xmlChar *) atom->valuep;                          values[nb++] = (xmlChar *) atom->valuep;
                     (*nbval)++;                      (*nbval)++;
                 }                  }
            }             }
         }          }
         for (transno = 0;          for (transno = 0;
              (transno < state->nbTrans) && (nb < maxval);               (transno < state->nbTrans) && (nb < maxval);
Line 4335  xmlRegExecGetValues(xmlRegExecCtxtPtr exec, int err, Line 4342  xmlRegExecGetValues(xmlRegExecCtxtPtr exec, int err,
                         values[nb++] = (xmlChar *) atom->valuep;                          values[nb++] = (xmlChar *) atom->valuep;
                     (*nbneg)++;                      (*nbneg)++;
                 }                  }
            }             }
         }          }
     }      }
     return(0);      return(0);
Line 4566  progress: Line 4573  progress:
 }  }
 #endif  #endif
 /************************************************************************  /************************************************************************
 *                                                                      * *                                                                        *
  *      Parser for the Schemas Datatype Regular Expressions             *   *      Parser for the Schemas Datatype Regular Expressions             *
  *      http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#regexs      *   *      http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#regexs      *
 *                                                                      * *                                                                        *
  ************************************************************************/   ************************************************************************/
   
 /**  /**
Line 4598  xmlFAIsChar(xmlRegParserCtxtPtr ctxt) { Line 4605  xmlFAIsChar(xmlRegParserCtxtPtr ctxt) {
  *   *
  * [27]   charProp   ::=   IsCategory | IsBlock   * [27]   charProp   ::=   IsCategory | IsBlock
  * [28]   IsCategory ::= Letters | Marks | Numbers | Punctuation |   * [28]   IsCategory ::= Letters | Marks | Numbers | Punctuation |
 *                       Separators | Symbols | Others  *                       Separators | Symbols | Others
  * [29]   Letters   ::=   'L' [ultmo]?   * [29]   Letters   ::=   'L' [ultmo]?
  * [30]   Marks   ::=   'M' [nce]?   * [30]   Marks   ::=   'M' [nce]?
  * [31]   Numbers   ::=   'N' [dlo]?   * [31]   Numbers   ::=   'N' [dlo]?
Line 4613  xmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) { Line 4620  xmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) {
     int cur;      int cur;
     xmlRegAtomType type = (xmlRegAtomType) 0;      xmlRegAtomType type = (xmlRegAtomType) 0;
     xmlChar *blockName = NULL;      xmlChar *blockName = NULL;
    
     cur = CUR;      cur = CUR;
     if (cur == 'L') {      if (cur == 'L') {
         NEXT;          NEXT;
Line 4785  xmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) { Line 4792  xmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) {
         NEXT;          NEXT;
         start = ctxt->cur;          start = ctxt->cur;
         cur = CUR;          cur = CUR;
        if (((cur >= 'a') && (cur <= 'z')) ||         if (((cur >= 'a') && (cur <= 'z')) ||
            ((cur >= 'A') && (cur <= 'Z')) ||             ((cur >= 'A') && (cur <= 'Z')) ||
            ((cur >= '0') && (cur <= '9')) ||             ((cur >= '0') && (cur <= '9')) ||
             (cur == 0x2D)) {              (cur == 0x2D)) {
             NEXT;              NEXT;
             cur = CUR;              cur = CUR;
            while (((cur >= 'a') && (cur <= 'z')) ||             while (((cur >= 'a') && (cur <= 'z')) ||
                ((cur >= 'A') && (cur <= 'Z')) ||                 ((cur >= 'A') && (cur <= 'Z')) ||
                ((cur >= '0') && (cur <= '9')) ||                 ((cur >= '0') && (cur <= '9')) ||
                 (cur == 0x2D)) {                  (cur == 0x2D)) {
                 NEXT;                  NEXT;
                 cur = CUR;                  cur = CUR;
Line 4819  xmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) { Line 4826  xmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) {
  * xmlFAParseCharClassEsc:   * xmlFAParseCharClassEsc:
  * @ctxt:  a regexp parser context   * @ctxt:  a regexp parser context
  *   *
 * [23] charClassEsc ::= ( SingleCharEsc | MultiCharEsc | catEsc | complEsc )  * [23] charClassEsc ::= ( SingleCharEsc | MultiCharEsc | catEsc | complEsc )
  * [24] SingleCharEsc ::= '\' [nrt\|.?*+(){}#x2D#x5B#x5D#x5E]   * [24] SingleCharEsc ::= '\' [nrt\|.?*+(){}#x2D#x5B#x5D#x5E]
  * [25] catEsc   ::=   '\p{' charProp '}'   * [25] catEsc   ::=   '\p{' charProp '}'
  * [26] complEsc ::=   '\P{' charProp '}'   * [26] complEsc ::=   '\P{' charProp '}'
Line 4916  xmlFAParseCharClassEsc(xmlRegParserCtxtPtr ctxt) { Line 4923  xmlFAParseCharClassEsc(xmlRegParserCtxtPtr ctxt) {
         xmlRegAtomType type = XML_REGEXP_ANYSPACE;          xmlRegAtomType type = XML_REGEXP_ANYSPACE;
   
         switch (cur) {          switch (cur) {
            case 's':             case 's':
                 type = XML_REGEXP_ANYSPACE;                  type = XML_REGEXP_ANYSPACE;
                 break;                  break;
            case 'S':             case 'S':
                 type = XML_REGEXP_NOTSPACE;                  type = XML_REGEXP_NOTSPACE;
                 break;                  break;
            case 'i':             case 'i':
                 type = XML_REGEXP_INITNAME;                  type = XML_REGEXP_INITNAME;
                 break;                  break;
            case 'I':             case 'I':
                 type = XML_REGEXP_NOTINITNAME;                  type = XML_REGEXP_NOTINITNAME;
                 break;                  break;
            case 'c':             case 'c':
                 type = XML_REGEXP_NAMECHAR;                  type = XML_REGEXP_NAMECHAR;
                 break;                  break;
            case 'C':             case 'C':
                 type = XML_REGEXP_NOTNAMECHAR;                  type = XML_REGEXP_NOTNAMECHAR;
                 break;                  break;
            case 'd':             case 'd':
                 type = XML_REGEXP_DECIMAL;                  type = XML_REGEXP_DECIMAL;
                 break;                  break;
            case 'D':             case 'D':
                 type = XML_REGEXP_NOTDECIMAL;                  type = XML_REGEXP_NOTDECIMAL;
                 break;                  break;
            case 'w':             case 'w':
                 type = XML_REGEXP_REALCHAR;                  type = XML_REGEXP_REALCHAR;
                 break;                  break;
            case 'W':             case 'W':
                 type = XML_REGEXP_NOTREALCHAR;                  type = XML_REGEXP_NOTREALCHAR;
                 break;                  break;
         }          }
Line 4963  xmlFAParseCharClassEsc(xmlRegParserCtxtPtr ctxt) { Line 4970  xmlFAParseCharClassEsc(xmlRegParserCtxtPtr ctxt) {
  * xmlFAParseCharRange:   * xmlFAParseCharRange:
  * @ctxt:  a regexp parser context   * @ctxt:  a regexp parser context
  *   *
 * [17]   charRange   ::=     seRange | XmlCharRef | XmlCharIncDash  * [17]   charRange   ::=     seRange | XmlCharRef | XmlCharIncDash
  * [18]   seRange   ::=   charOrEsc '-' charOrEsc   * [18]   seRange   ::=   charOrEsc '-' charOrEsc
  * [20]   charOrEsc   ::=   XmlChar | SingleCharEsc   * [20]   charOrEsc   ::=   XmlChar | SingleCharEsc
  * [21]   XmlChar   ::=   [^\#x2D#x5B#x5D]   * [21]   XmlChar   ::=   [^\#x2D#x5B#x5D]
Line 5078  xmlFAParsePosCharGroup(xmlRegParserCtxtPtr ctxt) { Line 5085  xmlFAParsePosCharGroup(xmlRegParserCtxtPtr ctxt) {
  *   *
  * [13]   charGroup    ::= posCharGroup | negCharGroup | charClassSub   * [13]   charGroup    ::= posCharGroup | negCharGroup | charClassSub
  * [15]   negCharGroup ::= '^' posCharGroup   * [15]   negCharGroup ::= '^' posCharGroup
 * [16]   charClassSub ::= ( posCharGroup | negCharGroup ) '-' charClassExpr   * [16]   charClassSub ::= ( posCharGroup | negCharGroup ) '-' charClassExpr
  * [12]   charClassExpr ::= '[' charGroup ']'   * [12]   charClassExpr ::= '[' charGroup ']'
  */   */
 static void  static void
Line 5326  xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegState Line 5333  xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegState
     previous = ctxt->state;      previous = ctxt->state;
     ret = xmlFAParsePiece(ctxt);      ret = xmlFAParsePiece(ctxt);
     if (ret != 0) {      if (ret != 0) {
        if (xmlFAGenerateTransitions(ctxt, previous,         if (xmlFAGenerateTransitions(ctxt, previous,
                 (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0)                  (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0)
             return(-1);              return(-1);
         previous = ctxt->state;          previous = ctxt->state;
Line 5335  xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegState Line 5342  xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegState
     while ((ret != 0) && (ctxt->error == 0)) {      while ((ret != 0) && (ctxt->error == 0)) {
         ret = xmlFAParsePiece(ctxt);          ret = xmlFAParsePiece(ctxt);
         if (ret != 0) {          if (ret != 0) {
            if (xmlFAGenerateTransitions(ctxt, previous,             if (xmlFAGenerateTransitions(ctxt, previous,
                     (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0)                      (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0)
                     return(-1);                      return(-1);
             previous = ctxt->state;              previous = ctxt->state;
Line 5373  xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) { Line 5380  xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) {
     end = ctxt->state;      end = ctxt->state;
     while ((CUR == '|') && (ctxt->error == 0)) {      while ((CUR == '|') && (ctxt->error == 0)) {
         NEXT;          NEXT;
           if (CUR == 0) {
               ERROR("expecting a branch after |")
               return;
           }
         ctxt->state = start;          ctxt->state = start;
         ctxt->end = NULL;          ctxt->end = NULL;
         xmlFAParseBranch(ctxt, end);          xmlFAParseBranch(ctxt, end);
Line 5384  xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) { Line 5395  xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) {
 }  }
   
 /************************************************************************  /************************************************************************
 *                                                                      * *                                                                        *
 *                      The basic API                                   * *                      The basic API                                   *
 *                                                                      * *                                                                      *
  ************************************************************************/   ************************************************************************/
   
 /**  /**
Line 5573  xmlRegFreeRegexp(xmlRegexpPtr regexp) { Line 5584  xmlRegFreeRegexp(xmlRegexpPtr regexp) {
   
 #ifdef LIBXML_AUTOMATA_ENABLED  #ifdef LIBXML_AUTOMATA_ENABLED
 /************************************************************************  /************************************************************************
 *                                                                      * *                                                                        *
 *                      The Automata interface                          * *                      The Automata interface                          *
 *                                                                      * *                                                                      *
  ************************************************************************/   ************************************************************************/
   
 /**  /**
Line 5846  xmlAutomataNewNegTrans(xmlAutomataPtr am, xmlAutomataS Line 5857  xmlAutomataNewNegTrans(xmlAutomataPtr am, xmlAutomataS
  *   *
  * If @to is NULL, this creates first a new target state in the automata   * If @to is NULL, this creates first a new target state in the automata
  * and then adds a transition from the @from state to the target state   * and then adds a transition from the @from state to the target state
 * activated by a succession of input of value @token and @token2 and  * activated by a succession of input of value @token and @token2 and
  * whose number is between @min and @max   * whose number is between @min and @max
  *   *
  * Returns the target state or NULL in case of error   * Returns the target state or NULL in case of error
Line 6000  xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomat Line 6011  xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomat
  *   *
  * If @to is NULL, this creates first a new target state in the automata   * If @to is NULL, this creates first a new target state in the automata
  * and then adds a transition from the @from state to the target state   * and then adds a transition from the @from state to the target state
 * activated by a succession of input of value @token and @token2 and whose  * activated by a succession of input of value @token and @token2 and whose
 * number is between @min and @max, moreover that transition can only be  * number is between @min and @max, moreover that transition can only be
  * crossed once.   * crossed once.
  *   *
  * Returns the target state or NULL in case of error   * Returns the target state or NULL in case of error
Line 6043  xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomat Line 6054  xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomat
         str[lenn + lenp + 1] = 0;          str[lenn + lenp + 1] = 0;
   
         atom->valuep = str;          atom->valuep = str;
    }        }
     atom->data = data;      atom->data = data;
     atom->quant = XML_REGEXP_QUANT_ONCEONLY;      atom->quant = XML_REGEXP_QUANT_ONCEONLY;
     atom->min = min;      atom->min = min;
Line 6066  xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomat Line 6077  xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomat
     return(to);      return(to);
 }  }
   
       
   
   
 /**  /**
  * xmlAutomataNewOnceTrans:   * xmlAutomataNewOnceTrans:
  * @am: an automata   * @am: an automata
Line 6135  xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomata Line 6146  xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomata
  */   */
 xmlAutomataStatePtr  xmlAutomataStatePtr
 xmlAutomataNewState(xmlAutomataPtr am) {  xmlAutomataNewState(xmlAutomataPtr am) {
    xmlAutomataStatePtr to;     xmlAutomataStatePtr to;
   
     if (am == NULL)      if (am == NULL)
         return(NULL);          return(NULL);
Line 6202  xmlAutomataNewAllTrans(xmlAutomataPtr am, xmlAutomataS Line 6213  xmlAutomataNewAllTrans(xmlAutomataPtr am, xmlAutomataS
  *   *
  * Returns the counter number or -1 in case of error   * Returns the counter number or -1 in case of error
  */   */
int             int
 xmlAutomataNewCounter(xmlAutomataPtr am, int min, int max) {  xmlAutomataNewCounter(xmlAutomataPtr am, int min, int max) {
     int ret;      int ret;
   
Line 6274  xmlAutomataNewCounterTrans(xmlAutomataPtr am, xmlAutom Line 6285  xmlAutomataNewCounterTrans(xmlAutomataPtr am, xmlAutom
  *   *
  * Returns the compiled regexp or NULL in case of error   * Returns the compiled regexp or NULL in case of error
  */   */
xmlRegexpPtr          xmlRegexpPtr
 xmlAutomataCompile(xmlAutomataPtr am) {  xmlAutomataCompile(xmlAutomataPtr am) {
     xmlRegexpPtr ret;      xmlRegexpPtr ret;
   
Line 6294  xmlAutomataCompile(xmlAutomataPtr am) { Line 6305  xmlAutomataCompile(xmlAutomataPtr am) {
  *   *
  * Returns 1 if true, 0 if not, and -1 in case of error   * Returns 1 if true, 0 if not, and -1 in case of error
  */   */
int          int
 xmlAutomataIsDeterminist(xmlAutomataPtr am) {  xmlAutomataIsDeterminist(xmlAutomataPtr am) {
     int ret;      int ret;
   
Line 6347  xmlExpNewCtxt(int maxNodes, xmlDictPtr dict) { Line 6358  xmlExpNewCtxt(int maxNodes, xmlDictPtr dict) {
   
     if (maxNodes <= 4096)      if (maxNodes <= 4096)
         maxNodes = 4096;          maxNodes = 4096;
    
     ret = (xmlExpCtxtPtr) xmlMalloc(sizeof(xmlExpCtxt));      ret = (xmlExpCtxtPtr) xmlMalloc(sizeof(xmlExpCtxt));
     if (ret == NULL)      if (ret == NULL)
         return(NULL);          return(NULL);
Line 6401  xmlExpFreeCtxt(xmlExpCtxtPtr ctxt) { Line 6412  xmlExpFreeCtxt(xmlExpCtxtPtr ctxt) {
 /* #define DEBUG_DERIV */  /* #define DEBUG_DERIV */
   
 /*  /*
 * TODO:  * TODO:
  * - Wildcards   * - Wildcards
  * - public API for creation   * - public API for creation
  *   *
Line 6469  static unsigned short Line 6480  static unsigned short
 xmlExpHashNameComputeKey(const xmlChar *name) {  xmlExpHashNameComputeKey(const xmlChar *name) {
     unsigned short value = 0L;      unsigned short value = 0L;
     char ch;      char ch;
    
     if (name != NULL) {      if (name != NULL) {
         value += 30 * (*name);          value += 30 * (*name);
         while ((ch = *name++) != 0) {          while ((ch = *name++) != 0) {
Line 6488  xmlExpHashComputeKey(xmlExpNodeType type, xmlExpNodePt Line 6499  xmlExpHashComputeKey(xmlExpNodeType type, xmlExpNodePt
                      xmlExpNodePtr right) {                       xmlExpNodePtr right) {
     unsigned long value;      unsigned long value;
     unsigned short ret;      unsigned short ret;
    
     switch (type) {      switch (type) {
         case XML_EXP_SEQ:          case XML_EXP_SEQ:
             value = left->key;              value = left->key;
Line 6629  xmlExpHashGetEntry(xmlExpCtxtPtr ctxt, xmlExpNodeType  Line 6640  xmlExpHashGetEntry(xmlExpCtxtPtr ctxt, xmlExpNodeType 
             left->exp_left->ref++;              left->exp_left->ref++;
             tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left->exp_left, tmp,              tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left->exp_left, tmp,
                                      NULL, 0, 0);                                       NULL, 0, 0);
        
             xmlExpFree(ctxt, left);              xmlExpFree(ctxt, left);
             return(tmp);              return(tmp);
         }          }
Line 6686  xmlExpHashGetEntry(xmlExpCtxtPtr ctxt, xmlExpNodeType  Line 6697  xmlExpHashGetEntry(xmlExpCtxtPtr ctxt, xmlExpNodeType 
             return(right);              return(right);
         }          }
         kbase = xmlExpHashComputeKey(type, left, right);          kbase = xmlExpHashComputeKey(type, left, right);
    } else     } else
         return(NULL);          return(NULL);
   
     key = kbase % ctxt->size;      key = kbase % ctxt->size;
Line 6827  xmlExpRef(xmlExpNodePtr exp) { Line 6838  xmlExpRef(xmlExpNodePtr exp) {
  * xmlExpNewAtom:   * xmlExpNewAtom:
  * @ctxt: the expression context   * @ctxt: the expression context
  * @name: the atom name   * @name: the atom name
 * @len: the atom name lenght in byte (or -1); * @len: the atom name length in byte (or -1);
  *   *
  * Get the atom associated to this name from that context   * Get the atom associated to this name from that context
  *   *
Line 6927  xmlExpNewRange(xmlExpCtxtPtr ctxt, xmlExpNodePtr subse Line 6938  xmlExpNewRange(xmlExpCtxtPtr ctxt, xmlExpNodePtr subse
  ************************************************************************/   ************************************************************************/
   
 static int  static int
xmlExpGetLanguageInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpGetLanguageInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp,
                      const xmlChar**list, int len, int nb) {                       const xmlChar**list, int len, int nb) {
     int tmp, tmp2;      int tmp, tmp2;
 tail:  tail:
Line 6964  tail: Line 6975  tail:
  * @ctxt: the expression context   * @ctxt: the expression context
  * @exp: the expression   * @exp: the expression
  * @langList: where to store the tokens   * @langList: where to store the tokens
 * @len: the allocated lenght of @list * @len: the allocated length of @list
  *   *
  * Find all the strings used in @exp and store them in @list   * Find all the strings used in @exp and store them in @list
  *   *
Line 6972  tail: Line 6983  tail:
  *         -2 if there is more than @len strings   *         -2 if there is more than @len strings
  */   */
 int  int
xmlExpGetLanguage(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpGetLanguage(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp,
                   const xmlChar**langList, int len) {                    const xmlChar**langList, int len) {
     if ((ctxt == NULL) || (exp == NULL) || (langList == NULL) || (len <= 0))      if ((ctxt == NULL) || (exp == NULL) || (langList == NULL) || (len <= 0))
         return(-1);          return(-1);
Line 6980  xmlExpGetLanguage(xmlExpCtxtPtr ctxt, xmlExpNodePtr ex Line 6991  xmlExpGetLanguage(xmlExpCtxtPtr ctxt, xmlExpNodePtr ex
 }  }
   
 static int  static int
xmlExpGetStartInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpGetStartInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp,
                   const xmlChar**list, int len, int nb) {                    const xmlChar**list, int len, int nb) {
     int tmp, tmp2;      int tmp, tmp2;
 tail:  tail:
Line 7030  tail: Line 7041  tail:
  * @ctxt: the expression context   * @ctxt: the expression context
  * @exp: the expression   * @exp: the expression
  * @tokList: where to store the tokens   * @tokList: where to store the tokens
 * @len: the allocated lenght of @list * @len: the allocated length of @list
  *   *
  * Find all the strings that appears at the start of the languages   * Find all the strings that appears at the start of the languages
  * accepted by @exp and store them in @list. E.g. for (a, b) | c   * accepted by @exp and store them in @list. E.g. for (a, b) | c
Line 7040  tail: Line 7051  tail:
  *         -2 if there is more than @len strings   *         -2 if there is more than @len strings
  */   */
 int  int
xmlExpGetStart(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpGetStart(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp,
                const xmlChar**tokList, int len) {                 const xmlChar**tokList, int len) {
     if ((ctxt == NULL) || (exp == NULL) || (tokList == NULL) || (len <= 0))      if ((ctxt == NULL) || (exp == NULL) || (tokList == NULL) || (len <= 0))
         return(-1);          return(-1);
Line 7737  xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr e Line 7748  xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr e
     xmlFree((xmlChar **) tab);      xmlFree((xmlChar **) tab);
     return(ret);      return(ret);
 }  }
    
 /**  /**
  * xmlExpExpDerive:   * xmlExpExpDerive:
  * @ctxt: the expressions context   * @ctxt: the expressions context
Line 7789  xmlExpExpDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, Line 7800  xmlExpExpDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp,
 int  int
 xmlExpSubsume(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {  xmlExpSubsume(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
     xmlExpNodePtr tmp;      xmlExpNodePtr tmp;
    
     if ((exp == NULL) || (ctxt == NULL) || (sub == NULL))      if ((exp == NULL) || (ctxt == NULL) || (sub == NULL))
         return(-1);          return(-1);
   
Line 7833  xmlExpSubsume(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, x Line 7844  xmlExpSubsume(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, x
   
 /************************************************************************  /************************************************************************
  *                                                                      *   *                                                                      *
 *                      Parsing expression                              * *                      Parsing expression                              *
  *                                                                      *   *                                                                      *
  ************************************************************************/   ************************************************************************/
   
Line 7937  parse_quantifier: Line 7948  parse_quantifier:
         ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL,          ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL,
                                  0, -1);                                   0, -1);
         SKIP_BLANKS          SKIP_BLANKS
    }     }
     return(ret);      return(ret);
 }  }
   
Line 8059  xmlExpDumpInt(xmlBufferPtr buf, xmlExpNodePtr expr, in Line 8070  xmlExpDumpInt(xmlBufferPtr buf, xmlExpNodePtr expr, in
             break;              break;
         case XML_EXP_COUNT: {          case XML_EXP_COUNT: {
             char rep[40];              char rep[40];
            
             c = expr->exp_left;              c = expr->exp_left;
             if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR))              if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR))
                 xmlExpDumpInt(buf, c, 1);                  xmlExpDumpInt(buf, c, 1);

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>