xmlregexp.c revision 8a001f62c195f956c7655df7464ff753b28bc957
14255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/*
24255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * regexp.c: generic and extensible Regular Expression engine
34255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
44255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Basically designed with the purpose of compiling regexps for
54255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * the variety of validation/shemas mechanisms now available in
64255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * XML related specifications thise includes:
74255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *    - XML-1.0 DTD validation
84255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *    - XML Schemas structure part 1
94255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *    - XML Schemas Datatypes part 2 especially Appendix F
104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *    - RELAX-NG/TREX i.e. the counter proposal
114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * See Copyright for the status of this software.
134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Daniel Veillard <veillard@redhat.com>
154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define IN_LIBXML
184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include "libxml.h"
194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef LIBXML_REGEXP_ENABLED
214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <stdio.h>
234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <string.h>
244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/tree.h>
254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/parserInternals.h>
264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/xmlregexp.h>
274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/xmlautomata.h>
284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/xmlunicode.h>
294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/* #define DEBUG_REGEXP_GRAPH  */
314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/* #define DEBUG_REGEXP_EXEC */
324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/* #define DEBUG_PUSH */
334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define ERROR(str) ctxt->error = 1;					\
354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "Regexp: %s: %s\n", str, ctxt->cur)
364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define NEXT ctxt->cur++
374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define CUR (*(ctxt->cur))
384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define NXT(index) (ctxt->cur[index])
394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l)
414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define NEXTL(l) ctxt->cur += l;
424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************
454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 			Datatypes and structures			*
474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/
494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef enum {
514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_EPSILON = 1,
524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_CHARVAL,
534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_RANGES,
544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_SUBREG,
554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_STRING,
564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_ANYCHAR, /* . */
574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_ANYSPACE, /* \s */
584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_NOTSPACE, /* \S */
594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_INITNAME, /* \l */
604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_NOTINITNAME, /* \l */
614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_NAMECHAR, /* \c */
624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_NOTNAMECHAR, /* \C */
634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_DECIMAL, /* \d */
644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_NOTDECIMAL, /* \d */
654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_REALCHAR, /* \w */
664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_NOTREALCHAR, /* \w */
674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_LETTER,
684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_LETTER_UPPERCASE,
694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_LETTER_LOWERCASE,
704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_LETTER_TITLECASE,
714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_LETTER_MODIFIER,
724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_LETTER_OTHERS,
734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_MARK,
744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_MARK_NONSPACING,
754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_MARK_SPACECOMBINING,
764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_MARK_ENCLOSING,
774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_NUMBER,
784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_NUMBER_DECIMAL,
794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_NUMBER_LETTER,
804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_NUMBER_OTHERS,
814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_PUNCT,
824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_PUNCT_CONNECTOR,
834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_PUNCT_DASH,
844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_PUNCT_OPEN,
854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_PUNCT_CLOSE,
864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_PUNCT_INITQUOTE,
874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_PUNCT_FINQUOTE,
884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_PUNCT_OTHERS,
894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_SEPAR,
904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_SEPAR_SPACE,
914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_SEPAR_LINE,
924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_SEPAR_PARA,
934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_SYMBOL,
944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_SYMBOL_MATH,
954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_SYMBOL_CURRENCY,
964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_SYMBOL_MODIFIER,
974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_SYMBOL_OTHERS,
984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_OTHER,
994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_OTHER_CONTROL,
1004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_OTHER_FORMAT,
1014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_OTHER_PRIVATE,
1024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_OTHER_NA,
1034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_BLOCK_NAME
1044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} xmlRegAtomType;
1054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef enum {
1074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_QUANT_EPSILON = 1,
1084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_QUANT_ONCE,
1094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_QUANT_OPT,
1104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_QUANT_MULT,
1114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_QUANT_PLUS,
1127646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    XML_REGEXP_QUANT_ONCEONLY,
1137646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    XML_REGEXP_QUANT_ALL,
1144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_QUANT_RANGE
1154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} xmlRegQuantType;
1164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef enum {
1184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_START_STATE = 1,
1194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_FINAL_STATE,
1204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_TRANS_STATE
1214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} xmlRegStateType;
1224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef enum {
1244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_MARK_NORMAL = 0,
1254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_MARK_START,
1264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    XML_REGEXP_MARK_VISITED
1274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} xmlRegMarkedType;
1284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegRange xmlRegRange;
1304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegRange *xmlRegRangePtr;
1314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegRange {
1334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int neg;
1344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegAtomType type;
1354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int start;
1364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int end;
1374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlChar *blockName;
1384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard};
1394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegAtom xmlRegAtom;
1414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegAtom *xmlRegAtomPtr;
1424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlAutomataState xmlRegState;
1444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegState *xmlRegStatePtr;
1454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegAtom {
1474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int no;
1484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegAtomType type;
1494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegQuantType quant;
1504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int min;
1514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int max;
1524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    void *valuep;
1544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int neg;
1554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int codepoint;
1564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr start;
1574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr stop;
1584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int maxRanges;
1594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int nbRanges;
1604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegRangePtr *ranges;
1614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    void *data;
1624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard};
1634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegCounter xmlRegCounter;
1654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegCounter *xmlRegCounterPtr;
1664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegCounter {
1684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int min;
1694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int max;
1704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard};
1714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegTrans xmlRegTrans;
1734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegTrans *xmlRegTransPtr;
1744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegTrans {
1764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegAtomPtr atom;
1774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int to;
1784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int counter;
1794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int count;
1804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard};
1814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlAutomataState {
1834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStateType type;
1844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegMarkedType mark;
1854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int no;
1864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int maxTrans;
1884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int nbTrans;
1894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegTrans *trans;
1904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard};
1914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlAutomata xmlRegParserCtxt;
1934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegParserCtxt *xmlRegParserCtxtPtr;
1944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlAutomata {
1964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlChar *string;
1974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlChar *cur;
1984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int error;
2004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int neg;
2014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr start;
2034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr end;
2044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr state;
2054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegAtomPtr atom;
2074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int maxAtoms;
2094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int nbAtoms;
2104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegAtomPtr *atoms;
2114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int maxStates;
2134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int nbStates;
2144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr *states;
2154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int maxCounters;
2174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int nbCounters;
2184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegCounter *counters;
2194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard};
2204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegexp {
2224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlChar *string;
2234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int nbStates;
2244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr *states;
2254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int nbAtoms;
2264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegAtomPtr *atoms;
2274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int nbCounters;
2284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegCounter *counters;
2294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard};
2304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegExecRollback xmlRegExecRollback;
2324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegExecRollback *xmlRegExecRollbackPtr;
2334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegExecRollback {
2354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr state;/* the current state */
2364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int index;		/* the index in the input stack */
2374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int nextbranch;	/* the next transition to explore in that state */
2384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int *counts;	/* save the automate state if it has some */
2394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard};
2404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegInputToken xmlRegInputToken;
2424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegInputToken *xmlRegInputTokenPtr;
2434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegInputToken {
2454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlChar *value;
2464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    void *data;
2474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard};
2484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegExecCtxt {
2504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int status;		/* execution status != 0 indicate an error */
2514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int determinist;	/* did we found an inderterministic behaviour */
2524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegexpPtr comp;	/* the compiled regexp */
2534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegExecCallbacks callback;
2544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    void *data;
2554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr state;/* the current state */
2574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int transno;	/* the current transition on that state */
2584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int transcount;	/* the number of char in char counted transitions */
2594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    /*
2614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     * A stack of rollback states
2624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     */
2634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int maxRollbacks;
2644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int nbRollbacks;
2654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegExecRollback *rollbacks;
2664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    /*
2684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     * The state of the automata if any
2694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     */
2704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int *counts;
2714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    /*
2734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     * The input stack
2744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     */
2754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int inputStackMax;
2764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int inputStackNr;
2774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int index;
2784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int *charStack;
2794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    const xmlChar *inputString; /* when operating on characters */
2804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegInputTokenPtr inputStack;/* when operating on strings */
2814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard};
2834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2847646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard#define REGEXP_ALL_COUNTER 0x123456
2857646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard
2864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top);
2874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************
2894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
2904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 			Allocation/Deallocation				*
2914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
2924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/
2934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
2944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
2954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegEpxFromParse:
2964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @ctxt:  the parser context used to build it
2974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
2984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Allocate a new regexp and fill it with the reult from the parser
2994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
3004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new regexp or NULL in case of error
3014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
3024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegexpPtr
3034255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) {
3044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegexpPtr ret;
3054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
3064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret = (xmlRegexpPtr) xmlMalloc(sizeof(xmlRegexp));
3074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ret == NULL)
3084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
3094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    memset(ret, 0, sizeof(xmlRegexp));
3104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->string = ctxt->string;
3114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->string = NULL;
3124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->nbStates = ctxt->nbStates;
3134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->nbStates = 0;
3144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->states = ctxt->states;
3154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->states = NULL;
3164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->nbAtoms = ctxt->nbAtoms;
3174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->nbAtoms = 0;
3184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->atoms = ctxt->atoms;
3194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->atoms = NULL;
3204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->nbCounters = ctxt->nbCounters;
3214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->nbCounters = 0;
3224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->counters = ctxt->counters;
3234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->counters = NULL;
3244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(ret);
3254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
3264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
3274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
3284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegNewParserCtxt:
3294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @string:  the string to parse
3304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
3314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Allocate a new regexp parser context
3324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
3334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new context or NULL in case of error
3344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
3354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegParserCtxtPtr
3364255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewParserCtxt(const xmlChar *string) {
3374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegParserCtxtPtr ret;
3384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
3394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret = (xmlRegParserCtxtPtr) xmlMalloc(sizeof(xmlRegParserCtxt));
3404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ret == NULL)
3414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
3424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    memset(ret, 0, sizeof(xmlRegParserCtxt));
3434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (string != NULL)
3444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ret->string = xmlStrdup(string);
3454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->cur = ret->string;
3464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->neg = 0;
3474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->error = 0;
3484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(ret);
3494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
3504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
3514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
3524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegNewRange:
3534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @ctxt:  the regexp parser context
3544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @neg:  is that negative
3554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @type:  the type of range
3564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @start:  the start codepoint
3574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @end:  the end codepoint
3584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
3594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Allocate a new regexp range
3604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
3614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new range or NULL in case of error
3624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
3634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegRangePtr
3644255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewRange(xmlRegParserCtxtPtr ctxt,
3654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	       int neg, xmlRegAtomType type, int start, int end) {
3664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegRangePtr ret;
3674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
3684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret = (xmlRegRangePtr) xmlMalloc(sizeof(xmlRegRange));
3694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ret == NULL) {
3704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("failed to allocate regexp range");
3714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
3724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
3734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->neg = neg;
3744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->type = type;
3754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->start = start;
3764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->end = end;
3774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(ret);
3784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
3794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
3804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
3814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeRange:
3824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @range:  the regexp range
3834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
3844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp range
3854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
3864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
3874255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeRange(xmlRegRangePtr range) {
3884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (range == NULL)
3894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
3904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
3914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (range->blockName != NULL)
3924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(range->blockName);
3934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFree(range);
3944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
3954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
3964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
3974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegNewAtom:
3984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @ctxt:  the regexp parser context
3994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @type:  the type of atom
4004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
4014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Allocate a new regexp range
4024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
4034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new atom or NULL in case of error
4044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
4054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegAtomPtr
4064255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewAtom(xmlRegParserCtxtPtr ctxt, xmlRegAtomType type) {
4074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegAtomPtr ret;
4084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret = (xmlRegAtomPtr) xmlMalloc(sizeof(xmlRegAtom));
4104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ret == NULL) {
4114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("failed to allocate regexp atom");
4124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
4134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
4144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    memset(ret, 0, sizeof(xmlRegAtom));
4154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->type = type;
4164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->quant = XML_REGEXP_QUANT_ONCE;
4174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->min = 0;
4184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->max = 0;
4194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(ret);
4204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
4214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
4234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeAtom:
4244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @atom:  the regexp atom
4254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
4264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp atom
4274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
4284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
4294255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeAtom(xmlRegAtomPtr atom) {
4304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int i;
4314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom == NULL)
4334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
4344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    for (i = 0;i < atom->nbRanges;i++)
4364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegFreeRange(atom->ranges[i]);
4374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom->ranges != NULL)
4384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(atom->ranges);
4394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom->type == XML_REGEXP_STRING)
4404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(atom->valuep);
4414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFree(atom);
4424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
4434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegStatePtr
4454255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewState(xmlRegParserCtxtPtr ctxt) {
4464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr ret;
4474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret = (xmlRegStatePtr) xmlMalloc(sizeof(xmlRegState));
4494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ret == NULL) {
4504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("failed to allocate regexp state");
4514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
4524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
4534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    memset(ret, 0, sizeof(xmlRegState));
4544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->type = XML_REGEXP_TRANS_STATE;
4554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret->mark = XML_REGEXP_MARK_NORMAL;
4564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(ret);
4574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
4584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
4604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeState:
4614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @state:  the regexp state
4624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
4634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp state
4644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
4654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
4664255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeState(xmlRegStatePtr state) {
4674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (state == NULL)
4684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
4694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (state->trans != NULL)
4714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(state->trans);
4724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFree(state);
4734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
4744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
4764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeParserCtxt:
4774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @ctxt:  the regexp parser context
4784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
4794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp parser context
4804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
4814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
4824255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeParserCtxt(xmlRegParserCtxtPtr ctxt) {
4834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int i;
4844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt == NULL)
4854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
4864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
4874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->string != NULL)
4884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(ctxt->string);
4894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->states != NULL) {
4904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	for (i = 0;i < ctxt->nbStates;i++)
4914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlRegFreeState(ctxt->states[i]);
4924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(ctxt->states);
4934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
4944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->atoms != NULL) {
4954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	for (i = 0;i < ctxt->nbAtoms;i++)
4964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlRegFreeAtom(ctxt->atoms[i]);
4974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(ctxt->atoms);
4984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
4994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->counters != NULL)
5004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(ctxt->counters);
5014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFree(ctxt);
5024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
5034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
5044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************
5054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
5064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 			Display of Data structures			*
5074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
5084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/
5094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
5104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
5114255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintAtomType(FILE *output, xmlRegAtomType type) {
5124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    switch (type) {
5134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_EPSILON:
5144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "epsilon "); break;
5154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_CHARVAL:
5164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "charval "); break;
5174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_RANGES:
5184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "ranges "); break;
5194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SUBREG:
5204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "subexpr "); break;
5214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_STRING:
5224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "string "); break;
5234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_ANYCHAR:
5244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "anychar "); break;
5254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_ANYSPACE:
5264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "anyspace "); break;
5274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTSPACE:
5284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "notspace "); break;
5294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_INITNAME:
5304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "initname "); break;
5314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTINITNAME:
5324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "notinitname "); break;
5334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NAMECHAR:
5344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "namechar "); break;
5354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTNAMECHAR:
5364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "notnamechar "); break;
5374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_DECIMAL:
5384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "decimal "); break;
5394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTDECIMAL:
5404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "notdecimal "); break;
5414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_REALCHAR:
5424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "realchar "); break;
5434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTREALCHAR:
5444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "notrealchar "); break;
5454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER:
5464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "LETTER "); break;
5474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_UPPERCASE:
5484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "LETTER_UPPERCASE "); break;
5494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_LOWERCASE:
5504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "LETTER_LOWERCASE "); break;
5514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_TITLECASE:
5524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "LETTER_TITLECASE "); break;
5534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_MODIFIER:
5544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "LETTER_MODIFIER "); break;
5554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_OTHERS:
5564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "LETTER_OTHERS "); break;
5574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_MARK:
5584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "MARK "); break;
5594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_MARK_NONSPACING:
5604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "MARK_NONSPACING "); break;
5614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_MARK_SPACECOMBINING:
5624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "MARK_SPACECOMBINING "); break;
5634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_MARK_ENCLOSING:
5644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "MARK_ENCLOSING "); break;
5654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NUMBER:
5664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "NUMBER "); break;
5674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NUMBER_DECIMAL:
5684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "NUMBER_DECIMAL "); break;
5694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NUMBER_LETTER:
5704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "NUMBER_LETTER "); break;
5714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NUMBER_OTHERS:
5724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "NUMBER_OTHERS "); break;
5734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT:
5744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "PUNCT "); break;
5754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_CONNECTOR:
5764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "PUNCT_CONNECTOR "); break;
5774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_DASH:
5784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "PUNCT_DASH "); break;
5794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_OPEN:
5804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "PUNCT_OPEN "); break;
5814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_CLOSE:
5824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "PUNCT_CLOSE "); break;
5834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_INITQUOTE:
5844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "PUNCT_INITQUOTE "); break;
5854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_FINQUOTE:
5864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "PUNCT_FINQUOTE "); break;
5874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_OTHERS:
5884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "PUNCT_OTHERS "); break;
5894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SEPAR:
5904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "SEPAR "); break;
5914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SEPAR_SPACE:
5924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "SEPAR_SPACE "); break;
5934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SEPAR_LINE:
5944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "SEPAR_LINE "); break;
5954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SEPAR_PARA:
5964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "SEPAR_PARA "); break;
5974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL:
5984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "SYMBOL "); break;
5994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL_MATH:
6004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "SYMBOL_MATH "); break;
6014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL_CURRENCY:
6024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "SYMBOL_CURRENCY "); break;
6034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL_MODIFIER:
6044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "SYMBOL_MODIFIER "); break;
6054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL_OTHERS:
6064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "SYMBOL_OTHERS "); break;
6074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER:
6084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "OTHER "); break;
6094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER_CONTROL:
6104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "OTHER_CONTROL "); break;
6114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER_FORMAT:
6124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "OTHER_FORMAT "); break;
6134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER_PRIVATE:
6144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "OTHER_PRIVATE "); break;
6154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER_NA:
6164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            fprintf(output, "OTHER_NA "); break;
6174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_BLOCK_NAME:
6184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "BLOCK "); break;
6194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
6204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
6214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
6224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
6234255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintQuantType(FILE *output, xmlRegQuantType type) {
6244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    switch (type) {
6254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_QUANT_EPSILON:
6264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "epsilon "); break;
6274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_QUANT_ONCE:
6284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "once "); break;
6294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_QUANT_OPT:
6304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "? "); break;
6314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_QUANT_MULT:
6324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "* "); break;
6334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_QUANT_PLUS:
6344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "+ "); break;
6354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	case XML_REGEXP_QUANT_RANGE:
6364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(output, "range "); break;
6377646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	case XML_REGEXP_QUANT_ONCEONLY:
6387646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	    fprintf(output, "onceonly "); break;
6397646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	case XML_REGEXP_QUANT_ALL:
6407646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	    fprintf(output, "all "); break;
6414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
6424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
6434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
6444255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintRange(FILE *output, xmlRegRangePtr range) {
6454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "  range: ");
6464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (range->neg)
6474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "negative ");
6484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegPrintAtomType(output, range->type);
6494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "%c - %c\n", range->start, range->end);
6504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
6514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
6524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
6534255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintAtom(FILE *output, xmlRegAtomPtr atom) {
6544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, " atom: ");
6554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom == NULL) {
6564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "NULL\n");
6574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
6584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
6594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegPrintAtomType(output, atom->type);
6604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegPrintQuantType(output, atom->quant);
6614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom->quant == XML_REGEXP_QUANT_RANGE)
6624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "%d-%d ", atom->min, atom->max);
6634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom->type == XML_REGEXP_STRING)
6644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "'%s' ", (char *) atom->valuep);
6654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom->type == XML_REGEXP_CHARVAL)
6664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "char %c\n", atom->codepoint);
6674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    else if (atom->type == XML_REGEXP_RANGES) {
6684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	int i;
6694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "%d entries\n", atom->nbRanges);
6704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	for (i = 0; i < atom->nbRanges;i++)
6714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlRegPrintRange(output, atom->ranges[i]);
6724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (atom->type == XML_REGEXP_SUBREG) {
6734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "start %d end %d\n", atom->start->no, atom->stop->no);
6744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else {
6754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "\n");
6764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
6774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
6784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
6794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
6804255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintTrans(FILE *output, xmlRegTransPtr trans) {
6814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "  trans: ");
6824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (trans == NULL) {
6834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "NULL\n");
6844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
6854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
6864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (trans->to < 0) {
6874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "removed\n");
6884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
6894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
6904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (trans->counter >= 0) {
6914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "counted %d, ", trans->counter);
6924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
6938a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard    if (trans->count == REGEXP_ALL_COUNTER) {
6948a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard	fprintf(output, "all transition, ");
6958a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard    } else if (trans->count >= 0) {
6964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "count based %d, ", trans->count);
6974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
6984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (trans->atom == NULL) {
6994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "epsilon to %d\n", trans->to);
7004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
7014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
7024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (trans->atom->type == XML_REGEXP_CHARVAL)
7034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "char %c ", trans->atom->codepoint);
7044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "atom %d, to %d\n", trans->atom->no, trans->to);
7054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
7064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
7074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
7084255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintState(FILE *output, xmlRegStatePtr state) {
7094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int i;
7104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
7114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, " state: ");
7124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (state == NULL) {
7134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "NULL\n");
7144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
7154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
7164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (state->type == XML_REGEXP_START_STATE)
7174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "START ");
7184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (state->type == XML_REGEXP_FINAL_STATE)
7194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "FINAL ");
7204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
7214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "%d, %d transitions:\n", state->no, state->nbTrans);
7224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    for (i = 0;i < state->nbTrans; i++) {
7234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegPrintTrans(output, &(state->trans[i]));
7244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
7254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
7264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
7274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#if 0
7284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
7294255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintCtxt(FILE *output, xmlRegParserCtxtPtr ctxt) {
7304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int i;
7314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
7324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, " ctxt: ");
7334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt == NULL) {
7344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "NULL\n");
7354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
7364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
7374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "'%s' ", ctxt->string);
7384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->error)
7394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "error ");
7404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->neg)
7414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "neg ");
7424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "\n");
7434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "%d atoms:\n", ctxt->nbAtoms);
7444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    for (i = 0;i < ctxt->nbAtoms; i++) {
7454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, " %02d ", i);
7464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegPrintAtom(output, ctxt->atoms[i]);
7474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
7484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->atom != NULL) {
7494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "current atom:\n");
7504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegPrintAtom(output, ctxt->atom);
7514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
7524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "%d states:", ctxt->nbStates);
7534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->start != NULL)
7544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, " start: %d", ctxt->start->no);
7554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->end != NULL)
7564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, " end: %d", ctxt->end->no);
7574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "\n");
7584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    for (i = 0;i < ctxt->nbStates; i++) {
7594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegPrintState(output, ctxt->states[i]);
7604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
7614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "%d counters:\n", ctxt->nbCounters);
7624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    for (i = 0;i < ctxt->nbCounters; i++) {
7634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, " %d: min %d max %d\n", i, ctxt->counters[i].min,
7644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                                ctxt->counters[i].max);
7654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
7664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
7674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
7684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
7694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************
7704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
7714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *		 Finite Automata structures manipulations		*
7724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
7734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/
7744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
7754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
7764255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom,
7774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	           int neg, xmlRegAtomType type, int start, int end,
7784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		   xmlChar *blockName) {
7794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegRangePtr range;
7804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
7814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom == NULL) {
7824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("add range: atom is NULL");
7834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
7844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
7854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom->type != XML_REGEXP_RANGES) {
7864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("add range: atom is not ranges");
7874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
7884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
7894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom->maxRanges == 0) {
7904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	atom->maxRanges = 4;
7914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	atom->ranges = (xmlRegRangePtr *) xmlMalloc(atom->maxRanges *
7924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                             sizeof(xmlRegRangePtr));
7934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (atom->ranges == NULL) {
7944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("add range: allocation failed");
7954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    atom->maxRanges = 0;
7964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
7974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
7984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (atom->nbRanges >= atom->maxRanges) {
7994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegRangePtr *tmp;
8004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	atom->maxRanges *= 2;
8014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	tmp = (xmlRegRangePtr *) xmlRealloc(atom->ranges, atom->maxRanges *
8024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                             sizeof(xmlRegRangePtr));
8034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (tmp == NULL) {
8044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("add range: allocation failed");
8054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    atom->maxRanges /= 2;
8064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
8074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
8084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	atom->ranges = tmp;
8094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
8104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    range = xmlRegNewRange(ctxt, neg, type, start, end);
8114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (range == NULL)
8124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
8134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    range->blockName = blockName;
8144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    atom->ranges[atom->nbRanges++] = range;
8154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
8164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
8174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
8184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
8194255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegGetCounter(xmlRegParserCtxtPtr ctxt) {
8204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->maxCounters == 0) {
8214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->maxCounters = 4;
8224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->counters = (xmlRegCounter *) xmlMalloc(ctxt->maxCounters *
8234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                             sizeof(xmlRegCounter));
8244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (ctxt->counters == NULL) {
8254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("reg counter: allocation failed");
8264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->maxCounters = 0;
8274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return(-1);
8284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
8294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (ctxt->nbCounters >= ctxt->maxCounters) {
8304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegCounter *tmp;
8314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->maxCounters *= 2;
8324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	tmp = (xmlRegCounter *) xmlRealloc(ctxt->counters, ctxt->maxCounters *
8334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                           sizeof(xmlRegCounter));
8344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (tmp == NULL) {
8354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("reg counter: allocation failed");
8364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->maxCounters /= 2;
8374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return(-1);
8384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
8394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->counters = tmp;
8404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
8414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->counters[ctxt->nbCounters].min = -1;
8424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->counters[ctxt->nbCounters].max = -1;
8434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(ctxt->nbCounters++);
8444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
8454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
8464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
8474255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegAtomPush(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) {
8484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom == NULL) {
8494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("atom push: atom is NULL");
8504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
8514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
8524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->maxAtoms == 0) {
8534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->maxAtoms = 4;
8544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->atoms = (xmlRegAtomPtr *) xmlMalloc(ctxt->maxAtoms *
8554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                             sizeof(xmlRegAtomPtr));
8564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (ctxt->atoms == NULL) {
8574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("atom push: allocation failed");
8584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->maxAtoms = 0;
8594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
8604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
8614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (ctxt->nbAtoms >= ctxt->maxAtoms) {
8624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegAtomPtr *tmp;
8634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->maxAtoms *= 2;
8644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	tmp = (xmlRegAtomPtr *) xmlRealloc(ctxt->atoms, ctxt->maxAtoms *
8654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                             sizeof(xmlRegAtomPtr));
8664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (tmp == NULL) {
8674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("atom push: allocation failed");
8684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->maxAtoms /= 2;
8694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
8704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
8714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->atoms = tmp;
8724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
8734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    atom->no = ctxt->nbAtoms;
8744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->atoms[ctxt->nbAtoms++] = atom;
8754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
8764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
8774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
8784255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
8794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	            xmlRegAtomPtr atom, xmlRegStatePtr target,
8804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    int counter, int count) {
8814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (state == NULL) {
8824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("add state: state is NULL");
8834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
8844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
8854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (target == NULL) {
8864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("add state: target is NULL");
8874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
8884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
8894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (state->maxTrans == 0) {
8904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	state->maxTrans = 4;
8914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	state->trans = (xmlRegTrans *) xmlMalloc(state->maxTrans *
8924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                             sizeof(xmlRegTrans));
8934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (state->trans == NULL) {
8944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("add range: allocation failed");
8954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    state->maxTrans = 0;
8964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
8974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
8984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (state->nbTrans >= state->maxTrans) {
8994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegTrans *tmp;
9004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	state->maxTrans *= 2;
9014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	tmp = (xmlRegTrans *) xmlRealloc(state->trans, state->maxTrans *
9024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                             sizeof(xmlRegTrans));
9034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (tmp == NULL) {
9044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("add range: allocation failed");
9054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    state->maxTrans /= 2;
9064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
9074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
9084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	state->trans = tmp;
9094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
9104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH
9114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    printf("Add trans from %d to %d ", state->no, target->no);
9128a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard    if (count == REGEXP_ALL_COUNTER)
9138a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard	printf("all transition");
9148a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard    else (count >= 0)
9154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	printf("count based %d", count);
9164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    else if (counter >= 0)
9174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	printf("counted %d", counter);
9184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    else if (atom == NULL)
9194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	printf("epsilon transition");
9204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    printf("\n");
9214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
9224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
9234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    state->trans[state->nbTrans].atom = atom;
9244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    state->trans[state->nbTrans].to = target->no;
9254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    state->trans[state->nbTrans].counter = counter;
9264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    state->trans[state->nbTrans].count = count;
9274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    state->nbTrans++;
9284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
9294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
9304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
9314255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegStatePush(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state) {
9324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->maxStates == 0) {
9334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->maxStates = 4;
9344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->states = (xmlRegStatePtr *) xmlMalloc(ctxt->maxStates *
9354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                             sizeof(xmlRegStatePtr));
9364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (ctxt->states == NULL) {
9374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("add range: allocation failed");
9384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->maxStates = 0;
9394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
9404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
9414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (ctxt->nbStates >= ctxt->maxStates) {
9424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegStatePtr *tmp;
9434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->maxStates *= 2;
9444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	tmp = (xmlRegStatePtr *) xmlRealloc(ctxt->states, ctxt->maxStates *
9454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                             sizeof(xmlRegStatePtr));
9464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (tmp == NULL) {
9474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("add range: allocation failed");
9484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->maxStates /= 2;
9494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
9504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
9514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->states = tmp;
9524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
9534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    state->no = ctxt->nbStates;
9544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->states[ctxt->nbStates++] = state;
9554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
9564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
9574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
9587646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * xmlFAGenerateAllTransition:
9597646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * ctxt:  a regexp parser context
9607646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * from:  the from state
9617646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * to:  the target state or NULL for building a new one
9627646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard *
9637646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard */
9647646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillardstatic void
9657646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlFAGenerateAllTransition(xmlRegParserCtxtPtr ctxt,
9667646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard			   xmlRegStatePtr from, xmlRegStatePtr to) {
9677646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    if (to == NULL) {
9687646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	to = xmlRegNewState(ctxt);
9697646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	xmlRegStatePush(ctxt, to);
9707646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	ctxt->state = to;
9717646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    }
9727646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_COUNTER);
9737646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard}
9747646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard
9757646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard/**
9764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAGenerateEpsilonTransition:
9774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
9784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * from:  the from state
9794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * to:  the target state or NULL for building a new one
9804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
9814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
9824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
9834255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAGenerateEpsilonTransition(xmlRegParserCtxtPtr ctxt,
9844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			       xmlRegStatePtr from, xmlRegStatePtr to) {
9854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (to == NULL) {
9864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	to = xmlRegNewState(ctxt);
9874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegStatePush(ctxt, to);
9884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->state = to;
9894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
9904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStateAddTrans(ctxt, from, NULL, to, -1, -1);
9914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
9924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
9934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
9944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAGenerateCountedEpsilonTransition:
9954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
9964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * from:  the from state
9974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * to:  the target state or NULL for building a new one
9984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * counter:  the counter for that transition
9994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
10004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
10014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
10024255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAGenerateCountedEpsilonTransition(xmlRegParserCtxtPtr ctxt,
10034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlRegStatePtr from, xmlRegStatePtr to, int counter) {
10044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (to == NULL) {
10054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	to = xmlRegNewState(ctxt);
10064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegStatePush(ctxt, to);
10074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->state = to;
10084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
10094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStateAddTrans(ctxt, from, NULL, to, counter, -1);
10104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
10114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
10124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
10134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAGenerateCountedTransition:
10144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
10154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * from:  the from state
10164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * to:  the target state or NULL for building a new one
10174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * counter:  the counter for that transition
10184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
10194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
10204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
10214255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAGenerateCountedTransition(xmlRegParserCtxtPtr ctxt,
10224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlRegStatePtr from, xmlRegStatePtr to, int counter) {
10234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (to == NULL) {
10244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	to = xmlRegNewState(ctxt);
10254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegStatePush(ctxt, to);
10264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->state = to;
10274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
10284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStateAddTrans(ctxt, from, NULL, to, -1, counter);
10294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
10304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
10314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
10324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAGenerateTransitions:
10334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
10344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * from:  the from state
10354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * to:  the target state or NULL for building a new one
10364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * atom:  the atom generating the transition
10374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
10384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
10394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
10404255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
10414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	                 xmlRegStatePtr to, xmlRegAtomPtr atom) {
10424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom == NULL) {
10434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("genrate transition: atom == NULL");
10444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
10454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
10464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom->type == XML_REGEXP_SUBREG) {
10474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	/*
10484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 * this is a subexpression handling one should not need to
10494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 * create a new node excep for XML_REGEXP_QUANT_RANGE.
10504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 */
10514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegAtomPush(ctxt, atom);
10524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if ((to != NULL) && (atom->stop != to) &&
10534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    (atom->quant != XML_REGEXP_QUANT_RANGE)) {
10544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /*
10554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	     * Generate an epsilon transition to link to the target
10564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	     */
10574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to);
10584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
10594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	switch (atom->quant) {
10604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case XML_REGEXP_QUANT_OPT:
10614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		atom->quant = XML_REGEXP_QUANT_ONCE;
10624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		xmlFAGenerateEpsilonTransition(ctxt, atom->start, atom->stop);
10634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
10644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case XML_REGEXP_QUANT_MULT:
10654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		atom->quant = XML_REGEXP_QUANT_ONCE;
10664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		xmlFAGenerateEpsilonTransition(ctxt, atom->start, atom->stop);
10674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start);
10684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
10694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case XML_REGEXP_QUANT_PLUS:
10704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		atom->quant = XML_REGEXP_QUANT_ONCE;
10714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start);
10724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
10734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case XML_REGEXP_QUANT_RANGE: {
10744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		int counter;
10754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		xmlRegStatePtr newstate;
10764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
10774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		/*
10784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 * This one is nasty:
10794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 *   1/ register a new counter
10804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 *   2/ register an epsilon transition associated to
10814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 *      this counter going from atom->stop to atom->start
10824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 *   3/ create a new state
10834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 *   4/ generate a counted transition from atom->stop to
10844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 *      that state
10854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 */
10864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		counter = xmlRegGetCounter(ctxt);
10874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ctxt->counters[counter].min = atom->min - 1;
10884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ctxt->counters[counter].max = atom->max - 1;
10894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		atom->min = 0;
10904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		atom->max = 0;
10914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		atom->quant = XML_REGEXP_QUANT_ONCE;
10924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		xmlFAGenerateCountedEpsilonTransition(ctxt, atom->stop,
10934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			                              atom->start, counter);
10944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (to != NULL) {
10954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    newstate = to;
10964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		} else {
10974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    newstate = xmlRegNewState(ctxt);
10984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    xmlRegStatePush(ctxt, newstate);
10994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    ctxt->state = newstate;
11004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
11014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		xmlFAGenerateCountedTransition(ctxt, atom->stop,
11024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			                       newstate, counter);
11034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
11044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    default:
11054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
11064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
11074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
11084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else {
11094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (to == NULL) {
11104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    to = xmlRegNewState(ctxt);
11114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlRegStatePush(ctxt, to);
11124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
11134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegStateAddTrans(ctxt, from, atom, to, -1, -1);
11144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegAtomPush(ctxt, atom);
11154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->state = to;
11164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
11174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    switch (atom->quant) {
11184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	case XML_REGEXP_QUANT_OPT:
11194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    atom->quant = XML_REGEXP_QUANT_ONCE;
11204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFAGenerateEpsilonTransition(ctxt, from, to);
11214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
11224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	case XML_REGEXP_QUANT_MULT:
11234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    atom->quant = XML_REGEXP_QUANT_ONCE;
11244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFAGenerateEpsilonTransition(ctxt, from, to);
11254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1);
11264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
11274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	case XML_REGEXP_QUANT_PLUS:
11284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    atom->quant = XML_REGEXP_QUANT_ONCE;
11294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1);
11304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
11314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	default:
11324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
11334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
11344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
11354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
11364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
11374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAReduceEpsilonTransitions:
11384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
11394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @fromnr:  the from state
11404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @tonr:  the to state
11414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @cpunter:  should that transition be associted to a counted
11424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
11434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
11444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
11454255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int fromnr,
11464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	                      int tonr, int counter) {
11474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int transnr;
11484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr from;
11494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr to;
11504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
11514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH
11524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    printf("xmlFAReduceEpsilonTransitions(%d, %d)\n", fromnr, tonr);
11534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
11544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    from = ctxt->states[fromnr];
11554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (from == NULL)
11564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
11574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    to = ctxt->states[tonr];
11584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (to == NULL)
11594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
11604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if ((to->mark == XML_REGEXP_MARK_START) ||
11614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	(to->mark == XML_REGEXP_MARK_VISITED))
11624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
11634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
11644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    to->mark = XML_REGEXP_MARK_VISITED;
11654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (to->type == XML_REGEXP_FINAL_STATE) {
11664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH
11674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	printf("State %d is final, so %d becomes final\n", tonr, fromnr);
11684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
11694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	from->type = XML_REGEXP_FINAL_STATE;
11704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
11714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    for (transnr = 0;transnr < to->nbTrans;transnr++) {
11724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (to->trans[transnr].atom == NULL) {
11734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /*
11744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	     * Don't remove counted transitions
11754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	     * Don't loop either
11764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	     */
1177b509f1543df71549969eeac076349e05d2f78044Daniel Veillard	    if (to->trans[transnr].to != fromnr) {
1178b509f1543df71549969eeac076349e05d2f78044Daniel Veillard		if (to->trans[transnr].count >= 0) {
1179b509f1543df71549969eeac076349e05d2f78044Daniel Veillard		    int newto = to->trans[transnr].to;
1180b509f1543df71549969eeac076349e05d2f78044Daniel Veillard
1181b509f1543df71549969eeac076349e05d2f78044Daniel Veillard		    xmlRegStateAddTrans(ctxt, from, NULL,
1182b509f1543df71549969eeac076349e05d2f78044Daniel Veillard					ctxt->states[newto],
1183b509f1543df71549969eeac076349e05d2f78044Daniel Veillard					-1, to->trans[transnr].count);
1184b509f1543df71549969eeac076349e05d2f78044Daniel Veillard		} else {
11854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH
1186b509f1543df71549969eeac076349e05d2f78044Daniel Veillard		    printf("Found epsilon trans %d from %d to %d\n",
1187b509f1543df71549969eeac076349e05d2f78044Daniel Veillard			   transnr, tonr, to->trans[transnr].to);
11884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
1189b509f1543df71549969eeac076349e05d2f78044Daniel Veillard		    if (to->trans[transnr].counter >= 0) {
1190b509f1543df71549969eeac076349e05d2f78044Daniel Veillard			xmlFAReduceEpsilonTransitions(ctxt, fromnr,
1191b509f1543df71549969eeac076349e05d2f78044Daniel Veillard					      to->trans[transnr].to,
1192b509f1543df71549969eeac076349e05d2f78044Daniel Veillard					      to->trans[transnr].counter);
1193b509f1543df71549969eeac076349e05d2f78044Daniel Veillard		    } else {
1194b509f1543df71549969eeac076349e05d2f78044Daniel Veillard			xmlFAReduceEpsilonTransitions(ctxt, fromnr,
1195b509f1543df71549969eeac076349e05d2f78044Daniel Veillard					      to->trans[transnr].to,
1196b509f1543df71549969eeac076349e05d2f78044Daniel Veillard					      counter);
1197b509f1543df71549969eeac076349e05d2f78044Daniel Veillard		    }
1198b509f1543df71549969eeac076349e05d2f78044Daniel Veillard		}
11994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
12004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
12014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    int newto = to->trans[transnr].to;
12024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
1203b509f1543df71549969eeac076349e05d2f78044Daniel Veillard	    if (to->trans[transnr].counter >= 0) {
1204b509f1543df71549969eeac076349e05d2f78044Daniel Veillard		xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom,
1205b509f1543df71549969eeac076349e05d2f78044Daniel Veillard				    ctxt->states[newto],
1206b509f1543df71549969eeac076349e05d2f78044Daniel Veillard				    to->trans[transnr].counter, -1);
1207b509f1543df71549969eeac076349e05d2f78044Daniel Veillard	    } else {
1208b509f1543df71549969eeac076349e05d2f78044Daniel Veillard		xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom,
1209b509f1543df71549969eeac076349e05d2f78044Daniel Veillard				    ctxt->states[newto], counter, -1);
1210b509f1543df71549969eeac076349e05d2f78044Daniel Veillard	    }
1211b509f1543df71549969eeac076349e05d2f78044Daniel Veillard
12124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
12134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
12144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    to->mark = XML_REGEXP_MARK_NORMAL;
12154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
12164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
12174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
12184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAEliminateEpsilonTransitions:
12194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
12204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
12214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
12224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
12234255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAEliminateEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
12244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int statenr, transnr;
12254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr state;
12264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
12274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    /*
12284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     * build the completed transitions bypassing the epsilons
12294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     * Use a marking algorithm to avoid loops
12304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     */
12314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
12324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	state = ctxt->states[statenr];
12334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (state == NULL)
12344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    continue;
12354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	for (transnr = 0;transnr < state->nbTrans;transnr++) {
12364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if ((state->trans[transnr].atom == NULL) &&
12374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		(state->trans[transnr].to >= 0)) {
12384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (state->trans[transnr].to == statenr) {
12394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    state->trans[transnr].to = -1;
12404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH
12414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    printf("Removed loopback epsilon trans %d on %d\n",
12424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			   transnr, statenr);
12434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
12444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		} else if (state->trans[transnr].count < 0) {
12454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    int newto = state->trans[transnr].to;
12464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
12474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH
12484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    printf("Found epsilon trans %d from %d to %d\n",
12494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			   transnr, statenr, newto);
12504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
12514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    state->mark = XML_REGEXP_MARK_START;
12524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    xmlFAReduceEpsilonTransitions(ctxt, statenr,
12534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard				      newto, state->trans[transnr].counter);
12544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    state->mark = XML_REGEXP_MARK_NORMAL;
12554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH
12564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		} else {
12574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    printf("Found counted transition %d on %d\n",
12584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			   transnr, statenr);
12594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
12604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	        }
12614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
12624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
12634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
12644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    /*
12654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     * Eliminate the epsilon transitions
12664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     */
12674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
12684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	state = ctxt->states[statenr];
12694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (state == NULL)
12704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    continue;
12714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	for (transnr = 0;transnr < state->nbTrans;transnr++) {
12724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if ((state->trans[transnr].atom == NULL) &&
12734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		(state->trans[transnr].count < 0) &&
12744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		(state->trans[transnr].to >= 0)) {
12754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		state->trans[transnr].to = -1;
12764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
12774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
12784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
12794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
12804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
12814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************
12824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
12834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *	Routines to check input against transition atoms		*
12844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
12854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/
12864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
12874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
12884255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, int neg,
12894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	                  int start, int end, const xmlChar *blockName) {
12904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int ret = 0;
12914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
12924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    switch (type) {
12934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_STRING:
12944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SUBREG:
12954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_RANGES:
12964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_EPSILON:
12974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return(-1);
12984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_ANYCHAR:
12994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = ((codepoint != '\n') && (codepoint != '\r'));
13004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_CHARVAL:
13024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = ((codepoint >= start) && (codepoint <= end));
13034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTSPACE:
13054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    neg = !neg;
13064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_ANYSPACE:
13074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = ((codepoint == '\n') || (codepoint == '\r') ||
13084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		   (codepoint == '\t') || (codepoint == ' '));
13094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTINITNAME:
13114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    neg = !neg;
13124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_INITNAME:
13134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = (xmlIsLetter(codepoint) ||
13144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		   (codepoint == '_') || (codepoint == ':'));
13154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTNAMECHAR:
13174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    neg = !neg;
13184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NAMECHAR:
13194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = (xmlIsLetter(codepoint) || xmlIsDigit(codepoint) ||
13204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		   (codepoint == '.') || (codepoint == '-') ||
13214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		   (codepoint == '_') || (codepoint == ':') ||
13224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		   xmlIsCombining(codepoint) || xmlIsExtender(codepoint));
13234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTDECIMAL:
13254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    neg = !neg;
13264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_DECIMAL:
13274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatNd(codepoint);
13284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_REALCHAR:
13304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    neg = !neg;
13314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTREALCHAR:
13324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatP(codepoint);
13334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (ret == 0)
13344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ret = xmlUCSIsCatZ(codepoint);
13354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (ret == 0)
13364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ret = xmlUCSIsCatC(codepoint);
13374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER:
13394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatL(codepoint);
13404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_UPPERCASE:
13424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatLu(codepoint);
13434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_LOWERCASE:
13454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatLl(codepoint);
13464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_TITLECASE:
13484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatLt(codepoint);
13494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_MODIFIER:
13514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatLm(codepoint);
13524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_OTHERS:
13544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatLo(codepoint);
13554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_MARK:
13574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatM(codepoint);
13584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_MARK_NONSPACING:
13604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatMn(codepoint);
13614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_MARK_SPACECOMBINING:
13634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatMc(codepoint);
13644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_MARK_ENCLOSING:
13664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatMe(codepoint);
13674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NUMBER:
13694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatN(codepoint);
13704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NUMBER_DECIMAL:
13724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatNd(codepoint);
13734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NUMBER_LETTER:
13754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatNl(codepoint);
13764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NUMBER_OTHERS:
13784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatNo(codepoint);
13794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT:
13814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatP(codepoint);
13824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_CONNECTOR:
13844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatPc(codepoint);
13854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_DASH:
13874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatPd(codepoint);
13884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_OPEN:
13904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatPs(codepoint);
13914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_CLOSE:
13934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatPe(codepoint);
13944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_INITQUOTE:
13964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatPi(codepoint);
13974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
13984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_FINQUOTE:
13994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatPf(codepoint);
14004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_OTHERS:
14024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatPo(codepoint);
14034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SEPAR:
14054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatZ(codepoint);
14064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SEPAR_SPACE:
14084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatZs(codepoint);
14094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SEPAR_LINE:
14114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatZl(codepoint);
14124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SEPAR_PARA:
14144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatZp(codepoint);
14154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL:
14174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatS(codepoint);
14184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL_MATH:
14204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatSm(codepoint);
14214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL_CURRENCY:
14234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatSc(codepoint);
14244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL_MODIFIER:
14264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatSk(codepoint);
14274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL_OTHERS:
14294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatSo(codepoint);
14304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER:
14324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatC(codepoint);
14334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER_CONTROL:
14354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatCc(codepoint);
14364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER_FORMAT:
14384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatCf(codepoint);
14394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER_PRIVATE:
14414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsCatCo(codepoint);
14424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER_NA:
14444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* ret = xmlUCSIsCatCn(codepoint); */
14454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* Seems it doesn't exist anymore in recent Unicode releases */
14464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = 0;
14474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_BLOCK_NAME:
14494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlUCSIsBlock(codepoint, (const char *) blockName);
14504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
14514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
14524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (neg)
14534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(!ret);
14544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(ret);
14554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
14564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
14574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
14584255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint) {
14594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int i, ret = 0;
14604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegRangePtr range;
14614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
14624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if ((atom == NULL) || (!xmlIsChar(codepoint)))
14634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(-1);
14644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
14654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    switch (atom->type) {
14664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SUBREG:
14674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_EPSILON:
14684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return(-1);
14694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_CHARVAL:
14704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard            return(codepoint == atom->codepoint);
14714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_RANGES: {
14724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    int accept = 0;
14734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    for (i = 0;i < atom->nbRanges;i++) {
14744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		range = atom->ranges[i];
14754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (range->neg) {
14764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    ret = xmlRegCheckCharacterRange(range->type, codepoint,
14774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard						0, range->start, range->end,
14784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard						range->blockName);
14794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (ret != 0)
14804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			return(0); /* excluded char */
14814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		} else {
14824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    ret = xmlRegCheckCharacterRange(range->type, codepoint,
14834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard						0, range->start, range->end,
14844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard						range->blockName);
14854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (ret != 0)
14864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			accept = 1; /* might still be excluded */
14874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
14884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
14894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return(accept);
14904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
14914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_STRING:
14924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    printf("TODO: XML_REGEXP_STRING\n");
14934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return(-1);
14944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_ANYCHAR:
14954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_ANYSPACE:
14964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTSPACE:
14974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_INITNAME:
14984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTINITNAME:
14994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NAMECHAR:
15004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTNAMECHAR:
15014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_DECIMAL:
15024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTDECIMAL:
15034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_REALCHAR:
15044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NOTREALCHAR:
15054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER:
15064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_UPPERCASE:
15074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_LOWERCASE:
15084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_TITLECASE:
15094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_MODIFIER:
15104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_LETTER_OTHERS:
15114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_MARK:
15124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_MARK_NONSPACING:
15134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_MARK_SPACECOMBINING:
15144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_MARK_ENCLOSING:
15154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NUMBER:
15164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NUMBER_DECIMAL:
15174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NUMBER_LETTER:
15184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_NUMBER_OTHERS:
15194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT:
15204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_CONNECTOR:
15214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_DASH:
15224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_OPEN:
15234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_CLOSE:
15244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_INITQUOTE:
15254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_FINQUOTE:
15264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_PUNCT_OTHERS:
15274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SEPAR:
15284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SEPAR_SPACE:
15294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SEPAR_LINE:
15304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SEPAR_PARA:
15314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL:
15324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL_MATH:
15334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL_CURRENCY:
15344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL_MODIFIER:
15354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_SYMBOL_OTHERS:
15364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER:
15374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER_CONTROL:
15384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER_FORMAT:
15394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER_PRIVATE:
15404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        case XML_REGEXP_OTHER_NA:
15414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	case XML_REGEXP_BLOCK_NAME:
15424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = xmlRegCheckCharacterRange(atom->type, codepoint, 0, 0, 0,
15434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                            (const xmlChar *)atom->valuep);
15444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (atom->neg)
15454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ret = !ret;
15464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
15474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
15484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(ret);
15494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
15504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
15514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************
15524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
15534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *	Saving an restoring state of an execution context		*
15544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
15554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/
15564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
15574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC
15584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
15594255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegDebugExec(xmlRegExecCtxtPtr exec) {
15604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    printf("state: %d:%d:idx %d", exec->state->no, exec->transno, exec->index);
15614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->inputStack != NULL) {
15624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	int i;
15634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	printf(": ");
15644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	for (i = 0;(i < 3) && (i < exec->inputStackNr);i++)
15654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    printf("%s ", exec->inputStack[exec->inputStackNr - (i + 1)]);
15664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else {
15674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	printf(": %s", &(exec->inputString[exec->index]));
15684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
15694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    printf("\n");
15704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
15714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
15724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
15734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
15744255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegExecSave(xmlRegExecCtxtPtr exec) {
15754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC
15764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    printf("saving ");
15774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->transno++;
15784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFARegDebugExec(exec);
15794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->transno--;
15804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
15814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
15824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->maxRollbacks == 0) {
15834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->maxRollbacks = 4;
15844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->rollbacks = (xmlRegExecRollback *) xmlMalloc(exec->maxRollbacks *
15854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                             sizeof(xmlRegExecRollback));
15864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (exec->rollbacks == NULL) {
15874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(stderr, "exec save: allocation failed");
15884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    exec->maxRollbacks = 0;
15894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
15904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
15914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	memset(exec->rollbacks, 0,
15924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	       exec->maxRollbacks * sizeof(xmlRegExecRollback));
15934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (exec->nbRollbacks >= exec->maxRollbacks) {
15944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegExecRollback *tmp;
15954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	int len = exec->maxRollbacks;
15964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
15974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->maxRollbacks *= 2;
15984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	tmp = (xmlRegExecRollback *) xmlRealloc(exec->rollbacks,
15994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			exec->maxRollbacks * sizeof(xmlRegExecRollback));
16004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (tmp == NULL) {
16014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(stderr, "exec save: allocation failed");
16024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    exec->maxRollbacks /= 2;
16034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
16044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
16054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->rollbacks = tmp;
16064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	tmp = &exec->rollbacks[len];
16074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	memset(tmp, 0, (exec->maxRollbacks - len) * sizeof(xmlRegExecRollback));
16084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
16094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->rollbacks[exec->nbRollbacks].state = exec->state;
16104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->rollbacks[exec->nbRollbacks].index = exec->index;
16114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->rollbacks[exec->nbRollbacks].nextbranch = exec->transno + 1;
16124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->comp->nbCounters > 0) {
16134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
16144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    exec->rollbacks[exec->nbRollbacks].counts = (int *)
16154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		xmlMalloc(exec->comp->nbCounters * sizeof(int));
16164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
16174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		fprintf(stderr, "exec save: allocation failed");
16184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		exec->status = -5;
16194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		return;
16204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
16214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
16224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	memcpy(exec->rollbacks[exec->nbRollbacks].counts, exec->counts,
16234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	       exec->comp->nbCounters * sizeof(int));
16244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
16254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->nbRollbacks++;
16264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
16274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
16284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
16294255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegExecRollBack(xmlRegExecCtxtPtr exec) {
16304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->nbRollbacks <= 0) {
16314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->status = -1;
16324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC
16334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	printf("rollback failed on empty stack\n");
16344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
16354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
16364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
16374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->nbRollbacks--;
16384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->state = exec->rollbacks[exec->nbRollbacks].state;
16394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->index = exec->rollbacks[exec->nbRollbacks].index;
16404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->transno = exec->rollbacks[exec->nbRollbacks].nextbranch;
16414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->comp->nbCounters > 0) {
16424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
16434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(stderr, "exec save: allocation failed");
16444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    exec->status = -6;
16454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
16464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
16474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	memcpy(exec->counts, exec->rollbacks[exec->nbRollbacks].counts,
16484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	       exec->comp->nbCounters * sizeof(int));
16494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
16504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
16514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC
16524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    printf("restored ");
16534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFARegDebugExec(exec);
16544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
16554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
16564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
16574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************
16584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
16594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *	Verifyer, running an input against a compiled regexp		*
16604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
16614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/
16624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
16634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
16644255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
16654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegExecCtxt execval;
16664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegExecCtxtPtr exec = &execval;
16674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int ret, codepoint, len;
16684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
16694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->inputString = content;
16704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->index = 0;
16714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->determinist = 1;
16724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->maxRollbacks = 0;
16734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->nbRollbacks = 0;
16744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->rollbacks = NULL;
16754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->status = 0;
16764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->comp = comp;
16774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->state = comp->states[0];
16784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->transno = 0;
16794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->transcount = 0;
16804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (comp->nbCounters > 0) {
16814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int));
16824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (exec->counts == NULL)
16834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return(-1);
16844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        memset(exec->counts, 0, comp->nbCounters * sizeof(int));
16854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else
16864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->counts = NULL;
16874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    while ((exec->status == 0) &&
16884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	   ((exec->inputString[exec->index] != 0) ||
16894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    (exec->state->type != XML_REGEXP_FINAL_STATE))) {
16904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegTransPtr trans;
16914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegAtomPtr atom;
16924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
16934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	/*
16944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 * End of input on non-terminal state, rollback, however we may
16954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 * still have epsilon like transition for counted transitions
16964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 * on counters, in that case don't break too early.
16974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 */
16984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL))
16994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    goto rollback;
17004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
17014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->transcount = 0;
17024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	for (;exec->transno < exec->state->nbTrans;exec->transno++) {
17034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    trans = &exec->state->trans[exec->transno];
17044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (trans->to < 0)
17054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		continue;
17064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    atom = trans->atom;
17074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = 0;
17084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (trans->count >= 0) {
17094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		int count;
17104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		xmlRegCounterPtr counter;
17114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
17124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		/*
17134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 * A counted transition.
17144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 */
17154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
17164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		count = exec->counts[trans->count];
17174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		counter = &exec->comp->counters[trans->count];
17184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC
17194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		printf("testing count %d: val %d, min %d, max %d\n",
17204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		       trans->count, count, counter->min,  counter->max);
17214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
17224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ret = ((count >= counter->min) && (count <= counter->max));
17234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    } else if (atom == NULL) {
17244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		fprintf(stderr, "epsilon transition left at runtime\n");
17254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		exec->status = -2;
17264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
17274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    } else if (exec->inputString[exec->index] != 0) {
17284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard                codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len);
17294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ret = xmlRegCheckCharacter(atom, codepoint);
17304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) {
17314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    xmlRegStatePtr to = comp->states[trans->to];
17324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
17334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    /*
17344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     * this is a multiple input sequence
17354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     */
17364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (exec->state->nbTrans > exec->transno + 1) {
17374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			xmlFARegExecSave(exec);
17384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    }
17394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    exec->transcount = 1;
17404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    do {
17414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			/*
17424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 * Try to progress as much as possible on the input
17434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 */
17444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			if (exec->transcount == atom->max) {
17454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    break;
17464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			}
17474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			exec->index += len;
17484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			/*
17494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 * End of input: stop here
17504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 */
17514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			if (exec->inputString[exec->index] == 0) {
17524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->index -= len;
17534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    break;
17544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			}
17554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			if (exec->transcount >= atom->min) {
17564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    int transno = exec->transno;
17574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    xmlRegStatePtr state = exec->state;
17584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
17594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    /*
17604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			     * The transition is acceptable save it
17614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			     */
17624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->transno = -1; /* trick */
17634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->state = to;
17644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    xmlFARegExecSave(exec);
17654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->transno = transno;
17664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->state = state;
17674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			}
17684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			codepoint = CUR_SCHAR(&(exec->inputString[exec->index]),
17694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard				              len);
17704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			ret = xmlRegCheckCharacter(atom, codepoint);
17714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			exec->transcount++;
17724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    } while (ret == 1);
17734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (exec->transcount < atom->min)
17744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			ret = 0;
17754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
17764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    /*
17774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     * If the last check failed but one transition was found
17784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     * possible, rollback
17794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     */
17804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (ret < 0)
17814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			ret = 0;
17824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (ret == 0) {
17834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			goto rollback;
17844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    }
17854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
17864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
17874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (ret == 1) {
17884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (exec->state->nbTrans > exec->transno + 1) {
17894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    xmlFARegExecSave(exec);
17904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
17914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (trans->counter >= 0) {
17924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC
17934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    printf("Increasing count %d\n", trans->counter);
17944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
17954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    exec->counts[trans->counter]++;
17964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
17974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC
17984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		printf("entering state %d\n", trans->to);
17994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
18004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		exec->state = comp->states[trans->to];
18014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		exec->transno = 0;
18024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (trans->atom != NULL) {
18034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    exec->index += len;
18044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
18054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		goto progress;
18064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    } else if (ret < 0) {
18074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		exec->status = -4;
18084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
18094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
18104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
18114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if ((exec->transno != 0) || (exec->state->nbTrans == 0)) {
18124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardrollback:
18134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /*
18144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	     * Failed to find a way out
18154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	     */
18164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    exec->determinist = 0;
18174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFARegExecRollBack(exec);
18184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
18194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardprogress:
18204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	continue;
18214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
18224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->rollbacks != NULL) {
18234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (exec->counts != NULL) {
18244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    int i;
18254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
18264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    for (i = 0;i < exec->maxRollbacks;i++)
18274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (exec->rollbacks[i].counts != NULL)
18284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    xmlFree(exec->rollbacks[i].counts);
18294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
18304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(exec->rollbacks);
18314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
18324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->counts != NULL)
18334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(exec->counts);
18344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->status == 0)
18354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(1);
18364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->status == -1)
18374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(0);
18384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(exec->status);
18394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
18404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
18414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************
18424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
18434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *	Progressive interface to the verifyer one atom at a time	*
18444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
18454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/
18464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
18474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
18484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegExecCtxtPtr:
18494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @comp: a precompiled regular expression
18504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @callback: a callback function used for handling progresses in the
18514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *            automata matching phase
18524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @data: the context data associated to the callback in this context
18534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
18544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Build a context used for progressive evaluation of a regexp.
18554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
18564255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegExecCtxtPtr
18574255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewExecCtxt(xmlRegexpPtr comp, xmlRegExecCallbacks callback, void *data) {
18584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegExecCtxtPtr exec;
18594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
18604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (comp == NULL)
18614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
18624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec = (xmlRegExecCtxtPtr) xmlMalloc(sizeof(xmlRegExecCtxt));
18634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec == NULL) {
18644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
18654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
18664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    memset(exec, 0, sizeof(xmlRegExecCtxt));
18674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->inputString = NULL;
18684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->index = 0;
18694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->determinist = 1;
18704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->maxRollbacks = 0;
18714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->nbRollbacks = 0;
18724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->rollbacks = NULL;
18734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->status = 0;
18744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->comp = comp;
18754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->state = comp->states[0];
18764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->transno = 0;
18774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->transcount = 0;
18784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->callback = callback;
18794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->data = data;
18804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (comp->nbCounters > 0) {
18814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int));
18824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (exec->counts == NULL) {
18834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFree(exec);
18844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return(NULL);
18854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
18864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        memset(exec->counts, 0, comp->nbCounters * sizeof(int));
18874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else
18884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->counts = NULL;
18894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->inputStackMax = 0;
18904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->inputStackNr = 0;
18914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->inputStack = NULL;
18924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(exec);
18934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
18944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
18954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
18964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeExecCtxt:
18974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @exec: a regular expression evaulation context
18984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
18994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free the structures associated to a regular expression evaulation context.
19004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
19014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid
19024255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeExecCtxt(xmlRegExecCtxtPtr exec) {
19034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec == NULL)
19044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
19054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
19064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->rollbacks != NULL) {
19074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (exec->counts != NULL) {
19084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    int i;
19094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
19104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    for (i = 0;i < exec->maxRollbacks;i++)
19114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (exec->rollbacks[i].counts != NULL)
19124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    xmlFree(exec->rollbacks[i].counts);
19134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
19144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(exec->rollbacks);
19154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
19164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->counts != NULL)
19174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(exec->counts);
19184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->inputStack != NULL) {
19194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	int i;
19204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
19214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	for (i = 0;i < exec->inputStackNr;i++)
19224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFree(exec->inputStack[i].value);
19234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(exec->inputStack);
19244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
19254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFree(exec);
19264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
19274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
19284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
19294255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegExecSaveInputString(xmlRegExecCtxtPtr exec, const xmlChar *value,
19304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	                    void *data) {
19314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH
19324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    printf("saving value: %d:%s\n", exec->inputStackNr, value);
19334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
19344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->inputStackMax == 0) {
19354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->inputStackMax = 4;
19364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->inputStack = (xmlRegInputTokenPtr)
19374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlMalloc(exec->inputStackMax * sizeof(xmlRegInputToken));
19384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (exec->inputStack == NULL) {
19394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(stderr, "push input: allocation failed");
19404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    exec->inputStackMax = 0;
19414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
19424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
19434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (exec->inputStackNr + 1 >= exec->inputStackMax) {
19444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegInputTokenPtr tmp;
19454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
19464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->inputStackMax *= 2;
19474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	tmp = (xmlRegInputTokenPtr) xmlRealloc(exec->inputStack,
19484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			exec->inputStackMax * sizeof(xmlRegInputToken));
19494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (tmp == NULL) {
19504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    fprintf(stderr, "push input: allocation failed");
19514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    exec->inputStackMax /= 2;
19524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
19534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
19544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->inputStack = tmp;
19554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
19564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->inputStack[exec->inputStackNr].value = xmlStrdup(value);
19574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->inputStack[exec->inputStackNr].data = data;
19584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->inputStackNr++;
19594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->inputStack[exec->inputStackNr].value = NULL;
19604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    exec->inputStack[exec->inputStackNr].data = NULL;
19614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
19624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
19634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
19644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
19654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegExecPushString:
19664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @exec: a regexp execution context
19674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @value: a string token input
19684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @data: data associated to the token to reuse in callbacks
19694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
19704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Push one input token in the execution context
19714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
19724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns: 1 if the regexp reached a final state, 0 if non-final, and
19734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *     a negative value in case of error.
19744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
19754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardint
19764255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegExecPushString(xmlRegExecCtxtPtr exec, const xmlChar *value,
19774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	             void *data) {
19784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegTransPtr trans;
19794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegAtomPtr atom;
19804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int ret;
19814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int final = 0;
19824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
19834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec == NULL)
19844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(-1);
19854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->status != 0)
19864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(exec->status);
19874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
19884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (value == NULL) {
19894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        if (exec->state->type == XML_REGEXP_FINAL_STATE)
19904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return(1);
19914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	final = 1;
19924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
19934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
19944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH
19954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    printf("value pushed: %s\n", value);
19964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
19974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    /*
19984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     * If we have an active rollback stack push the new value there
19994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     * and get back to where we were left
20004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard     */
20014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if ((value != NULL) && (exec->inputStackNr > 0)) {
20024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFARegExecSaveInputString(exec, value, data);
20034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	value = exec->inputStack[exec->index].value;
20044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	data = exec->inputStack[exec->index].data;
20054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH
20064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	printf("value loaded: %s\n", value);
20074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
20084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
20094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
20104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    while ((exec->status == 0) &&
20114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	   ((value != NULL) ||
20124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ((final == 1) &&
20134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	     (exec->state->type != XML_REGEXP_FINAL_STATE)))) {
20144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
20154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	/*
20164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 * End of input on non-terminal state, rollback, however we may
20174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 * still have epsilon like transition for counted transitions
20184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 * on counters, in that case don't break too early.
20194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 */
2020b509f1543df71549969eeac076349e05d2f78044Daniel Veillard	if ((value == NULL) && (exec->counts == NULL))
20214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    goto rollback;
20224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
20234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->transcount = 0;
20244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	for (;exec->transno < exec->state->nbTrans;exec->transno++) {
20254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    trans = &exec->state->trans[exec->transno];
20264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (trans->to < 0)
20274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		continue;
20284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    atom = trans->atom;
20294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = 0;
20308a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard	    if (trans->count == REGEXP_ALL_COUNTER) {
20318a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		int i;
20328a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		int count;
20338a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		xmlRegTransPtr t;
20348a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		xmlRegCounterPtr counter;
20358a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard
20368a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		ret = 1;
20378a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard
20388a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard#ifdef DEBUG_PUSH
20398a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		printf("testing all %d\n", trans->count);
20408a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard#endif
20418a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		/*
20428a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		 * Check all counted transitions from the current state
20438a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		 */
20448a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		for (i = 0;i < exec->state->nbTrans;i++) {
20458a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard                    t = &exec->state->trans[i];
20468a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		    if ((t->counter < 0) || (t == trans))
20478a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard			continue;
20488a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard                    counter = &exec->comp->counters[t->counter];
20498a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		    count = exec->counts[t->counter];
20508a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		    if ((count < counter->min) || (count > counter->max)) {
20518a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard			ret = 0;
20528a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard			break;
20538a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		    }
20548a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard		}
20558a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard	    } else if (trans->count >= 0) {
20564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		int count;
20574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		xmlRegCounterPtr counter;
20584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
20594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		/*
20604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 * A counted transition.
20614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 */
20624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
20634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		count = exec->counts[trans->count];
20644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		counter = &exec->comp->counters[trans->count];
20654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH
20664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		printf("testing count %d: val %d, min %d, max %d\n",
20674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		       trans->count, count, counter->min,  counter->max);
20684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
20694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ret = ((count >= counter->min) && (count <= counter->max));
20704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    } else if (atom == NULL) {
20714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		fprintf(stderr, "epsilon transition left at runtime\n");
20724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		exec->status = -2;
20734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
20744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    } else if (value != NULL) {
20754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ret = xmlStrEqual(value, atom->valuep);
20764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) {
20774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    xmlRegStatePtr to = exec->comp->states[trans->to];
20784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
20794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    /*
20804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     * this is a multiple input sequence
20814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     */
20824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (exec->state->nbTrans > exec->transno + 1) {
20834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			if (exec->inputStackNr <= 0) {
20844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    xmlFARegExecSaveInputString(exec, value, data);
20854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			}
20864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			xmlFARegExecSave(exec);
20874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    }
20884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    exec->transcount = 1;
20894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    do {
20904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			/*
20914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 * Try to progress as much as possible on the input
20924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 */
20934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			if (exec->transcount == atom->max) {
20944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    break;
20954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			}
20964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			exec->index++;
20974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			value = exec->inputStack[exec->index].value;
20984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			data = exec->inputStack[exec->index].data;
20994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH
21004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			printf("value loaded: %s\n", value);
21014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
21024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
21034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			/*
21044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 * End of input: stop here
21054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 */
21064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			if (value == NULL) {
21074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->index --;
21084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    break;
21094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			}
21104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			if (exec->transcount >= atom->min) {
21114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    int transno = exec->transno;
21124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    xmlRegStatePtr state = exec->state;
21134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
21144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    /*
21154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			     * The transition is acceptable save it
21164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			     */
21174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->transno = -1; /* trick */
21184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->state = to;
21194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    if (exec->inputStackNr <= 0) {
21204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard				xmlFARegExecSaveInputString(exec, value, data);
21214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    }
21224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    xmlFARegExecSave(exec);
21234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->transno = transno;
21244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->state = state;
21254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			}
21264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			ret = xmlStrEqual(value, atom->valuep);
21274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			exec->transcount++;
21284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    } while (ret == 1);
21294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (exec->transcount < atom->min)
21304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			ret = 0;
21314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
21324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    /*
21334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     * If the last check failed but one transition was found
21344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     * possible, rollback
21354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     */
21364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (ret < 0)
21374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			ret = 0;
21384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (ret == 0) {
21394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			goto rollback;
21404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    }
21414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
21424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
21434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (ret == 1) {
21444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if ((exec->callback != NULL) && (atom != NULL)) {
21454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    exec->callback(exec->data, atom->valuep,
21464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			           atom->data, data);
21474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
21484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (exec->state->nbTrans > exec->transno + 1) {
21494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (exec->inputStackNr <= 0) {
21504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			xmlFARegExecSaveInputString(exec, value, data);
21514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    }
21524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    xmlFARegExecSave(exec);
21534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
21544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (trans->counter >= 0) {
21554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH
21564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    printf("Increasing count %d\n", trans->counter);
21574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
21584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    exec->counts[trans->counter]++;
21594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
21604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH
21614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		printf("entering state %d\n", trans->to);
21624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
21634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		exec->state = exec->comp->states[trans->to];
21644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		exec->transno = 0;
21654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (trans->atom != NULL) {
21664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (exec->inputStack != NULL) {
21674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			exec->index++;
21684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			if (exec->index < exec->inputStackNr) {
21694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    value = exec->inputStack[exec->index].value;
21704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    data = exec->inputStack[exec->index].data;
21714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH
21724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    printf("value loaded: %s\n", value);
21734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
21744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			} else {
21754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    value = NULL;
21764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    data = NULL;
21774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH
21784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    printf("end of input\n");
21794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
21804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			}
21814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    } else {
21824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			value = NULL;
21834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			data = NULL;
21844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH
21854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			printf("end of input\n");
21864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
21874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    }
21884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
21894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		goto progress;
21904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    } else if (ret < 0) {
21914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		exec->status = -4;
21924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
21934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
21944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
21954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if ((exec->transno != 0) || (exec->state->nbTrans == 0)) {
21964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardrollback:
21974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /*
21984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	     * Failed to find a way out
21994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	     */
22004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    exec->determinist = 0;
22014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFARegExecRollBack(exec);
22024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (exec->status == 0) {
22034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		value = exec->inputStack[exec->index].value;
22044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		data = exec->inputStack[exec->index].data;
22054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH
22064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		printf("value loaded: %s\n", value);
22074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
22084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
22094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
22104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardprogress:
22114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	continue;
22124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
22134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->status == 0) {
22144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        return(exec->state->type == XML_REGEXP_FINAL_STATE);
22154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
22164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(exec->status);
22174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
22184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
22194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#if 0
22204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
22214255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegExecPushChar(xmlRegExecCtxtPtr exec, int UCS) {
22224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegTransPtr trans;
22234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegAtomPtr atom;
22244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int ret;
22254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int codepoint, len;
22264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
22274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec == NULL)
22284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(-1);
22294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (exec->status != 0)
22304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(exec->status);
22314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
22324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    while ((exec->status == 0) &&
22334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	   ((exec->inputString[exec->index] != 0) ||
22344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    (exec->state->type != XML_REGEXP_FINAL_STATE))) {
22354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
22364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	/*
22374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 * End of input on non-terminal state, rollback, however we may
22384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 * still have epsilon like transition for counted transitions
22394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 * on counters, in that case don't break too early.
22404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	 */
22414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL))
22424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    goto rollback;
22434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
22444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	exec->transcount = 0;
22454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	for (;exec->transno < exec->state->nbTrans;exec->transno++) {
22464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    trans = &exec->state->trans[exec->transno];
22474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (trans->to < 0)
22484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		continue;
22494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    atom = trans->atom;
22504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ret = 0;
22514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (trans->count >= 0) {
22524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		int count;
22534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		xmlRegCounterPtr counter;
22544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
22554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		/*
22564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 * A counted transition.
22574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		 */
22584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
22594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		count = exec->counts[trans->count];
22604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		counter = &exec->comp->counters[trans->count];
22614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC
22624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		printf("testing count %d: val %d, min %d, max %d\n",
22634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		       trans->count, count, counter->min,  counter->max);
22644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
22654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ret = ((count >= counter->min) && (count <= counter->max));
22664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    } else if (atom == NULL) {
22674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		fprintf(stderr, "epsilon transition left at runtime\n");
22684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		exec->status = -2;
22694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
22704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    } else if (exec->inputString[exec->index] != 0) {
22714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard                codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len);
22724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ret = xmlRegCheckCharacter(atom, codepoint);
22734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) {
22744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    xmlRegStatePtr to = exec->comp->states[trans->to];
22754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
22764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    /*
22774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     * this is a multiple input sequence
22784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     */
22794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (exec->state->nbTrans > exec->transno + 1) {
22804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			xmlFARegExecSave(exec);
22814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    }
22824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    exec->transcount = 1;
22834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    do {
22844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			/*
22854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 * Try to progress as much as possible on the input
22864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 */
22874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			if (exec->transcount == atom->max) {
22884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    break;
22894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			}
22904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			exec->index += len;
22914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			/*
22924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 * End of input: stop here
22934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 */
22944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			if (exec->inputString[exec->index] == 0) {
22954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->index -= len;
22964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    break;
22974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			}
22984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			if (exec->transcount >= atom->min) {
22994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    int transno = exec->transno;
23004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    xmlRegStatePtr state = exec->state;
23014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
23024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    /*
23034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			     * The transition is acceptable save it
23044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			     */
23054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->transno = -1; /* trick */
23064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->state = to;
23074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    xmlFARegExecSave(exec);
23084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->transno = transno;
23094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			    exec->state = state;
23104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			}
23114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			codepoint = CUR_SCHAR(&(exec->inputString[exec->index]),
23124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard				              len);
23134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			ret = xmlRegCheckCharacter(atom, codepoint);
23144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			exec->transcount++;
23154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    } while (ret == 1);
23164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (exec->transcount < atom->min)
23174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			ret = 0;
23184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
23194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    /*
23204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     * If the last check failed but one transition was found
23214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     * possible, rollback
23224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		     */
23234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (ret < 0)
23244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			ret = 0;
23254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    if (ret == 0) {
23264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			goto rollback;
23274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    }
23284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
23294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
23304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (ret == 1) {
23314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (exec->state->nbTrans > exec->transno + 1) {
23324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    xmlFARegExecSave(exec);
23334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
23344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (trans->counter >= 0) {
23354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC
23364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    printf("Increasing count %d\n", trans->counter);
23374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
23384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    exec->counts[trans->counter]++;
23394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
23404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC
23414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		printf("entering state %d\n", trans->to);
23424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
23434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		exec->state = exec->comp->states[trans->to];
23444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		exec->transno = 0;
23454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if (trans->atom != NULL) {
23464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    exec->index += len;
23474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		}
23484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		goto progress;
23494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    } else if (ret < 0) {
23504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		exec->status = -4;
23514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
23524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
23534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
23544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if ((exec->transno != 0) || (exec->state->nbTrans == 0)) {
23554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardrollback:
23564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /*
23574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	     * Failed to find a way out
23584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	     */
23594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    exec->determinist = 0;
23604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFARegExecRollBack(exec);
23614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
23624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardprogress:
23634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	continue;
23644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
23654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
23664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif
23674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************
23684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
23694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *	Parser for the Shemas Datatype Regular Expressions		*
23704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *	http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#regexs	*
23714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
23724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/
23734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
23744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
23754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAIsChar:
23764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
23774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
23784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [10]   Char   ::=   [^.\?*+()|#x5B#x5D]
23794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
23804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
23814255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAIsChar(xmlRegParserCtxtPtr ctxt) {
23824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int cur;
23834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int len;
23844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
23854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    cur = CUR_SCHAR(ctxt->cur, len);
23864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if ((cur == '.') || (cur == '\\') || (cur == '?') ||
23874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	(cur == '*') || (cur == '+') || (cur == '(') ||
23884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	(cur == ')') || (cur == '|') || (cur == 0x5B) ||
23894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	(cur == 0x5D) || (cur == 0))
23904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(-1);
23914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(cur);
23924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
23934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
23944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
23954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharProp:
23964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
23974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
23984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [27]   charProp   ::=   IsCategory | IsBlock
23994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [28]   IsCategory ::= Letters | Marks | Numbers | Punctuation |
24004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *                       Separators | Symbols | Others
24014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [29]   Letters   ::=   'L' [ultmo]?
24024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [30]   Marks   ::=   'M' [nce]?
24034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [31]   Numbers   ::=   'N' [dlo]?
24044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [32]   Punctuation   ::=   'P' [cdseifo]?
24054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [33]   Separators   ::=   'Z' [slp]?
24064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [34]   Symbols   ::=   'S' [mcko]?
24074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [35]   Others   ::=   'C' [cfon]?
24084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [36]   IsBlock   ::=   'Is' [a-zA-Z0-9#x2D]+
24094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
24104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
24114255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) {
24124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int cur;
24134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegAtomType type = 0;
24144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlChar *blockName = NULL;
24154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
24164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    cur = CUR;
24174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (cur == 'L') {
24184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
24194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	cur = CUR;
24204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (cur == 'u') {
24214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_LETTER_UPPERCASE;
24234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'l') {
24244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_LETTER_LOWERCASE;
24264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 't') {
24274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_LETTER_TITLECASE;
24294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'm') {
24304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_LETTER_MODIFIER;
24324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'o') {
24334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_LETTER_OTHERS;
24354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
24364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_LETTER;
24374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
24384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (cur == 'M') {
24394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
24404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	cur = CUR;
24414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (cur == 'n') {
24424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* nonspacing */
24444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_MARK_NONSPACING;
24454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'c') {
24464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* spacing combining */
24484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_MARK_SPACECOMBINING;
24494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'e') {
24504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* enclosing */
24524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_MARK_ENCLOSING;
24534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
24544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* all marks */
24554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_MARK;
24564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
24574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (cur == 'N') {
24584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
24594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	cur = CUR;
24604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (cur == 'd') {
24614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* digital */
24634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_NUMBER_DECIMAL;
24644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'l') {
24654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* letter */
24674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_NUMBER_LETTER;
24684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'o') {
24694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* other */
24714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_NUMBER_OTHERS;
24724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
24734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* all numbers */
24744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_NUMBER;
24754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
24764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (cur == 'P') {
24774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
24784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	cur = CUR;
24794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (cur == 'c') {
24804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* connector */
24824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_PUNCT_CONNECTOR;
24834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'd') {
24844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* dash */
24864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_PUNCT_DASH;
24874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 's') {
24884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* open */
24904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_PUNCT_OPEN;
24914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'e') {
24924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* close */
24944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_PUNCT_CLOSE;
24954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'i') {
24964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
24974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* initial quote */
24984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_PUNCT_INITQUOTE;
24994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'f') {
25004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* final quote */
25024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_PUNCT_FINQUOTE;
25034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'o') {
25044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* other */
25064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_PUNCT_OTHERS;
25074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
25084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* all punctuation */
25094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_PUNCT;
25104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
25114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (cur == 'Z') {
25124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
25134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	cur = CUR;
25144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (cur == 's') {
25154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* space */
25174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_SEPAR_SPACE;
25184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'l') {
25194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* line */
25214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_SEPAR_LINE;
25224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'p') {
25234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* paragraph */
25254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_SEPAR_PARA;
25264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
25274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* all separators */
25284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_SEPAR;
25294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
25304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (cur == 'S') {
25314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
25324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	cur = CUR;
25334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (cur == 'm') {
25344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_SYMBOL_MATH;
25364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* math */
25374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'c') {
25384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_SYMBOL_CURRENCY;
25404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* currency */
25414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'k') {
25424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_SYMBOL_MODIFIER;
25444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* modifiers */
25454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'o') {
25464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_SYMBOL_OTHERS;
25484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* other */
25494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
25504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* all symbols */
25514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_SYMBOL;
25524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
25534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (cur == 'C') {
25544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
25554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	cur = CUR;
25564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (cur == 'c') {
25574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* control */
25594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_OTHER_CONTROL;
25604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'f') {
25614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* format */
25634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_OTHER_FORMAT;
25644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'o') {
25654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* private use */
25674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_OTHER_PRIVATE;
25684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (cur == 'n') {
25694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* not assigned */
25714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_OTHER_NA;
25724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
25734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    /* all others */
25744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    type = XML_REGEXP_OTHER;
25754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
25764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (cur == 'I') {
25774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	const xmlChar *start;
25784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
25794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	cur = CUR;
25804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (cur != 's') {
25814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("IsXXXX expected");
25824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
25834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
25844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
25854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	start = ctxt->cur;
25864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	cur = CUR;
25874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (((cur >= 'a') && (cur <= 'z')) ||
25884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ((cur >= 'A') && (cur <= 'Z')) ||
25894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ((cur >= '0') && (cur <= '9')) ||
25904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    (cur == 0x2D)) {
25914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
25924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    cur = CUR;
25934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    while (((cur >= 'a') && (cur <= 'z')) ||
25944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		((cur >= 'A') && (cur <= 'Z')) ||
25954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		((cur >= '0') && (cur <= '9')) ||
25964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		(cur == 0x2D)) {
25974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		NEXT;
25984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		cur = CUR;
25994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
26004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
26014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	type = XML_REGEXP_BLOCK_NAME;
26024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	blockName = xmlStrndup(start, ctxt->cur - start);
26034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else {
26044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("Unknown char property");
26054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
26064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
26074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->atom == NULL) {
26084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->atom = xmlRegNewAtom(ctxt, type);
26094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (ctxt->atom != NULL)
26104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->atom->valuep = blockName;
26114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (ctxt->atom->type == XML_REGEXP_RANGES) {
26124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
26134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		           type, 0, 0, blockName);
26144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
26154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
26164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
26174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
26184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharClassEsc:
26194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
26204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
26214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [23] charClassEsc ::= ( SingleCharEsc | MultiCharEsc | catEsc | complEsc )
26224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [24] SingleCharEsc ::= '\' [nrt\|.?*+(){}#x2D#x5B#x5D#x5E]
26234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [25] catEsc   ::=   '\p{' charProp '}'
26244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [26] complEsc ::=   '\P{' charProp '}'
26254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [37] MultiCharEsc ::= '.' | ('\' [sSiIcCdDwW])
26264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
26274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
26284255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharClassEsc(xmlRegParserCtxtPtr ctxt) {
26294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int cur;
26304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
26314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (CUR == '.') {
26324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (ctxt->atom == NULL) {
26334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_ANYCHAR);
26344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (ctxt->atom->type == XML_REGEXP_RANGES) {
26354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
26364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			       XML_REGEXP_ANYCHAR, 0, 0, NULL);
26374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
26384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
26394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
26404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
26414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (CUR != '\\') {
26424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("Escaped sequence: expecting \\");
26434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
26444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
26454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    NEXT;
26464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    cur = CUR;
26474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (cur == 'p') {
26484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
26494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (CUR != '{') {
26504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("Expecting '{'");
26514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
26524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
26534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
26544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFAParseCharProp(ctxt);
26554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (CUR != '}') {
26564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("Expecting '}'");
26574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
26584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
26594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
26604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (cur == 'P') {
26614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
26624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (CUR != '{') {
26634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("Expecting '{'");
26644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
26654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
26664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
26674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFAParseCharProp(ctxt);
26684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->atom->neg = 1;
26694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (CUR != '}') {
26704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("Expecting '}'");
26714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
26724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
26734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
26744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if ((cur == 'n') || (cur == 'r') || (cur == 't') || (cur == '\\') ||
26754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	(cur == '|') || (cur == '.') || (cur == '?') || (cur == '*') ||
26764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	(cur == '+') || (cur == '(') || (cur == ')') || (cur == '{') ||
26774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	(cur == '}') || (cur == 0x2D) || (cur == 0x5B) || (cur == 0x5D) ||
26784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	(cur == 0x5E)) {
26794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (ctxt->atom == NULL) {
26804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL);
26814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (ctxt->atom != NULL)
26824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ctxt->atom->codepoint = cur;
26834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (ctxt->atom->type == XML_REGEXP_RANGES) {
26844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
26854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			       XML_REGEXP_CHARVAL, cur, cur, NULL);
26864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
26874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
26884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if ((cur == 's') || (cur == 'S') || (cur == 'i') || (cur == 'I') ||
26894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	(cur == 'c') || (cur == 'C') || (cur == 'd') || (cur == 'D') ||
26904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	(cur == 'w') || (cur == 'W')) {
2691b509f1543df71549969eeac076349e05d2f78044Daniel Veillard	xmlRegAtomType type = XML_REGEXP_ANYSPACE;
26924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
26934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	switch (cur) {
26944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 's':
26954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		type = XML_REGEXP_ANYSPACE;
26964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
26974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 'S':
26984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		type = XML_REGEXP_NOTSPACE;
26994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
27004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 'i':
27014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		type = XML_REGEXP_INITNAME;
27024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
27034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 'I':
27044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		type = XML_REGEXP_NOTINITNAME;
27054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
27064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 'c':
27074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		type = XML_REGEXP_NAMECHAR;
27084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
27094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 'C':
27104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		type = XML_REGEXP_NOTNAMECHAR;
27114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
27124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 'd':
27134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		type = XML_REGEXP_DECIMAL;
27144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
27154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 'D':
27164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		type = XML_REGEXP_NOTDECIMAL;
27174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
27184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 'w':
27194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		type = XML_REGEXP_REALCHAR;
27204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
27214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 'W':
27224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		type = XML_REGEXP_NOTREALCHAR;
27234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
27244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
27254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
27264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (ctxt->atom == NULL) {
27274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->atom = xmlRegNewAtom(ctxt, type);
27284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (ctxt->atom->type == XML_REGEXP_RANGES) {
27294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
27304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			       type, 0, 0, NULL);
27314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
27324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
27334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
27344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
27354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
27364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharRef:
27374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
27384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
27394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [19]   XmlCharRef   ::=   ( '&#' [0-9]+ ';' ) | (' &#x' [0-9a-fA-F]+ ';' )
27404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
27414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
27424255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharRef(xmlRegParserCtxtPtr ctxt) {
27434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int ret = 0, cur;
27444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
27454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if ((CUR != '&') || (NXT(1) != '#'))
27464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(-1);
27474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    NEXT;
27484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    NEXT;
27494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    cur = CUR;
27504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (cur == 'x') {
27514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
27524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	cur = CUR;
27534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (((cur >= '0') && (cur <= '9')) ||
27544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ((cur >= 'a') && (cur <= 'f')) ||
27554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ((cur >= 'A') && (cur <= 'F'))) {
27564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    while (((cur >= '0') && (cur <= '9')) ||
27574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		   ((cur >= 'A') && (cur <= 'F'))) {
27584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		if ((cur >= '0') && (cur <= '9'))
27594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    ret = ret * 16 + cur - '0';
27604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		else if ((cur >= 'a') && (cur <= 'f'))
27614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    ret = ret * 16 + 10 + (cur - 'a');
27624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		else
27634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		    ret = ret * 16 + 10 + (cur - 'A');
27644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		NEXT;
27654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		cur = CUR;
27664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
27674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
27684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("Char ref: expecting [0-9A-F]");
27694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return(-1);
27704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
27714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else {
27724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if ((cur >= '0') && (cur <= '9')) {
27734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    while ((cur >= '0') && (cur <= '9')) {
27744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ret = ret * 10 + cur - '0';
27754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		NEXT;
27764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		cur = CUR;
27774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
27784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
27794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("Char ref: expecting [0-9]");
27804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return(-1);
27814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
27824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
27834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (cur != ';') {
27844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("Char ref: expecting ';'");
27854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(-1);
27864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else {
27874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
27884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
27894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(ret);
27904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
27914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
27924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
27934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharRange:
27944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
27954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
27964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [17]   charRange   ::=     seRange | XmlCharRef | XmlCharIncDash
27974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [18]   seRange   ::=   charOrEsc '-' charOrEsc
27984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [20]   charOrEsc   ::=   XmlChar | SingleCharEsc
27994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [21]   XmlChar   ::=   [^\#x2D#x5B#x5D]
28004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [22]   XmlCharIncDash   ::=   [^\#x5B#x5D]
28014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
28024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
28034255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharRange(xmlRegParserCtxtPtr ctxt) {
28044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int cur;
28054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int start = -1;
28064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int end = -1;
28074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
28084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if ((CUR == '&') && (NXT(1) == '#')) {
28094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	end = start = xmlFAParseCharRef(ctxt);
28104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
28114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	                   XML_REGEXP_CHARVAL, start, end, NULL);
28124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
28134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
28144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    cur = CUR;
28154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (cur == '\\') {
28164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
28174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	cur = CUR;
28184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	switch (cur) {
28194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 'n': start = 0xA; break;
28204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 'r': start = 0xD; break;
28214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 't': start = 0x9; break;
28224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case '\\': case '|': case '.': case '-': case '^': case '?':
28234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case '*': case '+': case '{': case '}': case '(': case ')':
28244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case '[': case ']':
28254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		start = cur; break;
28264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    default:
28274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ERROR("Invalid escape value");
28284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		return;
28294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
28304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	end = start;
28314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if ((cur != 0x5B) && (cur != 0x5D)) {
28324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	end = start = cur;
28334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else {
28344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("Expecting a char range");
28354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
28364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
28374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    NEXT;
28384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (start == '-') {
28394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
28404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
28414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    cur = CUR;
28424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (cur != '-') {
28434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
28444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		              XML_REGEXP_CHARVAL, start, end, NULL);
28454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
28464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
28474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    NEXT;
28484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    cur = CUR;
28494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (cur == '\\') {
28504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
28514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	cur = CUR;
28524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	switch (cur) {
28534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 'n': end = 0xA; break;
28544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 'r': end = 0xD; break;
28554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case 't': end = 0x9; break;
28564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case '\\': case '|': case '.': case '-': case '^': case '?':
28574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case '*': case '+': case '{': case '}': case '(': case ')':
28584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    case '[': case ']':
28594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		end = cur; break;
28604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    default:
28614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ERROR("Invalid escape value");
28624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		return;
28634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
28644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if ((cur != 0x5B) && (cur != 0x5D)) {
28654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	end = cur;
28664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else {
28674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("Expecting the end of a char range");
28684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
28694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
28704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    NEXT;
28714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    /* TODO check that the values are acceptable character ranges for XML */
28724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (end < start) {
28734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("End of range is before start of range");
28744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else {
28754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard        xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
28764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		           XML_REGEXP_CHARVAL, start, end, NULL);
28774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
28784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return;
28794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
28804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
28814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
28824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParsePosCharGroup:
28834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
28844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
28854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [14]   posCharGroup ::= ( charRange | charClassEsc  )+
28864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
28874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
28884255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParsePosCharGroup(xmlRegParserCtxtPtr ctxt) {
28894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    do {
28904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if ((CUR == '\\') || (CUR == '.')) {
28914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFAParseCharClassEsc(ctxt);
28924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
28934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFAParseCharRange(ctxt);
28944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
28954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } while ((CUR != ']') && (CUR != '^') && (CUR != '-') &&
28964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	     (ctxt->error == 0));
28974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
28984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
28994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
29004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharGroup:
29014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
29024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
29034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [13]   charGroup    ::= posCharGroup | negCharGroup | charClassSub
29044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [15]   negCharGroup ::= '^' posCharGroup
29054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [16]   charClassSub ::= ( posCharGroup | negCharGroup ) '-' charClassExpr
29064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [12]   charClassExpr ::= '[' charGroup ']'
29074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
29084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
29094255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharGroup(xmlRegParserCtxtPtr ctxt) {
29104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int n = ctxt->neg;
29114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    while ((CUR != ']') && (ctxt->error == 0)) {
29124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (CUR == '^') {
29134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    int neg = ctxt->neg;
29144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
29154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
29164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->neg = !ctxt->neg;
29174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFAParsePosCharGroup(ctxt);
29184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->neg = neg;
29194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (CUR == '-') {
29204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
29214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->neg = !ctxt->neg;
29224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (CUR != '[') {
29234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ERROR("charClassExpr: '[' expected");
29244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
29254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
29264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
29274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFAParseCharGroup(ctxt);
29284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (CUR == ']') {
29294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		NEXT;
29304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    } else {
29314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ERROR("charClassExpr: ']' expected");
29324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		break;
29334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
29344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    break;
29354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else if (CUR != ']') {
29364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFAParsePosCharGroup(ctxt);
29374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
29384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
29394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->neg = n;
29404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
29414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
29424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
29434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharClass:
29444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
29454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
29464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [11]   charClass   ::=     charClassEsc | charClassExpr
29474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [12]   charClassExpr   ::=   '[' charGroup ']'
29484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
29494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
29504255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharClass(xmlRegParserCtxtPtr ctxt) {
29514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (CUR == '[') {
29524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
29534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_RANGES);
29544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (ctxt->atom == NULL)
29554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return;
29564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFAParseCharGroup(ctxt);
29574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (CUR == ']') {
29584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
29594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
29604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("xmlFAParseCharClass: ']' expected");
29614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
29624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else {
29634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFAParseCharClassEsc(ctxt);
29644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
29654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
29664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
29674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
29684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseQuantExact:
29694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
29704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
29714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [8]   QuantExact   ::=   [0-9]+
29724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
29734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
29744255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseQuantExact(xmlRegParserCtxtPtr ctxt) {
29754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int ret = 0;
29764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int ok = 0;
29774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
29784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    while ((CUR >= '0') && (CUR <= '9')) {
29794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ret = ret * 10 + (CUR - '0');
29804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ok = 1;
29814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
29824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
29834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ok != 1) {
29844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(-1);
29854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
29864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(ret);
29874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
29884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
29894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
29904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseQuantifier:
29914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
29924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
29934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [4]   quantifier   ::=   [?*+] | ( '{' quantity '}' )
29944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [5]   quantity   ::=   quantRange | quantMin | QuantExact
29954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [6]   quantRange   ::=   QuantExact ',' QuantExact
29964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [7]   quantMin   ::=   QuantExact ','
29974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [8]   QuantExact   ::=   [0-9]+
29984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
29994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
30004255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseQuantifier(xmlRegParserCtxtPtr ctxt) {
30014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int cur;
30024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
30034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    cur = CUR;
30044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if ((cur == '?') || (cur == '*') || (cur == '+')) {
30054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (ctxt->atom != NULL) {
30064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (cur == '?')
30074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ctxt->atom->quant = XML_REGEXP_QUANT_OPT;
30084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    else if (cur == '*')
30094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ctxt->atom->quant = XML_REGEXP_QUANT_MULT;
30104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    else if (cur == '+')
30114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		ctxt->atom->quant = XML_REGEXP_QUANT_PLUS;
30124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
30134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
30144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(1);
30154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
30164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (cur == '{') {
30174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	int min = 0, max = 0;
30184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
30194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
30204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	cur = xmlFAParseQuantExact(ctxt);
30214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (cur >= 0)
30224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    min = cur;
30234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (CUR == ',') {
30244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
30254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    cur = xmlFAParseQuantExact(ctxt);
30264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (cur >= 0)
30274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		max = cur;
30284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
30294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (CUR == '}') {
30304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
30314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
30324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("Unterminated quantifier");
30334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
30344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (max == 0)
30354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    max = min;
30364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (ctxt->atom != NULL) {
30374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->atom->quant = XML_REGEXP_QUANT_RANGE;
30384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->atom->min = min;
30394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->atom->max = max;
30404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
30414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(1);
30424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
30434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(0);
30444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
30454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
30464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
30474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseAtom:
30484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
30494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
30504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [9]   atom   ::=   Char | charClass | ( '(' regExp ')' )
30514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
30524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
30534255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseAtom(xmlRegParserCtxtPtr ctxt) {
30544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int codepoint, len;
30554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
30564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    codepoint = xmlFAIsChar(ctxt);
30574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (codepoint > 0) {
30584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL);
30594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (ctxt->atom == NULL)
30604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return(-1);
30614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	codepoint = CUR_SCHAR(ctxt->cur, len);
30624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->atom->codepoint = codepoint;
30634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXTL(len);
30644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(1);
30654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (CUR == '|') {
30664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(0);
30674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (CUR == 0) {
30684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(0);
30694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (CUR == ')') {
30704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(0);
30714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if (CUR == '(') {
30724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegStatePtr start, oldend;
30734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
30744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
30754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, NULL);
30764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	start = ctxt->state;
30774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	oldend = ctxt->end;
30784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->end = NULL;
30794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->atom = NULL;
30804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFAParseRegExp(ctxt, 0);
30814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (CUR == ')') {
30824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    NEXT;
30834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
30844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ERROR("xmlFAParseAtom: expecting ')'");
30854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
30864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_SUBREG);
30874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (ctxt->atom == NULL)
30884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    return(-1);
30894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->atom->start = start;
30904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->atom->stop = ctxt->state;
30914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->end = oldend;
30924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(1);
30934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    } else if ((CUR == '[') || (CUR == '\\') || (CUR == '.')) {
30944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFAParseCharClass(ctxt);
30954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(1);
30964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
30974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(0);
30984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
30994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
31004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
31014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParsePiece:
31024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
31034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
31044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [3]   piece   ::=   atom quantifier?
31054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
31064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int
31074255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParsePiece(xmlRegParserCtxtPtr ctxt) {
31084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int ret;
31094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
31104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->atom = NULL;
31114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret = xmlFAParseAtom(ctxt);
31124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ret == 0)
31134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(0);
31144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->atom == NULL) {
31154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("internal: no atom generated");
31164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
31174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFAParseQuantifier(ctxt);
31184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(1);
31194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
31204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
31214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
31224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseBranch:
31234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
31244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * first:  is taht the first
31254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
31264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [2]   branch   ::=   piece*
31274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
31284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
31294255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseBranch(xmlRegParserCtxtPtr ctxt, int first) {
31304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr previous;
31314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegAtomPtr prevatom = NULL;
31324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int ret;
31334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
31344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    previous = ctxt->state;
31354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret = xmlFAParsePiece(ctxt);
31364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ret != 0) {
31374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (first) {
31384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlFAGenerateTransitions(ctxt, previous, NULL, ctxt->atom);
31394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    previous = ctxt->state;
31404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	} else {
31414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    prevatom = ctxt->atom;
31424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
31434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->atom = NULL;
31444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
31454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    while ((ret != 0) && (ctxt->error == 0)) {
31464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ret = xmlFAParsePiece(ctxt);
31474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	if (ret != 0) {
31484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    if (first) {
31494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		xmlFAGenerateTransitions(ctxt, previous, NULL, ctxt->atom);
31504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    } else {
31514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		xmlFAGenerateTransitions(ctxt, previous, NULL, prevatom);
31524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		prevatom = ctxt->atom;
31534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    }
31544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    previous = ctxt->state;
31554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    ctxt->atom = NULL;
31564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	}
31574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
31584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (!first) {
31594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFAGenerateTransitions(ctxt, previous, ctxt->end, prevatom);
31604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
31614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
31624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
31634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
31644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseRegExp:
31654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * ctxt:  a regexp parser context
31664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * top:  is that the top-level expressions ?
31674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
31684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [1]   regExp   ::=     branch  ( '|' branch )*
31694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
31704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void
31714255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) {
31724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePtr start, end, oldend;
31734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
31744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    oldend = ctxt->end;
31754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
31764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    start = ctxt->state;
31774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFAParseBranch(ctxt, (ctxt->end == NULL));
31784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (CUR != '|') {
31794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->end = ctxt->state;
31804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
31814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
31824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    end = ctxt->state;
31834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    while ((CUR == '|') && (ctxt->error == 0)) {
31844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	NEXT;
31854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->state = start;
31864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->end = end;
31874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFAParseBranch(ctxt, 0);
31884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
31894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (!top)
31904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ctxt->end = oldend;
31914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
31924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
31934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************
31944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
31954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 			The basic API					*
31964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
31974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/
31984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
31994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
32004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegexpPrint:
32014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @output: the file for the output debug
32024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @regexp: the compiled regexp
32034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
32044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Print the content of the compiled regular expression
32054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
32064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid
32074255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpPrint(FILE *output, xmlRegexpPtr regexp) {
32084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int i;
32094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
32104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, " regexp: ");
32114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (regexp == NULL) {
32124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, "NULL\n");
32134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
32144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
32154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "'%s' ", regexp->string);
32164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "\n");
32174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "%d atoms:\n", regexp->nbAtoms);
32184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    for (i = 0;i < regexp->nbAtoms; i++) {
32194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, " %02d ", i);
32204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegPrintAtom(output, regexp->atoms[i]);
32214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
32224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "%d states:", regexp->nbStates);
32234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "\n");
32244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    for (i = 0;i < regexp->nbStates; i++) {
32254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegPrintState(output, regexp->states[i]);
32264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
32274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    fprintf(output, "%d counters:\n", regexp->nbCounters);
32284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    for (i = 0;i < regexp->nbCounters; i++) {
32294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	fprintf(output, " %d: min %d max %d\n", i, regexp->counters[i].min,
32304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		                                regexp->counters[i].max);
32314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
32324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
32334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
32344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
32354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegexpCompile:
32364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @regexp:  a regular expression string
32374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
32384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Parses a regular expression conforming to XML Schemas Part 2 Datatype
32394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Appendix F and build an automata suitable for testing strings against
32404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * that regular expression
32414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
32424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the compiled expression or NULL in case of error
32434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
32444255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpPtr
32454255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpCompile(const xmlChar *regexp) {
32464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegexpPtr ret;
32474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegParserCtxtPtr ctxt;
32484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
32494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt = xmlRegNewParserCtxt(regexp);
32504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt == NULL)
32514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
32524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
32534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    /* initialize the parser */
32544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->end = NULL;
32554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->start = ctxt->state = xmlRegNewState(ctxt);
32564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePush(ctxt, ctxt->start);
32574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
32584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    /* parse the expression building an automata */
32594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFAParseRegExp(ctxt, 1);
32604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (CUR != 0) {
32614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	ERROR("xmlFAParseRegExp: extra characters");
32624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
32634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->end = ctxt->state;
32644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->start->type = XML_REGEXP_START_STATE;
32654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->end->type = XML_REGEXP_FINAL_STATE;
32664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
32674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    /* remove the Epsilon except for counted transitions */
32684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFAEliminateEpsilonTransitions(ctxt);
32694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
32704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
32714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt->error != 0) {
32724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlRegFreeParserCtxt(ctxt);
32734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
32744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
32754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret = xmlRegEpxFromParse(ctxt);
32764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegFreeParserCtxt(ctxt);
32774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(ret);
32784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
32794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
32804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
32814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegexpExec:
32824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @comp:  the compiled regular expression
32834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @content:  the value to check against the regular expression
32844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
32854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Check if the regular expression generate the value
32864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
32874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns 1 if it matches, 0 if not and a negativa value in case of error
32884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
32894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardint
32904255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpExec(xmlRegexpPtr comp, const xmlChar *content) {
32914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if ((comp == NULL) || (content == NULL))
32924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(-1);
32934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(xmlFARegExec(comp, content));
32944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
32954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
32964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
32974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeRegexp:
32984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @regexp:  the regexp
32994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
33004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp
33014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
33024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid
33034255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeRegexp(xmlRegexpPtr regexp) {
33044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    int i;
33054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (regexp == NULL)
33064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
33074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
33084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (regexp->string != NULL)
33094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(regexp->string);
33104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (regexp->states != NULL) {
33114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	for (i = 0;i < regexp->nbStates;i++)
33124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlRegFreeState(regexp->states[i]);
33134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(regexp->states);
33144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
33154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (regexp->atoms != NULL) {
33164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	for (i = 0;i < regexp->nbAtoms;i++)
33174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	    xmlRegFreeAtom(regexp->atoms[i]);
33184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(regexp->atoms);
33194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    }
33204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (regexp->counters != NULL)
33214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFree(regexp->counters);
33224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFree(regexp);
33234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
33244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
33254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef LIBXML_AUTOMATA_ENABLED
33264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************
33274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
33284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 			The Automata interface				*
33294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 									*
33304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/
33314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
33324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
33334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlNewAutomata:
33344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
33354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Create a new automata
33364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
33374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new object or NULL in case of failure
33384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
33394255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataPtr
33404255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlNewAutomata(void) {
33414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlAutomataPtr ctxt;
33424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
33434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt = xmlRegNewParserCtxt(NULL);
33444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (ctxt == NULL)
33454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
33464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
33474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    /* initialize the parser */
33484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->end = NULL;
33494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ctxt->start = ctxt->state = xmlRegNewState(ctxt);
33504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePush(ctxt, ctxt->start);
33514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
33524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(ctxt);
33534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
33544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
33554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
33564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFreeAutomata:
33574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata
33584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
33594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free an automata
33604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
33614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid
33624255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFreeAutomata(xmlAutomataPtr am) {
33634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (am == NULL)
33644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return;
33654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegFreeParserCtxt(am);
33664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
33674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
33684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
33694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataGetInitState:
33704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata
33714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
33724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the initial state of the automata
33734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
33744255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr
33754255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataGetInitState(xmlAutomataPtr am) {
33764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (am == NULL)
33774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
33784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(am->start);
33794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
33804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
33814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
33824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataSetFinalState:
33834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata
33844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @state: a state in this automata
33854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
33864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Makes that state a final state
33874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
33884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns 0 or -1 in case of error
33894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
33904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardint
33914255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataSetFinalState(xmlAutomataPtr am, xmlAutomataStatePtr state) {
33924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if ((am == NULL) || (state == NULL))
33934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(-1);
33944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    state->type = XML_REGEXP_FINAL_STATE;
33954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(0);
33964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
33974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
33984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
33994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataNewTransition:
34004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata
34014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @from: the starting point of the transition
34024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @to: the target point of the transition or NULL
34034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @token: the input string associated to that transition
34044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @data: data passed to the callback function if the transition is activated
34054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
34064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * If @to is NULL, this create first a new target state in the automata
34074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * and then adds a transition from the @from state to the target state
34084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * activated by the value of @token
34094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
34104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the target state or NULL in case of error
34114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
34124255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr
34134255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataNewTransition(xmlAutomataPtr am, xmlAutomataStatePtr from,
34144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 xmlAutomataStatePtr to, const xmlChar *token,
34154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 void *data) {
34164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegAtomPtr atom;
34174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
34184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if ((am == NULL) || (from == NULL) || (token == NULL))
34194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
34204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
34214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    atom->data = data;
34224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom == NULL)
34234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
34244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    atom->valuep = xmlStrdup(token);
34254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
34264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFAGenerateTransitions(am, from, to, atom);
34274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (to == NULL)
34284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(am->state);
34294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(to);
34304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
34314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
34324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
34334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataNewCountTrans:
34344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata
34354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @from: the starting point of the transition
34364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @to: the target point of the transition or NULL
34374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @token: the input string associated to that transition
34384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @min:  the minimum successive occurences of token
34394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @min:  the maximum successive occurences of token
34404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
34414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * If @to is NULL, this create first a new target state in the automata
34424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * and then adds a transition from the @from state to the target state
34434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * activated by a succession of input of value @token and whose number
34444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * is between @min and @max
34454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
34464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the target state or NULL in case of error
34474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
34484255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr
34494255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
34504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 xmlAutomataStatePtr to, const xmlChar *token,
34514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard			 int min, int max, void *data) {
34524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegAtomPtr atom;
34534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
34544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if ((am == NULL) || (from == NULL) || (token == NULL))
34554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
34564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (min < 0)
34574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
34584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if ((max < min) || (max < 1))
34594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
34604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
34614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (atom == NULL)
34624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
34634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    atom->valuep = xmlStrdup(token);
34644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    atom->data = data;
34654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (min == 0)
34664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	atom->min = 1;
34674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    else
34684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	atom->min = min;
34694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    atom->max = max;
34704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
34714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFAGenerateTransitions(am, from, to, atom);
34724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (to == NULL)
34734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	to = am->state;
34744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (to == NULL)
34754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
34764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (min == 0)
34774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	xmlFAGenerateEpsilonTransition(am, from, to);
34784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(to);
34794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
34804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
34814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
34827646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * xmlAutomataNewOnceTrans:
34837646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @am: an automata
34847646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @from: the starting point of the transition
34857646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @to: the target point of the transition or NULL
34867646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @token: the input string associated to that transition
34877646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @min:  the minimum successive occurences of token
34887646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @min:  the maximum successive occurences of token
34897646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard *
34907646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * If @to is NULL, this create first a new target state in the automata
34917646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * and then adds a transition from the @from state to the target state
34927646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * activated by a succession of input of value @token and whose number
34937646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * is between @min and @max, moreover that transistion can only be crossed
34947646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * once.
34957646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard *
34967646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * Returns the target state or NULL in case of error
34977646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard */
34987646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlAutomataStatePtr
34997646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
35007646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard			 xmlAutomataStatePtr to, const xmlChar *token,
35017646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard			 int min, int max, void *data) {
35027646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    xmlRegAtomPtr atom;
35037646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    int counter;
35047646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard
35057646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    if ((am == NULL) || (from == NULL) || (token == NULL))
35067646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	return(NULL);
35077646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    if (min < 1)
35087646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	return(NULL);
35097646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    if ((max < min) || (max < 1))
35107646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	return(NULL);
35117646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
35127646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    if (atom == NULL)
35137646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	return(NULL);
35147646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    atom->valuep = xmlStrdup(token);
35157646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    atom->data = data;
35167646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    atom->quant = XML_REGEXP_QUANT_ONCEONLY;
35177646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    if (min == 0)
35187646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	atom->min = 1;
35197646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    else
35207646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	atom->min = min;
35217646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    atom->max = max;
35227646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    /*
35237646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard     * associate a counter to the transition.
35247646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard     */
35257646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    counter = xmlRegGetCounter(am);
35267646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    am->counters[counter].min = 1;
35277646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    am->counters[counter].max = 1;
35287646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard
35297646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    /* xmlFAGenerateTransitions(am, from, to, atom); */
35307646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    if (to == NULL) {
35317646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	to = xmlRegNewState(am);
35327646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	xmlRegStatePush(am, to);
35337646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    }
35347646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    xmlRegStateAddTrans(am, from, atom, to, counter, -1);
35357646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    xmlRegAtomPush(am, atom);
35367646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    am->state = to;
35377646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    if (to == NULL)
35387646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	to = am->state;
35397646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    if (to == NULL)
35407646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	return(NULL);
35417646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    return(to);
35427646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard}
35437646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard
35447646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard/**
35454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataNewState:
35464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata
35474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
35484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Create a new disconnected state in the automata
35494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
35504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new state or NULL in case of error
35514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
35524255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr
35534255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataNewState(xmlAutomataPtr am) {
35544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlAutomataStatePtr to;
35554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
35564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (am == NULL)
35574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
35584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    to = xmlRegNewState(am);
35594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegStatePush(am, to);
35604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(to);
35614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
35624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
35634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
35644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataNewTransition:
35654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata
35664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @from: the starting point of the transition
35674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @to: the target point of the transition or NULL
35684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
35694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * If @to is NULL, this create first a new target state in the automata
35704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * and then adds a an epsilon transition from the @from state to the
35714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * target state
35724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
35734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the target state or NULL in case of error
35744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
35754255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr
35764255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataNewEpsilon(xmlAutomataPtr am, xmlAutomataStatePtr from,
35774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard		      xmlAutomataStatePtr to) {
35784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if ((am == NULL) || (from == NULL))
35794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(NULL);
35804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFAGenerateEpsilonTransition(am, from, to);
35814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    if (to == NULL)
35824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard	return(am->state);
35834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(to);
35844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
35854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
3586b509f1543df71549969eeac076349e05d2f78044Daniel Veillard/**
35877646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * xmlAutomataNewAllTrans:
35887646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @am: an automata
35897646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @from: the starting point of the transition
35907646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @to: the target point of the transition or NULL
35917646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard *
35927646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * If @to is NULL, this create first a new target state in the automata
35937646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * and then adds a an ALL transition from the @from state to the
35947646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * target state. That transition is an epsilon transition allowed only when
35957646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * all transitions from the @from node have been activated.
35967646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard *
35977646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * Returns the target state or NULL in case of error
35987646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard */
35997646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlAutomataStatePtr
36007646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlAutomataNewAllTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
36017646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard		      xmlAutomataStatePtr to) {
36027646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    if ((am == NULL) || (from == NULL))
36037646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	return(NULL);
36047646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    xmlFAGenerateAllTransition(am, from, to);
36057646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    if (to == NULL)
36067646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard	return(am->state);
36077646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard    return(to);
36087646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard}
36097646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard
36107646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard/**
3611b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * xmlAutomataNewCounter:
3612b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @am: an automata
3613b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @min:  the minimal value on the counter
3614b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @max:  the maximal value on the counter
3615b509f1543df71549969eeac076349e05d2f78044Daniel Veillard *
3616b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * Create a new counter
3617b509f1543df71549969eeac076349e05d2f78044Daniel Veillard *
3618b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * Returns the counter number or -1 in case of error
3619b509f1543df71549969eeac076349e05d2f78044Daniel Veillard */
3620b509f1543df71549969eeac076349e05d2f78044Daniel Veillardint
3621b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataNewCounter(xmlAutomataPtr am, int min, int max) {
3622b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    int ret;
3623b509f1543df71549969eeac076349e05d2f78044Daniel Veillard
3624b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    if (am == NULL)
3625b509f1543df71549969eeac076349e05d2f78044Daniel Veillard	return(-1);
3626b509f1543df71549969eeac076349e05d2f78044Daniel Veillard
3627b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    ret = xmlRegGetCounter(am);
3628b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    if (ret < 0)
3629b509f1543df71549969eeac076349e05d2f78044Daniel Veillard	return(-1);
3630b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    am->counters[ret].min = min;
3631b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    am->counters[ret].max = max;
3632b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    return(ret);
3633b509f1543df71549969eeac076349e05d2f78044Daniel Veillard}
3634b509f1543df71549969eeac076349e05d2f78044Daniel Veillard
3635b509f1543df71549969eeac076349e05d2f78044Daniel Veillard/**
3636b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * xmlAutomataNewCountedTrans:
3637b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @am: an automata
3638b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @from: the starting point of the transition
3639b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @to: the target point of the transition or NULL
3640b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @counter: the counter associated to that transition
3641b509f1543df71549969eeac076349e05d2f78044Daniel Veillard *
3642b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * If @to is NULL, this create first a new target state in the automata
3643b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * and then adds an epsilon transition from the @from state to the target state
3644b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * which will increment the counter provided
3645b509f1543df71549969eeac076349e05d2f78044Daniel Veillard *
3646b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * Returns the target state or NULL in case of error
3647b509f1543df71549969eeac076349e05d2f78044Daniel Veillard */
3648b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataStatePtr
3649b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataNewCountedTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
3650b509f1543df71549969eeac076349e05d2f78044Daniel Veillard		xmlAutomataStatePtr to, int counter) {
3651b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    if ((am == NULL) || (from == NULL) || (counter < 0))
3652b509f1543df71549969eeac076349e05d2f78044Daniel Veillard	return(NULL);
3653b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    xmlFAGenerateCountedEpsilonTransition(am, from, to, counter);
3654b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    if (to == NULL)
3655b509f1543df71549969eeac076349e05d2f78044Daniel Veillard	return(am->state);
3656b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    return(to);
3657b509f1543df71549969eeac076349e05d2f78044Daniel Veillard}
3658b509f1543df71549969eeac076349e05d2f78044Daniel Veillard
3659b509f1543df71549969eeac076349e05d2f78044Daniel Veillard/**
3660b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * xmlAutomataNewCounterTrans:
3661b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @am: an automata
3662b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @from: the starting point of the transition
3663b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @to: the target point of the transition or NULL
3664b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @counter: the counter associated to that transition
3665b509f1543df71549969eeac076349e05d2f78044Daniel Veillard *
3666b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * If @to is NULL, this create first a new target state in the automata
3667b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * and then adds an epsilon transition from the @from state to the target state
3668b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * which will be allowed only if the counter is within the right range.
3669b509f1543df71549969eeac076349e05d2f78044Daniel Veillard *
3670b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * Returns the target state or NULL in case of error
3671b509f1543df71549969eeac076349e05d2f78044Daniel Veillard */
3672b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataStatePtr
3673b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataNewCounterTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
3674b509f1543df71549969eeac076349e05d2f78044Daniel Veillard		xmlAutomataStatePtr to, int counter) {
3675b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    if ((am == NULL) || (from == NULL) || (counter < 0))
3676b509f1543df71549969eeac076349e05d2f78044Daniel Veillard	return(NULL);
3677b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    xmlFAGenerateCountedTransition(am, from, to, counter);
3678b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    if (to == NULL)
3679b509f1543df71549969eeac076349e05d2f78044Daniel Veillard	return(am->state);
3680b509f1543df71549969eeac076349e05d2f78044Daniel Veillard    return(to);
3681b509f1543df71549969eeac076349e05d2f78044Daniel Veillard}
36824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
36834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/**
36844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataCompile:
36854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata
36864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
36874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Compile the automata into a Reg Exp ready for being executed.
36884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The automata should be free after this point.
36894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *
36904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the compiled regexp or NULL in case of error
36914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */
36924255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpPtr
36934255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataCompile(xmlAutomataPtr am) {
36944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlRegexpPtr ret;
36954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
36964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    xmlFAEliminateEpsilonTransitions(am);
36974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    ret = xmlRegEpxFromParse(am);
36984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard
36994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard    return(ret);
37004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}
37014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif /* LIBXML_AUTOMATA_ENABLED */
37024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif /* LIBXML_REGEXP_ENABLED */
3703