xmlregexp.c revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * regexp.c: generic and extensible Regular Expression engine
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Basically designed with the purpose of compiling regexps for
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the variety of validation/shemas mechanisms now available in
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * XML related specifications these include:
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    - XML-1.0 DTD validation
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    - XML Schemas structure part 1
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    - XML Schemas Datatypes part 2 especially Appendix F
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    - RELAX-NG/TREX i.e. the counter proposal
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See Copyright for the status of this software.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Daniel Veillard <veillard@redhat.com>
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IN_LIBXML
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxml.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_REGEXP_ENABLED
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_ERR */
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_LIMITS_H
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits.h>
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/tree.h>
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/parserInternals.h>
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlregexp.h>
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlautomata.h>
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlunicode.h>
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef INT_MAX
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INT_MAX 123456789 /* easy to flag and big enough for our needs */
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_REGEXP_GRAPH */
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_REGEXP_EXEC */
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_PUSH */
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_COMPACTION */
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX_PUSH 10000000
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ERROR(str)							\
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->error = XML_REGEXP_COMPILE_ERROR;				\
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegexpErrCompile(ctxt, str);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEXT ctxt->cur++
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CUR (*(ctxt->cur))
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NXT(index) (ctxt->cur[index])
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEXTL(l) ctxt->cur += l;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_REG_STRING_SEPARATOR '|'
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Need PREV to check on a '-' within a Character Group. May only be used
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * when it's guaranteed that cur is not at the beginning of ctxt->string!
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PREV (ctxt->cur[-1])
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO:
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * macro to flag unimplemented blocks
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TODO 								\
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlGenericError(xmlGenericErrorContext,				\
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    "Unimplemented block at %s:%d\n",				\
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            __FILE__, __LINE__);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 			Datatypes and structures			*
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note: the order of the enums below is significant, do not shuffle
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_EPSILON = 1,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_CHARVAL,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_RANGES,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_SUBREG,  /* used for () sub regexps */
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_STRING,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_ANYCHAR, /* . */
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_ANYSPACE, /* \s */
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_NOTSPACE, /* \S */
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_INITNAME, /* \l */
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_NOTINITNAME, /* \L */
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_NAMECHAR, /* \c */
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_NOTNAMECHAR, /* \C */
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_DECIMAL, /* \d */
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_NOTDECIMAL, /* \D */
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_REALCHAR, /* \w */
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_NOTREALCHAR, /* \W */
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_LETTER = 100,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_LETTER_UPPERCASE,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_LETTER_LOWERCASE,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_LETTER_TITLECASE,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_LETTER_MODIFIER,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_LETTER_OTHERS,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_MARK,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_MARK_NONSPACING,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_MARK_SPACECOMBINING,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_MARK_ENCLOSING,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_NUMBER,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_NUMBER_DECIMAL,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_NUMBER_LETTER,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_NUMBER_OTHERS,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_PUNCT,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_PUNCT_CONNECTOR,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_PUNCT_DASH,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_PUNCT_OPEN,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_PUNCT_CLOSE,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_PUNCT_INITQUOTE,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_PUNCT_FINQUOTE,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_PUNCT_OTHERS,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_SEPAR,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_SEPAR_SPACE,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_SEPAR_LINE,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_SEPAR_PARA,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_SYMBOL,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_SYMBOL_MATH,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_SYMBOL_CURRENCY,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_SYMBOL_MODIFIER,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_SYMBOL_OTHERS,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_OTHER,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_OTHER_CONTROL,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_OTHER_FORMAT,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_OTHER_PRIVATE,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_OTHER_NA,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_BLOCK_NAME
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xmlRegAtomType;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_QUANT_EPSILON = 1,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_QUANT_ONCE,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_QUANT_OPT,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_QUANT_MULT,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_QUANT_PLUS,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_QUANT_ONCEONLY,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_QUANT_ALL,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_QUANT_RANGE
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xmlRegQuantType;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_START_STATE = 1,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_FINAL_STATE,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_TRANS_STATE,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_SINK_STATE,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_UNREACH_STATE
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xmlRegStateType;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_MARK_NORMAL = 0,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_MARK_START,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_REGEXP_MARK_VISITED
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xmlRegMarkedType;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlRegRange xmlRegRange;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegRange *xmlRegRangePtr;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegRange {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int neg;		/* 0 normal, 1 not, 2 exclude */
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomType type;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int start;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int end;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *blockName;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlRegAtom xmlRegAtom;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegAtom *xmlRegAtomPtr;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlAutomataState xmlRegState;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegState *xmlRegStatePtr;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegAtom {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int no;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomType type;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegQuantType quant;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int min;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int max;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void *valuep;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void *valuep2;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int neg;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int codepoint;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr start;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr start0;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr stop;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int maxRanges;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbRanges;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegRangePtr *ranges;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void *data;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlRegCounter xmlRegCounter;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegCounter *xmlRegCounterPtr;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegCounter {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int min;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int max;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlRegTrans xmlRegTrans;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegTrans *xmlRegTransPtr;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegTrans {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr atom;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int to;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int counter;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int count;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nd;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlAutomataState {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStateType type;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegMarkedType mark;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegMarkedType reached;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int no;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int maxTrans;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbTrans;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegTrans *trans;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*  knowing states ponting to us can speed things up */
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int maxTransTo;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbTransTo;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int *transTo;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlAutomata xmlRegParserCtxt;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegParserCtxt *xmlRegParserCtxtPtr;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AM_AUTOMATA_RNG 1
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlAutomata {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *string;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *cur;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int error;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int neg;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr start;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr end;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr state;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr atom;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int maxAtoms;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbAtoms;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr *atoms;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int maxStates;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbStates;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr *states;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int maxCounters;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbCounters;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegCounter *counters;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int determinist;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int negs;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int flags;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegexp {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *string;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbStates;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr *states;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbAtoms;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr *atoms;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbCounters;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegCounter *counters;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int determinist;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int flags;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * That's the compact form for determinists automatas
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbstates;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int *compact;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void **transdata;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbstrings;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar **stringMap;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlRegExecRollback xmlRegExecRollback;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegExecRollback *xmlRegExecRollbackPtr;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegExecRollback {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr state;/* the current state */
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int index;		/* the index in the input stack */
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nextbranch;	/* the next transition to explore in that state */
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int *counts;	/* save the automata state if it has some */
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlRegInputToken xmlRegInputToken;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegInputToken *xmlRegInputTokenPtr;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegInputToken {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *value;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void *data;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegExecCtxt {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int status;		/* execution status != 0 indicate an error */
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int determinist;	/* did we find an indeterministic behaviour */
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegexpPtr comp;	/* the compiled regexp */
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegExecCallbacks callback;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void *data;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr state;/* the current state */
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int transno;	/* the current transition on that state */
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int transcount;	/* the number of chars in char counted transitions */
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * A stack of rollback states
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int maxRollbacks;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbRollbacks;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegExecRollback *rollbacks;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * The state of the automata if any
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int *counts;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * The input stack
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int inputStackMax;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int inputStackNr;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int index;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int *charStack;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *inputString; /* when operating on characters */
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegInputTokenPtr inputStack;/* when operating on strings */
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * error handling
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int errStateNo;		/* the error state number */
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr errState;    /* the error state */
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *errString;		/* the string raising the error */
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int *errCounts;		/* counters at the error state */
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbPush;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define REGEXP_ALL_COUNTER	0x123456
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define REGEXP_ALL_LAX_COUNTER	0x123457
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void xmlRegFreeState(xmlRegStatePtr state);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void xmlRegFreeAtom(xmlRegAtomPtr atom);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int xmlRegStrEqualWildcard(const xmlChar *expStr, const xmlChar *valStr);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int xmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  int neg, int start, int end, const xmlChar *blockName);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void xmlAutomataSetFlags(xmlAutomataPtr am, int flags);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 		Regexp memory error handler				*
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegexpErrMemory:
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @extra:  extra information
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handle an out of memory condition
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpErrMemory(xmlRegParserCtxtPtr ctxt, const char *extra)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *regexp = NULL;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt != NULL) {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        regexp = (const char *) ctxt->string;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->error = XML_ERR_NO_MEMORY;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_REGEXP,
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    regexp, NULL, 0, 0,
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "Memory allocation failed : %s\n", extra);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegexpErrCompile:
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @extra:  extra information
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handle a compilation failure
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpErrCompile(xmlRegParserCtxtPtr ctxt, const char *extra)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *regexp = NULL;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int idx = 0;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt != NULL) {
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        regexp = (const char *) ctxt->string;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	idx = ctxt->cur - ctxt->string;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->error = XML_REGEXP_COMPILE_ERROR;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_REGEXP,
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    XML_REGEXP_COMPILE_ERROR, XML_ERR_FATAL, NULL, 0, extra,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    regexp, NULL, idx, 0,
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "failed to compile: %s\n", extra);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 			Allocation/Deallocation				*
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegEpxFromParse:
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the parser context used to build it
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate a new regexp and fill it with the result from the parser
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new regexp or NULL in case of error
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegexpPtr
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegexpPtr ret;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlRegexpPtr) xmlMalloc(sizeof(xmlRegexp));
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegexpErrMemory(ctxt, "compiling regexp");
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0, sizeof(xmlRegexp));
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->string = ctxt->string;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->nbStates = ctxt->nbStates;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->states = ctxt->states;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->nbAtoms = ctxt->nbAtoms;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->atoms = ctxt->atoms;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->nbCounters = ctxt->nbCounters;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->counters = ctxt->counters;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->determinist = ctxt->determinist;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->flags = ctxt->flags;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret->determinist == -1) {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlRegexpIsDeterminist(ret);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ret->determinist != 0) &&
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(ret->nbCounters == 0) &&
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(ctxt->negs == 0) &&
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(ret->atoms != NULL) &&
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(ret->atoms[0] != NULL) &&
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(ret->atoms[0]->type == XML_REGEXP_STRING)) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i, j, nbstates = 0, nbatoms = 0;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int *stateRemap;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int *stringRemap;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int *transitions;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	void **transdata;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlChar **stringMap;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlChar *value;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Switch to a compact representation
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * 1/ counting the effective number of states left
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * 2/ counting the unique number of atoms, and check that
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *    they are all of the string type
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * 3/ build a table state x atom for the transitions
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	stateRemap = xmlMalloc(ret->nbStates * sizeof(int));
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (stateRemap == NULL) {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "compiling regexp");
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(ret);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < ret->nbStates;i++) {
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret->states[i] != NULL) {
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		stateRemap[i] = nbstates;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		nbstates++;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		stateRemap[i] = -1;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_COMPACTION
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("Final: %d states\n", nbstates);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	stringMap = xmlMalloc(ret->nbAtoms * sizeof(char *));
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (stringMap == NULL) {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "compiling regexp");
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(stateRemap);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(ret);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	stringRemap = xmlMalloc(ret->nbAtoms * sizeof(int));
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (stringRemap == NULL) {
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "compiling regexp");
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(stringMap);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(stateRemap);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(ret);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < ret->nbAtoms;i++) {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((ret->atoms[i]->type == XML_REGEXP_STRING) &&
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(ret->atoms[i]->quant == XML_REGEXP_QUANT_ONCE)) {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		value = ret->atoms[i]->valuep;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                for (j = 0;j < nbatoms;j++) {
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (xmlStrEqual(stringMap[j], value)) {
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			stringRemap[i] = j;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (j >= nbatoms) {
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    stringRemap[i] = nbatoms;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    stringMap[nbatoms] = xmlStrdup(value);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (stringMap[nbatoms] == NULL) {
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			for (i = 0;i < nbatoms;i++)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlFree(stringMap[i]);
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFree(stringRemap);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFree(stringMap);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFree(stateRemap);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFree(ret);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return(NULL);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    nbatoms++;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlFree(stateRemap);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlFree(stringRemap);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		for (i = 0;i < nbatoms;i++)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFree(stringMap[i]);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlFree(stringMap);
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlFree(ret);
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(NULL);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_COMPACTION
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("Final: %d atoms\n", nbatoms);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	transitions = (int *) xmlMalloc((nbstates + 1) *
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                                (nbatoms + 1) * sizeof(int));
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (transitions == NULL) {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(stateRemap);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(stringRemap);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(stringMap);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(ret);
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memset(transitions, 0, (nbstates + 1) * (nbatoms + 1) * sizeof(int));
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Allocate the transition table. The first entry for each
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * state corresponds to the state type.
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	transdata = NULL;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < ret->nbStates;i++) {
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int stateno, atomno, targetno, prev;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegStatePtr state;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegTransPtr trans;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    stateno = stateRemap[i];
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (stateno == -1)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    state = ret->states[i];
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    transitions[stateno * (nbatoms + 1)] = state->type;
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (j = 0;j < state->nbTrans;j++) {
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		trans = &(state->trans[j]);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((trans->to == -1) || (trans->atom == NULL))
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    continue;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                atomno = stringRemap[trans->atom->no];
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((trans->atom->data != NULL) && (transdata == NULL)) {
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    transdata = (void **) xmlMalloc(nbstates * nbatoms *
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			                            sizeof(void *));
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (transdata != NULL)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			memset(transdata, 0,
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       nbstates * nbatoms * sizeof(void *));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    else {
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlRegexpErrMemory(ctxt, "compiling regexp");
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		targetno = stateRemap[trans->to];
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * if the same atom can generate transitions to 2 different
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * states then it means the automata is not determinist and
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * the compact form can't be used !
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		prev = transitions[stateno * (nbatoms + 1) + atomno + 1];
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (prev != 0) {
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (prev != targetno + 1) {
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ret->determinist = 0;
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_COMPACTION
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("Indet: state %d trans %d, atom %d to %d : %d to %d\n",
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       i, j, trans->atom->no, trans->to, atomno, targetno);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("       previous to is %d\n", prev);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (transdata != NULL)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlFree(transdata);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFree(transitions);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFree(stateRemap);
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFree(stringRemap);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			for (i = 0;i < nbatoms;i++)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlFree(stringMap[i]);
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFree(stringMap);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto not_determ;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("State %d trans %d: atom %d to %d : %d to %d\n",
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   i, j, trans->atom->no, trans->to, atomno, targetno);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    transitions[stateno * (nbatoms + 1) + atomno + 1] =
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			targetno + 1; /* to avoid 0 */
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (transdata != NULL)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			transdata[stateno * nbatoms + atomno] =
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    trans->atom->data;
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->determinist = 1;
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_COMPACTION
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Debug
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < nbstates;i++) {
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (j = 0;j < nbatoms + 1;j++) {
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                printf("%02d ", transitions[i * (nbatoms + 1) + j]);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("\n");
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("\n");
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Cleanup of the old data
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret->states != NULL) {
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i = 0;i < ret->nbStates;i++)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegFreeState(ret->states[i]);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(ret->states);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->states = NULL;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->nbStates = 0;
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret->atoms != NULL) {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i = 0;i < ret->nbAtoms;i++)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegFreeAtom(ret->atoms[i]);
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(ret->atoms);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->atoms = NULL;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->nbAtoms = 0;
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->compact = transitions;
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->transdata = transdata;
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->stringMap = stringMap;
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->nbstrings = nbatoms;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->nbstates = nbstates;
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(stateRemap);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(stringRemap);
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)not_determ:
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->string = NULL;
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->nbStates = 0;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->states = NULL;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->nbAtoms = 0;
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->atoms = NULL;
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->nbCounters = 0;
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->counters = NULL;
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegNewParserCtxt:
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @string:  the string to parse
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate a new regexp parser context
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new context or NULL in case of error
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegParserCtxtPtr
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegNewParserCtxt(const xmlChar *string) {
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegParserCtxtPtr ret;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlRegParserCtxtPtr) xmlMalloc(sizeof(xmlRegParserCtxt));
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0, sizeof(xmlRegParserCtxt));
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (string != NULL)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->string = xmlStrdup(string);
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->cur = ret->string;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->neg = 0;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->negs = 0;
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->error = 0;
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->determinist = -1;
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegNewRange:
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the regexp parser context
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @neg:  is that negative
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type:  the type of range
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @start:  the start codepoint
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @end:  the end codepoint
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate a new regexp range
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new range or NULL in case of error
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegRangePtr
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegNewRange(xmlRegParserCtxtPtr ctxt,
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       int neg, xmlRegAtomType type, int start, int end) {
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegRangePtr ret;
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlRegRangePtr) xmlMalloc(sizeof(xmlRegRange));
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegexpErrMemory(ctxt, "allocating range");
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->neg = neg;
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = type;
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->start = start;
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->end = end;
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegFreeRange:
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @range:  the regexp range
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free a regexp range
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegFreeRange(xmlRegRangePtr range) {
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range == NULL)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range->blockName != NULL)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(range->blockName);
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(range);
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegCopyRange:
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @range:  the regexp range
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copy a regexp range
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new copy or NULL in case of error.
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegRangePtr
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegCopyRange(xmlRegParserCtxtPtr ctxt, xmlRegRangePtr range) {
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegRangePtr ret;
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range == NULL)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlRegNewRange(ctxt, range->neg, range->type, range->start,
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         range->end);
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range->blockName != NULL) {
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->blockName = xmlStrdup(range->blockName);
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret->blockName == NULL) {
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "allocating range");
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegFreeRange(ret);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegNewAtom:
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the regexp parser context
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type:  the type of atom
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate a new atom
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new atom or NULL in case of error
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegAtomPtr
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegNewAtom(xmlRegParserCtxtPtr ctxt, xmlRegAtomType type) {
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr ret;
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlRegAtomPtr) xmlMalloc(sizeof(xmlRegAtom));
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegexpErrMemory(ctxt, "allocating atom");
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0, sizeof(xmlRegAtom));
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = type;
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->quant = XML_REGEXP_QUANT_ONCE;
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->min = 0;
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->max = 0;
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegFreeAtom:
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom:  the regexp atom
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free a regexp atom
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegFreeAtom(xmlRegAtomPtr atom) {
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom == NULL)
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < atom->nbRanges;i++)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegFreeRange(atom->ranges[i]);
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom->ranges != NULL)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(atom->ranges);
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((atom->type == XML_REGEXP_STRING) && (atom->valuep != NULL))
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(atom->valuep);
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((atom->type == XML_REGEXP_STRING) && (atom->valuep2 != NULL))
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(atom->valuep2);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((atom->type == XML_REGEXP_BLOCK_NAME) && (atom->valuep != NULL))
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(atom->valuep);
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(atom);
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegCopyAtom:
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the regexp parser context
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom:  the oiginal atom
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate a new regexp range
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new atom or NULL in case of error
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegAtomPtr
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegCopyAtom(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) {
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr ret;
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlRegAtomPtr) xmlMalloc(sizeof(xmlRegAtom));
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegexpErrMemory(ctxt, "copying atom");
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0, sizeof(xmlRegAtom));
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = atom->type;
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->quant = atom->quant;
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->min = atom->min;
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->max = atom->max;
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom->nbRanges > 0) {
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int i;
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret->ranges = (xmlRegRangePtr *) xmlMalloc(sizeof(xmlRegRangePtr) *
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                                           atom->nbRanges);
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret->ranges == NULL) {
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "copying atom");
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto error;
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < atom->nbRanges;i++) {
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret->ranges[i] = xmlRegCopyRange(ctxt, atom->ranges[i]);
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret->ranges[i] == NULL)
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        goto error;
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret->nbRanges = i + 1;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error:
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegFreeAtom(ret);
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(NULL);
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegStatePtr
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegNewState(xmlRegParserCtxtPtr ctxt) {
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr ret;
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlRegStatePtr) xmlMalloc(sizeof(xmlRegState));
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegexpErrMemory(ctxt, "allocating state");
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0, sizeof(xmlRegState));
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = XML_REGEXP_TRANS_STATE;
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->mark = XML_REGEXP_MARK_NORMAL;
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegFreeState:
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @state:  the regexp state
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free a regexp state
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegFreeState(xmlRegStatePtr state) {
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state == NULL)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state->trans != NULL)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(state->trans);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state->transTo != NULL)
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(state->transTo);
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(state);
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegFreeParserCtxt:
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the regexp parser context
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free a regexp parser context
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegFreeParserCtxt(xmlRegParserCtxtPtr ctxt) {
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL)
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->string != NULL)
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(ctxt->string);
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->states != NULL) {
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < ctxt->nbStates;i++)
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegFreeState(ctxt->states[i]);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(ctxt->states);
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->atoms != NULL) {
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < ctxt->nbAtoms;i++)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegFreeAtom(ctxt->atoms[i]);
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(ctxt->atoms);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->counters != NULL)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(ctxt->counters);
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(ctxt);
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 			Display of Data structures			*
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintAtomType(FILE *output, xmlRegAtomType type) {
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (type) {
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_EPSILON:
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "epsilon "); break;
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_CHARVAL:
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "charval "); break;
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_RANGES:
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "ranges "); break;
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SUBREG:
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "subexpr "); break;
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_STRING:
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "string "); break;
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_ANYCHAR:
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "anychar "); break;
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_ANYSPACE:
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "anyspace "); break;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTSPACE:
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "notspace "); break;
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_INITNAME:
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "initname "); break;
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTINITNAME:
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "notinitname "); break;
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NAMECHAR:
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "namechar "); break;
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTNAMECHAR:
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "notnamechar "); break;
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_DECIMAL:
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "decimal "); break;
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTDECIMAL:
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "notdecimal "); break;
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_REALCHAR:
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "realchar "); break;
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTREALCHAR:
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "notrealchar "); break;
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER:
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "LETTER "); break;
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_UPPERCASE:
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "LETTER_UPPERCASE "); break;
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_LOWERCASE:
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "LETTER_LOWERCASE "); break;
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_TITLECASE:
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "LETTER_TITLECASE "); break;
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_MODIFIER:
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "LETTER_MODIFIER "); break;
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_OTHERS:
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "LETTER_OTHERS "); break;
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK:
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "MARK "); break;
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK_NONSPACING:
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "MARK_NONSPACING "); break;
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK_SPACECOMBINING:
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "MARK_SPACECOMBINING "); break;
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK_ENCLOSING:
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "MARK_ENCLOSING "); break;
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER:
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "NUMBER "); break;
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER_DECIMAL:
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "NUMBER_DECIMAL "); break;
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER_LETTER:
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "NUMBER_LETTER "); break;
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER_OTHERS:
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "NUMBER_OTHERS "); break;
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT:
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "PUNCT "); break;
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_CONNECTOR:
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "PUNCT_CONNECTOR "); break;
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_DASH:
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "PUNCT_DASH "); break;
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_OPEN:
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "PUNCT_OPEN "); break;
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_CLOSE:
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "PUNCT_CLOSE "); break;
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_INITQUOTE:
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "PUNCT_INITQUOTE "); break;
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_FINQUOTE:
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "PUNCT_FINQUOTE "); break;
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_OTHERS:
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "PUNCT_OTHERS "); break;
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR:
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "SEPAR "); break;
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR_SPACE:
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "SEPAR_SPACE "); break;
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR_LINE:
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "SEPAR_LINE "); break;
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR_PARA:
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "SEPAR_PARA "); break;
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL:
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "SYMBOL "); break;
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_MATH:
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "SYMBOL_MATH "); break;
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_CURRENCY:
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "SYMBOL_CURRENCY "); break;
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_MODIFIER:
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "SYMBOL_MODIFIER "); break;
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_OTHERS:
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "SYMBOL_OTHERS "); break;
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER:
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "OTHER "); break;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_CONTROL:
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "OTHER_CONTROL "); break;
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_FORMAT:
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "OTHER_FORMAT "); break;
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_PRIVATE:
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "OTHER_PRIVATE "); break;
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_NA:
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(output, "OTHER_NA "); break;
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_BLOCK_NAME:
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "BLOCK "); break;
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintQuantType(FILE *output, xmlRegQuantType type) {
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (type) {
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_QUANT_EPSILON:
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "epsilon "); break;
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_QUANT_ONCE:
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "once "); break;
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_QUANT_OPT:
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "? "); break;
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_QUANT_MULT:
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "* "); break;
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_QUANT_PLUS:
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "+ "); break;
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_REGEXP_QUANT_RANGE:
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "range "); break;
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_REGEXP_QUANT_ONCEONLY:
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "onceonly "); break;
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_REGEXP_QUANT_ALL:
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "all "); break;
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintRange(FILE *output, xmlRegRangePtr range) {
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "  range: ");
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range->neg)
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "negative ");
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegPrintAtomType(output, range->type);
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "%c - %c\n", range->start, range->end);
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintAtom(FILE *output, xmlRegAtomPtr atom) {
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, " atom: ");
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom == NULL) {
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "NULL\n");
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom->neg)
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fprintf(output, "not ");
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegPrintAtomType(output, atom->type);
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegPrintQuantType(output, atom->quant);
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom->quant == XML_REGEXP_QUANT_RANGE)
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "%d-%d ", atom->min, atom->max);
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom->type == XML_REGEXP_STRING)
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "'%s' ", (char *) atom->valuep);
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom->type == XML_REGEXP_CHARVAL)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "char %c\n", atom->codepoint);
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (atom->type == XML_REGEXP_RANGES) {
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i;
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "%d entries\n", atom->nbRanges);
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0; i < atom->nbRanges;i++)
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegPrintRange(output, atom->ranges[i]);
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (atom->type == XML_REGEXP_SUBREG) {
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "start %d end %d\n", atom->start->no, atom->stop->no);
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "\n");
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintTrans(FILE *output, xmlRegTransPtr trans) {
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "  trans: ");
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (trans == NULL) {
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "NULL\n");
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (trans->to < 0) {
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "removed\n");
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (trans->nd != 0) {
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (trans->nd == 2)
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "last not determinist, ");
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(output, "not determinist, ");
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (trans->counter >= 0) {
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "counted %d, ", trans->counter);
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (trans->count == REGEXP_ALL_COUNTER) {
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "all transition, ");
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (trans->count >= 0) {
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "count based %d, ", trans->count);
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (trans->atom == NULL) {
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "epsilon to %d\n", trans->to);
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (trans->atom->type == XML_REGEXP_CHARVAL)
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "char %c ", trans->atom->codepoint);
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "atom %d, to %d\n", trans->atom->no, trans->to);
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintState(FILE *output, xmlRegStatePtr state) {
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, " state: ");
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state == NULL) {
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "NULL\n");
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state->type == XML_REGEXP_START_STATE)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "START ");
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state->type == XML_REGEXP_FINAL_STATE)
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "FINAL ");
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "%d, %d transitions:\n", state->no, state->nbTrans);
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < state->nbTrans; i++) {
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegPrintTrans(output, &(state->trans[i]));
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintCtxt(FILE *output, xmlRegParserCtxtPtr ctxt) {
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, " ctxt: ");
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL) {
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "NULL\n");
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "'%s' ", ctxt->string);
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->error)
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "error ");
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->neg)
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "neg ");
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "\n");
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "%d atoms:\n", ctxt->nbAtoms);
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < ctxt->nbAtoms; i++) {
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, " %02d ", i);
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegPrintAtom(output, ctxt->atoms[i]);
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->atom != NULL) {
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "current atom:\n");
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegPrintAtom(output, ctxt->atom);
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "%d states:", ctxt->nbStates);
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->start != NULL)
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, " start: %d", ctxt->start->no);
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->end != NULL)
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, " end: %d", ctxt->end->no);
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "\n");
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < ctxt->nbStates; i++) {
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegPrintState(output, ctxt->states[i]);
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "%d counters:\n", ctxt->nbCounters);
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < ctxt->nbCounters; i++) {
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, " %d: min %d max %d\n", i, ctxt->counters[i].min,
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                                ctxt->counters[i].max);
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *		 Finite Automata structures manipulations		*
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom,
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	           int neg, xmlRegAtomType type, int start, int end,
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   xmlChar *blockName) {
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegRangePtr range;
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom == NULL) {
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("add range: atom is NULL");
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom->type != XML_REGEXP_RANGES) {
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("add range: atom is not ranges");
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom->maxRanges == 0) {
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->maxRanges = 4;
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->ranges = (xmlRegRangePtr *) xmlMalloc(atom->maxRanges *
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                             sizeof(xmlRegRangePtr));
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (atom->ranges == NULL) {
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "adding ranges");
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    atom->maxRanges = 0;
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (atom->nbRanges >= atom->maxRanges) {
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegRangePtr *tmp;
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->maxRanges *= 2;
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = (xmlRegRangePtr *) xmlRealloc(atom->ranges, atom->maxRanges *
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                             sizeof(xmlRegRangePtr));
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == NULL) {
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "adding ranges");
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    atom->maxRanges /= 2;
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->ranges = tmp;
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    range = xmlRegNewRange(ctxt, neg, type, start, end);
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range == NULL)
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    range->blockName = blockName;
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->ranges[atom->nbRanges++] = range;
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegGetCounter(xmlRegParserCtxtPtr ctxt) {
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->maxCounters == 0) {
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->maxCounters = 4;
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->counters = (xmlRegCounter *) xmlMalloc(ctxt->maxCounters *
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                             sizeof(xmlRegCounter));
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->counters == NULL) {
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "allocating counter");
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->maxCounters = 0;
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (ctxt->nbCounters >= ctxt->maxCounters) {
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegCounter *tmp;
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->maxCounters *= 2;
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = (xmlRegCounter *) xmlRealloc(ctxt->counters, ctxt->maxCounters *
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                           sizeof(xmlRegCounter));
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == NULL) {
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "allocating counter");
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->maxCounters /= 2;
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->counters = tmp;
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->counters[ctxt->nbCounters].min = -1;
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->counters[ctxt->nbCounters].max = -1;
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ctxt->nbCounters++);
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegAtomPush(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) {
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom == NULL) {
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("atom push: atom is NULL");
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->maxAtoms == 0) {
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->maxAtoms = 4;
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->atoms = (xmlRegAtomPtr *) xmlMalloc(ctxt->maxAtoms *
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                             sizeof(xmlRegAtomPtr));
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->atoms == NULL) {
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "pushing atom");
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->maxAtoms = 0;
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (ctxt->nbAtoms >= ctxt->maxAtoms) {
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegAtomPtr *tmp;
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->maxAtoms *= 2;
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = (xmlRegAtomPtr *) xmlRealloc(ctxt->atoms, ctxt->maxAtoms *
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                             sizeof(xmlRegAtomPtr));
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == NULL) {
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "allocating counter");
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->maxAtoms /= 2;
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->atoms = tmp;
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->no = ctxt->nbAtoms;
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->atoms[ctxt->nbAtoms++] = atom;
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegStateAddTransTo(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr target,
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      int from) {
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (target->maxTransTo == 0) {
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	target->maxTransTo = 8;
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	target->transTo = (int *) xmlMalloc(target->maxTransTo *
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                             sizeof(int));
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (target->transTo == NULL) {
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "adding transition");
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    target->maxTransTo = 0;
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (target->nbTransTo >= target->maxTransTo) {
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int *tmp;
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	target->maxTransTo *= 2;
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = (int *) xmlRealloc(target->transTo, target->maxTransTo *
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                             sizeof(int));
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == NULL) {
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "adding transition");
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    target->maxTransTo /= 2;
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	target->transTo = tmp;
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    target->transTo[target->nbTransTo] = from;
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    target->nbTransTo++;
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	            xmlRegAtomPtr atom, xmlRegStatePtr target,
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int counter, int count) {
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nrtrans;
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state == NULL) {
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("add state: state is NULL");
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (target == NULL) {
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("add state: target is NULL");
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Other routines follow the philosophy 'When in doubt, add a transition'
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * so we check here whether such a transition is already present and, if
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * so, silently ignore this request.
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (nrtrans = state->nbTrans - 1; nrtrans >= 0; nrtrans--) {
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegTransPtr trans = &(state->trans[nrtrans]);
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((trans->atom == atom) &&
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (trans->to == target->no) &&
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (trans->counter == counter) &&
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (trans->count == count)) {
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("Ignoring duplicate transition from %d to %d\n",
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    state->no, target->no);
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state->maxTrans == 0) {
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state->maxTrans = 8;
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state->trans = (xmlRegTrans *) xmlMalloc(state->maxTrans *
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                             sizeof(xmlRegTrans));
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (state->trans == NULL) {
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "adding transition");
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    state->maxTrans = 0;
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (state->nbTrans >= state->maxTrans) {
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegTrans *tmp;
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state->maxTrans *= 2;
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = (xmlRegTrans *) xmlRealloc(state->trans, state->maxTrans *
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                             sizeof(xmlRegTrans));
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == NULL) {
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "adding transition");
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    state->maxTrans /= 2;
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state->trans = tmp;
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("Add trans from %d to %d ", state->no, target->no);
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (count == REGEXP_ALL_COUNTER)
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("all transition\n");
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (count >= 0)
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("count based %d\n", count);
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (counter >= 0)
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("counted %d\n", counter);
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (atom == NULL)
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("epsilon transition\n");
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (atom != NULL)
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlRegPrintAtom(stdout, atom);
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state->trans[state->nbTrans].atom = atom;
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state->trans[state->nbTrans].to = target->no;
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state->trans[state->nbTrans].counter = counter;
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state->trans[state->nbTrans].count = count;
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state->trans[state->nbTrans].nd = 0;
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state->nbTrans++;
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStateAddTransTo(ctxt, target, state->no);
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegStatePush(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state) {
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state == NULL) return(-1);
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->maxStates == 0) {
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->maxStates = 4;
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->states = (xmlRegStatePtr *) xmlMalloc(ctxt->maxStates *
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                             sizeof(xmlRegStatePtr));
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->states == NULL) {
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "adding state");
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->maxStates = 0;
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (ctxt->nbStates >= ctxt->maxStates) {
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStatePtr *tmp;
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->maxStates *= 2;
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = (xmlRegStatePtr *) xmlRealloc(ctxt->states, ctxt->maxStates *
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                             sizeof(xmlRegStatePtr));
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == NULL) {
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(ctxt, "adding state");
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->maxStates /= 2;
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->states = tmp;
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state->no = ctxt->nbStates;
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->states[ctxt->nbStates++] = state;
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAGenerateAllTransition:
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from:  the from state
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to:  the target state or NULL for building a new one
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @lax:
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAGenerateAllTransition(xmlRegParserCtxtPtr ctxt,
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   xmlRegStatePtr from, xmlRegStatePtr to,
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   int lax) {
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL) {
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to = xmlRegNewState(ctxt);
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStatePush(ctxt, to);
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->state = to;
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (lax)
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_LAX_COUNTER);
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_COUNTER);
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAGenerateEpsilonTransition:
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from:  the from state
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to:  the target state or NULL for building a new one
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAGenerateEpsilonTransition(xmlRegParserCtxtPtr ctxt,
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       xmlRegStatePtr from, xmlRegStatePtr to) {
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL) {
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to = xmlRegNewState(ctxt);
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStatePush(ctxt, to);
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->state = to;
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStateAddTrans(ctxt, from, NULL, to, -1, -1);
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAGenerateCountedEpsilonTransition:
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from:  the from state
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to:  the target state or NULL for building a new one
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * counter:  the counter for that transition
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAGenerateCountedEpsilonTransition(xmlRegParserCtxtPtr ctxt,
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegStatePtr from, xmlRegStatePtr to, int counter) {
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL) {
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to = xmlRegNewState(ctxt);
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStatePush(ctxt, to);
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->state = to;
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStateAddTrans(ctxt, from, NULL, to, counter, -1);
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAGenerateCountedTransition:
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from:  the from state
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to:  the target state or NULL for building a new one
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * counter:  the counter for that transition
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAGenerateCountedTransition(xmlRegParserCtxtPtr ctxt,
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegStatePtr from, xmlRegStatePtr to, int counter) {
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL) {
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to = xmlRegNewState(ctxt);
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStatePush(ctxt, to);
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->state = to;
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStateAddTrans(ctxt, from, NULL, to, -1, counter);
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAGenerateTransitions:
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from:  the from state
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to:  the target state or NULL for building a new one
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom:  the atom generating the transition
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 0 if success and -1 in case of error.
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                 xmlRegStatePtr to, xmlRegAtomPtr atom) {
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr end;
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom == NULL) {
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("genrate transition: atom == NULL");
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom->type == XML_REGEXP_SUBREG) {
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * this is a subexpression handling one should not need to
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * create a new node except for XML_REGEXP_QUANT_RANGE.
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (xmlRegAtomPush(ctxt, atom) < 0) {
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((to != NULL) && (atom->stop != to) &&
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (atom->quant != XML_REGEXP_QUANT_RANGE)) {
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Generate an epsilon transition to link to the target
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to);
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DV
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if ((to == NULL) && (atom->quant != XML_REGEXP_QUANT_RANGE) &&
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   (atom->quant != XML_REGEXP_QUANT_ONCE)) {
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    to = xmlRegNewState(ctxt);
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegStatePush(ctxt, to);
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->state = to;
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to);
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (atom->quant) {
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_REGEXP_QUANT_OPT:
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		atom->quant = XML_REGEXP_QUANT_ONCE;
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * transition done to the state after end of atom.
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 *      1. set transition from atom start to new state
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 *      2. set transition from atom end to this state.
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (to == NULL) {
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    xmlFAGenerateEpsilonTransition(ctxt, atom->start, 0);
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    xmlFAGenerateEpsilonTransition(ctxt, atom->stop,
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   ctxt->state);
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                } else {
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    xmlFAGenerateEpsilonTransition(ctxt, atom->start, to);
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_REGEXP_QUANT_MULT:
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		atom->quant = XML_REGEXP_QUANT_ONCE;
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlFAGenerateEpsilonTransition(ctxt, atom->start, atom->stop);
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start);
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_REGEXP_QUANT_PLUS:
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		atom->quant = XML_REGEXP_QUANT_ONCE;
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start);
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_REGEXP_QUANT_RANGE: {
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int counter;
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegStatePtr inter, newstate;
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * create the final state now if needed
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (to != NULL) {
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    newstate = to;
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    newstate = xmlRegNewState(ctxt);
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRegStatePush(ctxt, newstate);
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * The principle here is to use counted transition
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * to avoid explosion in the number of states in the
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * graph. This is clearly more complex but should not
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * be exploitable at runtime.
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((atom->min == 0) && (atom->start0 == NULL)) {
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRegAtomPtr copy;
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * duplicate a transition based on atom to count next
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * occurences after 1. We cannot loop to atom->start
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * directly because we need an epsilon transition to
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * newstate.
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     /* ???? For some reason it seems we never reach that
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        case, I suppose this got optimized out before when
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			building the automata */
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    copy = xmlRegCopyAtom(ctxt, atom);
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (copy == NULL)
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        return(-1);
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    copy->quant = XML_REGEXP_QUANT_ONCE;
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    copy->min = 0;
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    copy->max = 0;
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (xmlFAGenerateTransitions(ctxt, atom->start, NULL, copy)
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        < 0)
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return(-1);
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    inter = ctxt->state;
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    counter = xmlRegGetCounter(ctxt);
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt->counters[counter].min = atom->min - 1;
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt->counters[counter].max = atom->max - 1;
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* count the number of times we see it again */
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFAGenerateCountedEpsilonTransition(ctxt, inter,
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						   atom->stop, counter);
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* allow a way out based on the count */
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFAGenerateCountedTransition(ctxt, inter,
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			                           newstate, counter);
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* and also allow a direct exit for 0 */
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFAGenerateEpsilonTransition(ctxt, atom->start,
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                                   newstate);
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * either we need the atom at least once or there
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * is an atom->start0 allowing to easilly plug the
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * epsilon transition.
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    counter = xmlRegGetCounter(ctxt);
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt->counters[counter].min = atom->min - 1;
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt->counters[counter].max = atom->max - 1;
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* count the number of times we see it again */
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFAGenerateCountedEpsilonTransition(ctxt, atom->stop,
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						   atom->start, counter);
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* allow a way out based on the count */
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFAGenerateCountedTransition(ctxt, atom->stop,
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			                           newstate, counter);
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* and if needed allow a direct exit for 0 */
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (atom->min == 0)
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFAGenerateEpsilonTransition(ctxt, atom->start0,
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						       newstate);
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		atom->min = 0;
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		atom->max = 0;
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		atom->quant = XML_REGEXP_QUANT_ONCE;
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ctxt->state = newstate;
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    default:
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((atom->min == 0) && (atom->max == 0) &&
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               (atom->quant == XML_REGEXP_QUANT_RANGE)) {
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * we can discard the atom and generate an epsilon transition instead
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (to == NULL) {
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    to = xmlRegNewState(ctxt);
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (to != NULL)
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegStatePush(ctxt, to);
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else {
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(-1);
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFAGenerateEpsilonTransition(ctxt, from, to);
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->state = to;
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegFreeAtom(atom);
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL) {
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to = xmlRegNewState(ctxt);
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (to != NULL)
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegStatePush(ctxt, to);
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else {
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    end = to;
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((atom->quant == XML_REGEXP_QUANT_MULT) ||
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (atom->quant == XML_REGEXP_QUANT_PLUS)) {
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Do not pollute the target state by adding transitions from
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * it as it is likely to be the shared target of multiple branches.
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * So isolate with an epsilon transition.
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlRegStatePtr tmp;
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = xmlRegNewState(ctxt);
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp != NULL)
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegStatePush(ctxt, tmp);
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else {
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFAGenerateEpsilonTransition(ctxt, tmp, to);
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to = tmp;
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xmlRegAtomPush(ctxt, atom) < 0) {
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStateAddTrans(ctxt, from, atom, to, -1, -1);
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->state = end;
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (atom->quant) {
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_REGEXP_QUANT_OPT:
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    atom->quant = XML_REGEXP_QUANT_ONCE;
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFAGenerateEpsilonTransition(ctxt, from, to);
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_REGEXP_QUANT_MULT:
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    atom->quant = XML_REGEXP_QUANT_ONCE;
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFAGenerateEpsilonTransition(ctxt, from, to);
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1);
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_REGEXP_QUANT_PLUS:
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    atom->quant = XML_REGEXP_QUANT_ONCE;
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1);
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_REGEXP_QUANT_RANGE:
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if DV_test
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (atom->min == 0) {
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlFAGenerateEpsilonTransition(ctxt, from, to);
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAReduceEpsilonTransitions:
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @fromnr:  the from state
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @tonr:  the to state
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @counter:  should that transition be associated to a counted
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int fromnr,
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                      int tonr, int counter) {
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int transnr;
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr from;
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr to;
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("xmlFAReduceEpsilonTransitions(%d, %d)\n", fromnr, tonr);
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    from = ctxt->states[fromnr];
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (from == NULL)
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to = ctxt->states[tonr];
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL)
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((to->mark == XML_REGEXP_MARK_START) ||
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(to->mark == XML_REGEXP_MARK_VISITED))
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->mark = XML_REGEXP_MARK_VISITED;
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to->type == XML_REGEXP_FINAL_STATE) {
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("State %d is final, so %d becomes final\n", tonr, fromnr);
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	from->type = XML_REGEXP_FINAL_STATE;
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (transnr = 0;transnr < to->nbTrans;transnr++) {
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (to->trans[transnr].to < 0)
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (to->trans[transnr].atom == NULL) {
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Don't remove counted transitions
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Don't loop either
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (to->trans[transnr].to != fromnr) {
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (to->trans[transnr].count >= 0) {
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int newto = to->trans[transnr].to;
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRegStateAddTrans(ctxt, from, NULL,
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					ctxt->states[newto],
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					-1, to->trans[transnr].count);
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Found epsilon trans %d from %d to %d\n",
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   transnr, tonr, to->trans[transnr].to);
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (to->trans[transnr].counter >= 0) {
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFAReduceEpsilonTransitions(ctxt, fromnr,
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					      to->trans[transnr].to,
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					      to->trans[transnr].counter);
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFAReduceEpsilonTransitions(ctxt, fromnr,
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					      to->trans[transnr].to,
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					      counter);
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int newto = to->trans[transnr].to;
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (to->trans[transnr].counter >= 0) {
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom,
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    ctxt->states[newto],
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    to->trans[transnr].counter, -1);
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom,
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    ctxt->states[newto], counter, -1);
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to->mark = XML_REGEXP_MARK_NORMAL;
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAEliminateSimpleEpsilonTransitions:
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Eliminating general epsilon transitions can get costly in the general
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * algorithm due to the large amount of generated new transitions and
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * associated comparisons. However for simple epsilon transition used just
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to separate building blocks when generating the automata this can be
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reduced to state elimination:
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    - if there exists an epsilon from X to Y
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    - if there is no other transition from X
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * then X and Y are semantically equivalent and X can be eliminated
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If X is the start state then make Y the start state, else replace the
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * target of all transitions to X by transitions to Y.
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int statenr, i, j, newto;
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr state, tmp;
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state = ctxt->states[statenr];
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (state == NULL)
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (state->nbTrans != 1)
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (state->type == XML_REGEXP_UNREACH_STATE)
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* is the only transition out a basic transition */
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((state->trans[0].atom == NULL) &&
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (state->trans[0].to >= 0) &&
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (state->trans[0].to != statenr) &&
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (state->trans[0].counter < 0) &&
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (state->trans[0].count < 0)) {
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    newto = state->trans[0].to;
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (state->type == XML_REGEXP_START_STATE) {
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("Found simple epsilon trans from start %d to %d\n",
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       statenr, newto);
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("Found simple epsilon trans from %d to %d\n",
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       statenr, newto);
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        for (i = 0;i < state->nbTransTo;i++) {
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    tmp = ctxt->states[state->transTo[i]];
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    for (j = 0;j < tmp->nbTrans;j++) {
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (tmp->trans[j].to == statenr) {
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    printf("Changed transition %d on %d to go to %d\n",
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   j, tmp->no, newto);
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    tmp->trans[j].to = -1;
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlRegStateAddTrans(ctxt, tmp, tmp->trans[j].atom,
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    			ctxt->states[newto],
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					        tmp->trans[j].counter,
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						tmp->trans[j].count);
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (state->type == XML_REGEXP_FINAL_STATE)
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt->states[newto]->type = XML_REGEXP_FINAL_STATE;
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* eliminate the transition completely */
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		state->nbTrans = 0;
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                state->type = XML_REGEXP_UNREACH_STATE;
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAEliminateEpsilonTransitions:
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAEliminateEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int statenr, transnr;
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr state;
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int has_epsilon;
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->states == NULL) return;
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Eliminate simple epsilon transition and the associated unreachable
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * states.
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFAEliminateSimpleEpsilonTransitions(ctxt);
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state = ctxt->states[statenr];
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((state != NULL) && (state->type == XML_REGEXP_UNREACH_STATE)) {
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("Removed unreachable state %d\n", statenr);
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegFreeState(state);
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->states[statenr] = NULL;
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_epsilon = 0;
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Build the completed transitions bypassing the epsilons
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Use a marking algorithm to avoid loops
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Mark sink states too.
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Process from the latests states backward to the start when
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * there is long cascading epsilon chains this minimize the
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * recursions and transition compares when adding the new ones
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (statenr = ctxt->nbStates - 1;statenr >= 0;statenr--) {
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state = ctxt->states[statenr];
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (state == NULL)
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((state->nbTrans == 0) &&
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (state->type != XML_REGEXP_FINAL_STATE)) {
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    state->type = XML_REGEXP_SINK_STATE;
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (transnr = 0;transnr < state->nbTrans;transnr++) {
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((state->trans[transnr].atom == NULL) &&
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(state->trans[transnr].to >= 0)) {
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (state->trans[transnr].to == statenr) {
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    state->trans[transnr].to = -1;
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Removed loopback epsilon trans %d on %d\n",
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   transnr, statenr);
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if (state->trans[transnr].count < 0) {
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int newto = state->trans[transnr].to;
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Found epsilon trans %d from %d to %d\n",
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   transnr, statenr, newto);
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    has_epsilon = 1;
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    state->trans[transnr].to = -2;
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    state->mark = XML_REGEXP_MARK_START;
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFAReduceEpsilonTransitions(ctxt, statenr,
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				      newto, state->trans[transnr].counter);
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    state->mark = XML_REGEXP_MARK_NORMAL;
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Found counted transition %d on %d\n",
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   transnr, statenr);
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        }
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Eliminate the epsilon transitions
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_epsilon) {
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    state = ctxt->states[statenr];
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (state == NULL)
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (transnr = 0;transnr < state->nbTrans;transnr++) {
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegTransPtr trans = &(state->trans[transnr]);
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((trans->atom == NULL) &&
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (trans->count < 0) &&
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (trans->to >= 0)) {
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    trans->to = -1;
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Use this pass to detect unreachable states too
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state = ctxt->states[statenr];
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (state != NULL)
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    state->reached = XML_REGEXP_MARK_NORMAL;
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state = ctxt->states[0];
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state != NULL)
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state->reached = XML_REGEXP_MARK_START;
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (state != NULL) {
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStatePtr target = NULL;
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state->reached = XML_REGEXP_MARK_VISITED;
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Mark all states reachable from the current reachable state
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (transnr = 0;transnr < state->nbTrans;transnr++) {
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((state->trans[transnr].to >= 0) &&
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		((state->trans[transnr].atom != NULL) ||
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (state->trans[transnr].count >= 0))) {
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int newto = state->trans[transnr].to;
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (ctxt->states[newto] == NULL)
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    continue;
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (ctxt->states[newto]->reached == XML_REGEXP_MARK_NORMAL) {
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt->states[newto]->reached = XML_REGEXP_MARK_START;
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    target = ctxt->states[newto];
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * find the next accessible state not explored
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (target == NULL) {
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (statenr = 1;statenr < ctxt->nbStates;statenr++) {
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		state = ctxt->states[statenr];
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((state != NULL) && (state->reached ==
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			XML_REGEXP_MARK_START)) {
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    target = state;
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state = target;
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state = ctxt->states[statenr];
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((state != NULL) && (state->reached == XML_REGEXP_MARK_NORMAL)) {
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("Removed unreachable state %d\n", statenr);
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegFreeState(state);
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->states[statenr] = NULL;
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFACompareRanges(xmlRegRangePtr range1, xmlRegRangePtr range2) {
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret = 0;
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((range1->type == XML_REGEXP_RANGES) ||
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (range2->type == XML_REGEXP_RANGES) ||
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (range2->type == XML_REGEXP_SUBREG) ||
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (range1->type == XML_REGEXP_SUBREG) ||
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (range1->type == XML_REGEXP_STRING) ||
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (range2->type == XML_REGEXP_STRING))
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* put them in order */
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range1->type > range2->type) {
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlRegRangePtr tmp;
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = range1;
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	range1 = range2;
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	range2 = tmp;
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((range1->type == XML_REGEXP_ANYCHAR) ||
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (range2->type == XML_REGEXP_ANYCHAR)) {
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = 1;
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((range1->type == XML_REGEXP_EPSILON) ||
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               (range2->type == XML_REGEXP_EPSILON)) {
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (range1->type == range2->type) {
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (range1->type != XML_REGEXP_CHARVAL)
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ret = 1;
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else if ((range1->end < range2->start) ||
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         (range2->end < range1->start))
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 1;
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (range1->type == XML_REGEXP_CHARVAL) {
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int codepoint;
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int neg = 0;
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * just check all codepoints in the range for acceptance,
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * this is usually way cheaper since done only once at
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * compilation than testing over and over at runtime or
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * pushing too many states when evaluating.
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (((range1->neg == 0) && (range2->neg != 0)) ||
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ((range1->neg != 0) && (range2->neg == 0)))
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    neg = 1;
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (codepoint = range1->start;codepoint <= range1->end ;codepoint++) {
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlRegCheckCharacterRange(range2->type, codepoint,
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    0, range2->start, range2->end,
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    range2->blockName);
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret < 0)
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(-1);
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (((neg == 1) && (ret == 0)) ||
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((neg == 0) && (ret == 1)))
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(1);
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((range1->type == XML_REGEXP_BLOCK_NAME) ||
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               (range2->type == XML_REGEXP_BLOCK_NAME)) {
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (range1->type == range2->type) {
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlStrEqual(range1->blockName, range2->blockName);
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * comparing a block range with anything else is way
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * too costly, and maintining the table is like too much
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * memory too, so let's force the automata to save state
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * here.
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(1);
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((range1->type < XML_REGEXP_LETTER) ||
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               (range2->type < XML_REGEXP_LETTER)) {
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((range1->type == XML_REGEXP_ANYSPACE) &&
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (range2->type == XML_REGEXP_NOTSPACE))
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else if ((range1->type == XML_REGEXP_INITNAME) &&
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         (range2->type == XML_REGEXP_NOTINITNAME))
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else if ((range1->type == XML_REGEXP_NAMECHAR) &&
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         (range2->type == XML_REGEXP_NOTNAMECHAR))
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else if ((range1->type == XML_REGEXP_DECIMAL) &&
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         (range2->type == XML_REGEXP_NOTDECIMAL))
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else if ((range1->type == XML_REGEXP_REALCHAR) &&
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         (range2->type == XML_REGEXP_NOTREALCHAR))
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else {
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* same thing to limit complexity */
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(1);
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = 0;
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* range1->type < range2->type here */
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switch (range1->type) {
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_REGEXP_LETTER:
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         /* all disjoint except in the subgroups */
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         if ((range2->type == XML_REGEXP_LETTER_UPPERCASE) ||
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_LETTER_LOWERCASE) ||
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_LETTER_TITLECASE) ||
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_LETTER_MODIFIER) ||
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_LETTER_OTHERS))
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     ret = 1;
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 break;
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_REGEXP_MARK:
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         if ((range2->type == XML_REGEXP_MARK_NONSPACING) ||
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_MARK_SPACECOMBINING) ||
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_MARK_ENCLOSING))
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     ret = 1;
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 break;
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_REGEXP_NUMBER:
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         if ((range2->type == XML_REGEXP_NUMBER_DECIMAL) ||
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_NUMBER_LETTER) ||
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_NUMBER_OTHERS))
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     ret = 1;
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 break;
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_REGEXP_PUNCT:
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         if ((range2->type == XML_REGEXP_PUNCT_CONNECTOR) ||
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_PUNCT_DASH) ||
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_PUNCT_OPEN) ||
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_PUNCT_CLOSE) ||
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_PUNCT_INITQUOTE) ||
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_PUNCT_FINQUOTE) ||
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_PUNCT_OTHERS))
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     ret = 1;
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 break;
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_REGEXP_SEPAR:
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         if ((range2->type == XML_REGEXP_SEPAR_SPACE) ||
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_SEPAR_LINE) ||
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_SEPAR_PARA))
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     ret = 1;
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 break;
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_REGEXP_SYMBOL:
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         if ((range2->type == XML_REGEXP_SYMBOL_MATH) ||
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_SYMBOL_CURRENCY) ||
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_SYMBOL_MODIFIER) ||
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_SYMBOL_OTHERS))
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     ret = 1;
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 break;
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_REGEXP_OTHER:
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         if ((range2->type == XML_REGEXP_OTHER_CONTROL) ||
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_OTHER_FORMAT) ||
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type == XML_REGEXP_OTHER_PRIVATE))
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     ret = 1;
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 break;
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            default:
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         if ((range2->type >= XML_REGEXP_LETTER) &&
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (range2->type < XML_REGEXP_BLOCK_NAME))
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     ret = 0;
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 else {
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     /* safety net ! */
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     return(1);
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 }
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (((range1->neg == 0) && (range2->neg != 0)) ||
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ((range1->neg != 0) && (range2->neg == 0)))
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = !ret;
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFACompareAtomTypes:
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type1:  an atom type
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type2:  an atom type
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compares two atoms type to check whether they intersect in some ways,
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is used by xmlFACompareAtoms only
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if they may intersect and 0 otherwise
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFACompareAtomTypes(xmlRegAtomType type1, xmlRegAtomType type2) {
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((type1 == XML_REGEXP_EPSILON) ||
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (type1 == XML_REGEXP_CHARVAL) ||
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(type1 == XML_REGEXP_RANGES) ||
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(type1 == XML_REGEXP_SUBREG) ||
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(type1 == XML_REGEXP_STRING) ||
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(type1 == XML_REGEXP_ANYCHAR))
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((type2 == XML_REGEXP_EPSILON) ||
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (type2 == XML_REGEXP_CHARVAL) ||
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(type2 == XML_REGEXP_RANGES) ||
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(type2 == XML_REGEXP_SUBREG) ||
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(type2 == XML_REGEXP_STRING) ||
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(type2 == XML_REGEXP_ANYCHAR))
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (type1 == type2) return(1);
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* simplify subsequent compares by making sure type1 < type2 */
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (type1 > type2) {
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlRegAtomType tmp = type1;
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	type1 = type2;
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	type2 = tmp;
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (type1) {
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_ANYSPACE: /* \s */
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* can't be a letter, number, mark, pontuation, symbol */
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((type2 == XML_REGEXP_NOTSPACE) ||
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		((type2 >= XML_REGEXP_LETTER) &&
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_LETTER_OTHERS)) ||
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_NUMBER) &&
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_NUMBER_OTHERS)) ||
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_MARK) &&
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_MARK_ENCLOSING)) ||
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_PUNCT) &&
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_PUNCT_OTHERS)) ||
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_SYMBOL) &&
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_SYMBOL_OTHERS))
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ) return(0);
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTSPACE: /* \S */
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_INITNAME: /* \l */
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* can't be a number, mark, separator, pontuation, symbol or other */
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((type2 == XML_REGEXP_NOTINITNAME) ||
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_NUMBER) &&
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_NUMBER_OTHERS)) ||
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_MARK) &&
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_MARK_ENCLOSING)) ||
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_SEPAR) &&
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_SEPAR_PARA)) ||
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_PUNCT) &&
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_PUNCT_OTHERS)) ||
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_SYMBOL) &&
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_SYMBOL_OTHERS)) ||
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_OTHER) &&
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_OTHER_NA))
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		) return(0);
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTINITNAME: /* \L */
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NAMECHAR: /* \c */
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* can't be a mark, separator, pontuation, symbol or other */
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((type2 == XML_REGEXP_NOTNAMECHAR) ||
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_MARK) &&
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_MARK_ENCLOSING)) ||
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_PUNCT) &&
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_PUNCT_OTHERS)) ||
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_SEPAR) &&
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_SEPAR_PARA)) ||
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_SYMBOL) &&
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_SYMBOL_OTHERS)) ||
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_OTHER) &&
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_OTHER_NA))
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		) return(0);
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTNAMECHAR: /* \C */
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_DECIMAL: /* \d */
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* can't be a letter, mark, separator, pontuation, symbol or other */
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((type2 == XML_REGEXP_NOTDECIMAL) ||
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (type2 == XML_REGEXP_REALCHAR) ||
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		((type2 >= XML_REGEXP_LETTER) &&
23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_LETTER_OTHERS)) ||
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_MARK) &&
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_MARK_ENCLOSING)) ||
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_PUNCT) &&
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_PUNCT_OTHERS)) ||
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_SEPAR) &&
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_SEPAR_PARA)) ||
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_SYMBOL) &&
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_SYMBOL_OTHERS)) ||
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_OTHER) &&
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_OTHER_NA))
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		)return(0);
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTDECIMAL: /* \D */
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_REALCHAR: /* \w */
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* can't be a mark, separator, pontuation, symbol or other */
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((type2 == XML_REGEXP_NOTDECIMAL) ||
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_MARK) &&
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_MARK_ENCLOSING)) ||
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_PUNCT) &&
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_PUNCT_OTHERS)) ||
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_SEPAR) &&
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_SEPAR_PARA)) ||
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_SYMBOL) &&
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_SYMBOL_OTHERS)) ||
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ((type2 >= XML_REGEXP_OTHER) &&
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (type2 <= XML_REGEXP_OTHER_NA))
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		)return(0);
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTREALCHAR: /* \W */
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * at that point we know both type 1 and type2 are from
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * character categories are ordered and are different,
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * it becomes simple because this is a partition
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER:
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (type2 <= XML_REGEXP_LETTER_OTHERS)
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(1);
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_UPPERCASE:
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_LOWERCASE:
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_TITLECASE:
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_MODIFIER:
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_OTHERS:
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK:
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (type2 <= XML_REGEXP_MARK_ENCLOSING)
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(1);
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK_NONSPACING:
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK_SPACECOMBINING:
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK_ENCLOSING:
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER:
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (type2 <= XML_REGEXP_NUMBER_OTHERS)
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(1);
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER_DECIMAL:
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER_LETTER:
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER_OTHERS:
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT:
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (type2 <= XML_REGEXP_PUNCT_OTHERS)
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(1);
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_CONNECTOR:
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_DASH:
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_OPEN:
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_CLOSE:
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_INITQUOTE:
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_FINQUOTE:
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_OTHERS:
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR:
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (type2 <= XML_REGEXP_SEPAR_PARA)
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(1);
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR_SPACE:
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR_LINE:
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR_PARA:
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL:
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (type2 <= XML_REGEXP_SYMBOL_OTHERS)
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(1);
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_MATH:
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_CURRENCY:
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_MODIFIER:
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_OTHERS:
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER:
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (type2 <= XML_REGEXP_OTHER_NA)
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(1);
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_CONTROL:
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_FORMAT:
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_PRIVATE:
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_NA:
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(1);
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAEqualAtoms:
24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom1:  an atom
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom2:  an atom
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @deep: if not set only compare string pointers
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compares two atoms to check whether they are the same exactly
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is used to remove equivalent transitions
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if same and 0 otherwise
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAEqualAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) {
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret = 0;
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom1 == atom2)
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((atom1 == NULL) || (atom2 == NULL))
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom1->type != atom2->type)
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(0);
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (atom1->type) {
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_EPSILON:
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_STRING:
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (!deep)
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ret = (atom1->valuep == atom2->valuep);
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ret = xmlStrEqual((xmlChar *)atom1->valuep,
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  (xmlChar *)atom2->valuep);
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_CHARVAL:
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = (atom1->codepoint == atom2->codepoint);
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_REGEXP_RANGES:
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* too hard to do in the general case */
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFACompareAtoms:
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom1:  an atom
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom2:  an atom
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @deep: if not set only compare string pointers
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compares two atoms to check whether they intersect in some ways,
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is used by xmlFAComputesDeterminism and xmlFARecurseDeterminism only
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if yes and 0 otherwise
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFACompareAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) {
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret = 1;
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom1 == atom2)
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((atom1 == NULL) || (atom2 == NULL))
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((atom1->type == XML_REGEXP_ANYCHAR) ||
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (atom2->type == XML_REGEXP_ANYCHAR))
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom1->type > atom2->type) {
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegAtomPtr tmp;
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = atom1;
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom1 = atom2;
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom2 = tmp;
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom1->type != atom2->type) {
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = xmlFACompareAtomTypes(atom1->type, atom2->type);
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* if they can't intersect at the type level break now */
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret == 0)
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (atom1->type) {
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_STRING:
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (!deep)
25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ret = (atom1->valuep != atom2->valuep);
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ret = xmlRegStrEqualWildcard((xmlChar *)atom1->valuep,
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             (xmlChar *)atom2->valuep);
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_EPSILON:
25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto not_determinist;
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_CHARVAL:
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (atom2->type == XML_REGEXP_CHARVAL) {
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = (atom1->codepoint == atom2->codepoint);
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ret = xmlRegCheckCharacter(atom2, atom1->codepoint);
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (ret < 0)
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = 1;
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_RANGES:
25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (atom2->type == XML_REGEXP_RANGES) {
25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        int i, j, res;
25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegRangePtr r1, r2;
25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * need to check that none of the ranges eventually matches
25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		for (i = 0;i < atom1->nbRanges;i++) {
25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    for (j = 0;j < atom2->nbRanges;j++) {
25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			r1 = atom1->ranges[i];
25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			r2 = atom2->ranges[j];
25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			res = xmlFACompareRanges(r1, r2);
25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (res == 1) {
25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    ret = 1;
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    goto done;
25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = 0;
25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto not_determinist;
25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)done:
25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom1->neg != atom2->neg) {
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = !ret;
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == 0)
25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(0);
25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)not_determinist:
25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(1);
25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFARecurseDeterminism:
25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check whether the associated regexp is determinist,
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * should be called after xmlFAEliminateEpsilonTransitions()
25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                 int to, xmlRegAtomPtr atom) {
25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret = 1;
25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int res;
25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int transnr, nbTrans;
25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegTransPtr t1;
25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int deep = 1;
25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state == NULL)
25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(ret);
25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->flags & AM_AUTOMATA_RNG)
25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        deep = 0;
25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * don't recurse on transitions potentially added in the course of
25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * the elimination.
25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nbTrans = state->nbTrans;
25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (transnr = 0;transnr < nbTrans;transnr++) {
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	t1 = &(state->trans[transnr]);
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * check transitions conflicting with the one looked at
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (t1->atom == NULL) {
26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (t1->to < 0)
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    res = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to],
26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                           to, atom);
26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (res == 0) {
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ret = 0;
26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* t1->nd = 1; */
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (t1->to != to)
26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (xmlFACompareAtoms(t1->atom, atom, deep)) {
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* mark the transition as non-deterministic */
26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    t1->nd = 1;
26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAComputesDeterminism:
26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check whether the associated regexp is determinist,
26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * should be called after xmlFAEliminateEpsilonTransitions()
26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) {
26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int statenr, transnr;
26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr state;
26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegTransPtr t1, t2, last;
26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret = 1;
26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int deep = 1;
26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("xmlFAComputesDeterminism\n");
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegPrintCtxt(stdout, ctxt);
26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->determinist != -1)
26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(ctxt->determinist);
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->flags & AM_AUTOMATA_RNG)
26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        deep = 0;
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * First cleanup the automata removing cancelled transitions
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state = ctxt->states[statenr];
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (state == NULL)
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (state->nbTrans < 2)
26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (transnr = 0;transnr < state->nbTrans;transnr++) {
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    t1 = &(state->trans[transnr]);
26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Determinism checks in case of counted or all transitions
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * will have to be handled separately
26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (t1->atom == NULL) {
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* t1->nd = 1; */
26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (t1->to == -1) /* eliminated */
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i = 0;i < transnr;i++) {
26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		t2 = &(state->trans[i]);
26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (t2->to == -1) /* eliminated */
26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    continue;
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (t2->atom != NULL) {
26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (t1->to == t2->to) {
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /*
26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         * Here we use deep because we want to keep the
26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         * transitions which indicate a conflict
26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         */
26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (xmlFAEqualAtoms(t1->atom, t2->atom, deep) &&
26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            (t1->counter == t2->counter) &&
26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            (t1->count == t2->count))
26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    t2->to = -1; /* eliminated */
26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Check for all states that there aren't 2 transitions
26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * with the same atom and a different target.
26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	state = ctxt->states[statenr];
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (state == NULL)
27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (state->nbTrans < 2)
27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	last = NULL;
27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (transnr = 0;transnr < state->nbTrans;transnr++) {
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    t1 = &(state->trans[transnr]);
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Determinism checks in case of counted or all transitions
27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * will have to be handled separately
27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (t1->atom == NULL) {
27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (t1->to == -1) /* eliminated */
27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i = 0;i < transnr;i++) {
27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		t2 = &(state->trans[i]);
27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (t2->to == -1) /* eliminated */
27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    continue;
27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (t2->atom != NULL) {
27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /*
27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     * But here we don't use deep because we want to
27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     * find transitions which indicate a conflict
27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     */
27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (xmlFACompareAtoms(t1->atom, t2->atom, 1)) {
27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ret = 0;
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/* mark the transitions as non-deterministic ones */
27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			t1->nd = 1;
27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			t2->nd = 1;
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			last = t1;
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if (t1->to != -1) {
27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * do the closure in case of remaining specific
27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * epsilon transitions like choices or all
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to],
27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						   t2->to, t2->atom);
27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* don't shortcut the computation so all non deterministic
27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       transition get marked down
27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (ret == 0)
27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return(0);
27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (ret == 0) {
27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			t1->nd = 1;
27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/* t2->nd = 1; */
27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			last = t1;
27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* don't shortcut the computation so all non deterministic
27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       transition get marked down
27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret == 0)
27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break; */
27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * mark specifically the last non-deterministic transition
27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * from a state since there is no need to set-up rollback
27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * from it
27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (last != NULL) {
27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    last->nd = 2;
27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* don't shortcut the computation so all non deterministic
27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   transition get marked down
27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret == 0)
27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break; */
27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->determinist = ret;
27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *	Routines to check input against transition atoms		*
27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, int neg,
27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                  int start, int end, const xmlChar *blockName) {
27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret = 0;
27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (type) {
27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_STRING:
27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SUBREG:
27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_RANGES:
27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_EPSILON:
27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_ANYCHAR:
27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = ((codepoint != '\n') && (codepoint != '\r'));
27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_CHARVAL:
27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = ((codepoint >= start) && (codepoint <= end));
27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTSPACE:
27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    neg = !neg;
28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_ANYSPACE:
28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = ((codepoint == '\n') || (codepoint == '\r') ||
28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   (codepoint == '\t') || (codepoint == ' '));
28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTINITNAME:
28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    neg = !neg;
28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_INITNAME:
28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = (IS_LETTER(codepoint) ||
28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   (codepoint == '_') || (codepoint == ':'));
28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTNAMECHAR:
28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    neg = !neg;
28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NAMECHAR:
28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = (IS_LETTER(codepoint) || IS_DIGIT(codepoint) ||
28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   (codepoint == '.') || (codepoint == '-') ||
28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   (codepoint == '_') || (codepoint == ':') ||
28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   IS_COMBINING(codepoint) || IS_EXTENDER(codepoint));
28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTDECIMAL:
28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    neg = !neg;
28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_DECIMAL:
28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatNd(codepoint);
28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_REALCHAR:
28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    neg = !neg;
28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTREALCHAR:
28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatP(codepoint);
28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret == 0)
28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = xmlUCSIsCatZ(codepoint);
28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret == 0)
28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = xmlUCSIsCatC(codepoint);
28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER:
28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatL(codepoint);
28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_UPPERCASE:
28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatLu(codepoint);
28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_LOWERCASE:
28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatLl(codepoint);
28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_TITLECASE:
28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatLt(codepoint);
28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_MODIFIER:
28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatLm(codepoint);
28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_OTHERS:
28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatLo(codepoint);
28495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK:
28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatM(codepoint);
28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK_NONSPACING:
28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatMn(codepoint);
28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK_SPACECOMBINING:
28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatMc(codepoint);
28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK_ENCLOSING:
28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatMe(codepoint);
28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER:
28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatN(codepoint);
28645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER_DECIMAL:
28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatNd(codepoint);
28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER_LETTER:
28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatNl(codepoint);
28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER_OTHERS:
28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatNo(codepoint);
28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT:
28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatP(codepoint);
28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_CONNECTOR:
28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatPc(codepoint);
28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_DASH:
28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatPd(codepoint);
28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_OPEN:
28845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatPs(codepoint);
28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_CLOSE:
28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatPe(codepoint);
28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_INITQUOTE:
28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatPi(codepoint);
28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_FINQUOTE:
28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatPf(codepoint);
28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_OTHERS:
28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatPo(codepoint);
28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR:
28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatZ(codepoint);
29005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR_SPACE:
29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatZs(codepoint);
29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR_LINE:
29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatZl(codepoint);
29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR_PARA:
29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatZp(codepoint);
29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL:
29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatS(codepoint);
29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_MATH:
29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatSm(codepoint);
29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_CURRENCY:
29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatSc(codepoint);
29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_MODIFIER:
29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatSk(codepoint);
29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_OTHERS:
29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatSo(codepoint);
29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER:
29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatC(codepoint);
29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_CONTROL:
29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatCc(codepoint);
29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_FORMAT:
29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatCf(codepoint);
29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_PRIVATE:
29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsCatCo(codepoint);
29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_NA:
29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* ret = xmlUCSIsCatCn(codepoint); */
29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Seems it doesn't exist anymore in recent Unicode releases */
29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_BLOCK_NAME:
29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUCSIsBlock(codepoint, (const char *) blockName);
29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (neg)
29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(!ret);
29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint) {
29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i, ret = 0;
29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegRangePtr range;
29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((atom == NULL) || (!IS_CHAR(codepoint)))
29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (atom->type) {
29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SUBREG:
29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_EPSILON:
29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_CHARVAL:
29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return(codepoint == atom->codepoint);
29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_RANGES: {
29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int accept = 0;
29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i = 0;i < atom->nbRanges;i++) {
29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		range = atom->ranges[i];
29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (range->neg == 2) {
29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = xmlRegCheckCharacterRange(range->type, codepoint,
29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						0, range->start, range->end,
29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						range->blockName);
29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (ret != 0)
29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return(0); /* excluded char */
29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if (range->neg) {
29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = xmlRegCheckCharacterRange(range->type, codepoint,
29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						0, range->start, range->end,
29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						range->blockName);
29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (ret == 0)
29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        accept = 1;
29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    else
29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        return(0);
29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = xmlRegCheckCharacterRange(range->type, codepoint,
29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						0, range->start, range->end,
29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						range->blockName);
29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (ret != 0)
29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			accept = 1; /* might still be excluded */
29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(accept);
29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_STRING:
29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("TODO: XML_REGEXP_STRING\n");
29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_ANYCHAR:
29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_ANYSPACE:
29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTSPACE:
30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_INITNAME:
30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTINITNAME:
30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NAMECHAR:
30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTNAMECHAR:
30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_DECIMAL:
30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTDECIMAL:
30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_REALCHAR:
30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NOTREALCHAR:
30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER:
30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_UPPERCASE:
30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_LOWERCASE:
30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_TITLECASE:
30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_MODIFIER:
30135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_LETTER_OTHERS:
30145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK:
30155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK_NONSPACING:
30165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK_SPACECOMBINING:
30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_MARK_ENCLOSING:
30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER:
30195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER_DECIMAL:
30205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER_LETTER:
30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_NUMBER_OTHERS:
30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT:
30235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_CONNECTOR:
30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_DASH:
30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_OPEN:
30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_CLOSE:
30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_INITQUOTE:
30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_FINQUOTE:
30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_PUNCT_OTHERS:
30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR:
30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR_SPACE:
30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR_LINE:
30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SEPAR_PARA:
30345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL:
30355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_MATH:
30365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_CURRENCY:
30375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_MODIFIER:
30385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_SYMBOL_OTHERS:
30395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER:
30405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_CONTROL:
30415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_FORMAT:
30425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_PRIVATE:
30435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_REGEXP_OTHER_NA:
30445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_REGEXP_BLOCK_NAME:
30455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlRegCheckCharacterRange(atom->type, codepoint, 0, 0, 0,
30465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                            (const xmlChar *)atom->valuep);
30475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (atom->neg)
30485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = !ret;
30495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
30505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
30515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
30525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
30555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
30565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *	Saving and restoring state of an execution context		*
30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
30585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
30615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFARegDebugExec(xmlRegExecCtxtPtr exec) {
30635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("state: %d:%d:idx %d", exec->state->no, exec->transno, exec->index);
30645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->inputStack != NULL) {
30655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i;
30665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf(": ");
30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;(i < 3) && (i < exec->inputStackNr);i++)
30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("%s ", (const char *)
30695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	           exec->inputStack[exec->inputStackNr - (i + 1)].value);
30705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
30715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf(": %s", &(exec->inputString[exec->index]));
30725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
30735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("\n");
30745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
30765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
30785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFARegExecSave(xmlRegExecCtxtPtr exec) {
30795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
30805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("saving ");
30815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->transno++;
30825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFARegDebugExec(exec);
30835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->transno--;
30845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
30855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef MAX_PUSH
30865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->nbPush > MAX_PUSH) {
30875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
30885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
30895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->nbPush++;
30905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
30915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->maxRollbacks == 0) {
30935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->maxRollbacks = 4;
30945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->rollbacks = (xmlRegExecRollback *) xmlMalloc(exec->maxRollbacks *
30955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                             sizeof(xmlRegExecRollback));
30965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (exec->rollbacks == NULL) {
30975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(NULL, "saving regexp");
30985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exec->maxRollbacks = 0;
30995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
31005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
31015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memset(exec->rollbacks, 0,
31025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       exec->maxRollbacks * sizeof(xmlRegExecRollback));
31035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (exec->nbRollbacks >= exec->maxRollbacks) {
31045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegExecRollback *tmp;
31055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int len = exec->maxRollbacks;
31065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->maxRollbacks *= 2;
31085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = (xmlRegExecRollback *) xmlRealloc(exec->rollbacks,
31095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exec->maxRollbacks * sizeof(xmlRegExecRollback));
31105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == NULL) {
31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(NULL, "saving regexp");
31125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exec->maxRollbacks /= 2;
31135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->rollbacks = tmp;
31165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = &exec->rollbacks[len];
31175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memset(tmp, 0, (exec->maxRollbacks - len) * sizeof(xmlRegExecRollback));
31185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
31195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->rollbacks[exec->nbRollbacks].state = exec->state;
31205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->rollbacks[exec->nbRollbacks].index = exec->index;
31215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->rollbacks[exec->nbRollbacks].nextbranch = exec->transno + 1;
31225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->comp->nbCounters > 0) {
31235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
31245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exec->rollbacks[exec->nbRollbacks].counts = (int *)
31255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlMalloc(exec->comp->nbCounters * sizeof(int));
31265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
31275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegexpErrMemory(NULL, "saving regexp");
31285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->status = -5;
31295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
31305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
31315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
31325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memcpy(exec->rollbacks[exec->nbRollbacks].counts, exec->counts,
31335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       exec->comp->nbCounters * sizeof(int));
31345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
31355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->nbRollbacks++;
31365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
31375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
31395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFARegExecRollBack(xmlRegExecCtxtPtr exec) {
31405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->nbRollbacks <= 0) {
31415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->status = -1;
31425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
31435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("rollback failed on empty stack\n");
31445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
31455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
31465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
31475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->nbRollbacks--;
31485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->state = exec->rollbacks[exec->nbRollbacks].state;
31495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->index = exec->rollbacks[exec->nbRollbacks].index;
31505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->transno = exec->rollbacks[exec->nbRollbacks].nextbranch;
31515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->comp->nbCounters > 0) {
31525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
31535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(stderr, "exec save: allocation failed");
31545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exec->status = -6;
31555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
31565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
31575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memcpy(exec->counts, exec->rollbacks[exec->nbRollbacks].counts,
31585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       exec->comp->nbCounters * sizeof(int));
31595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
31605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
31625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("restored ");
31635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFARegDebugExec(exec);
31645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
31655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
31665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
31685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
31695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *	Verifier, running an input against a compiled regexp		*
31705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
31715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
31725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
31745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
31755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegExecCtxt execval;
31765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegExecCtxtPtr exec = &execval;
31775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret, codepoint = 0, len, deter;
31785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->inputString = content;
31805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->index = 0;
31815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->nbPush = 0;
31825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->determinist = 1;
31835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->maxRollbacks = 0;
31845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->nbRollbacks = 0;
31855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->rollbacks = NULL;
31865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->status = 0;
31875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->comp = comp;
31885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->state = comp->states[0];
31895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->transno = 0;
31905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->transcount = 0;
31915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->inputStack = NULL;
31925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->inputStackMax = 0;
31935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (comp->nbCounters > 0) {
31945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int));
31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (exec->counts == NULL) {
31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(NULL, "running regexp");
31975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
31985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        memset(exec->counts, 0, comp->nbCounters * sizeof(int));
32005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else
32015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->counts = NULL;
32025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((exec->status == 0) &&
32035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   ((exec->inputString[exec->index] != 0) ||
32045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ((exec->state != NULL) &&
32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     (exec->state->type != XML_REGEXP_FINAL_STATE)))) {
32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegTransPtr trans;
32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegAtomPtr atom;
32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * If end of input on non-terminal state, rollback, however we may
32115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * still have epsilon like transition for counted transitions
32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * on counters, in that case don't break too early.  Additionally,
32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * if we are working on a range like "AB{0,2}", where B is not present,
32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * we don't want to break.
32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len = 1;
32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL)) {
32185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * if there is a transition, we must check if
32205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     *  atom allows minOccurs of 0
32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
32225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exec->transno < exec->state->nbTrans) {
32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        trans = &exec->state->trans[exec->transno];
32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (trans->to >=0) {
32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    atom = trans->atom;
32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (!((atom->min == 0) && (atom->max > 0)))
32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        goto rollback;
32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else
32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        goto rollback;
32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->transcount = 0;
32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (;exec->transno < exec->state->nbTrans;exec->transno++) {
32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    trans = &exec->state->trans[exec->transno];
32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (trans->to < 0)
32375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
32385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    atom = trans->atom;
32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    deter = 1;
32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (trans->count >= 0) {
32425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int count;
32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegCounterPtr counter;
32445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (exec->counts == NULL) {
32465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->status = -1;
32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto error;
32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
32495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * A counted transition.
32515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
32525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		count = exec->counts[trans->count];
32545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		counter = &exec->comp->counters[trans->count];
32555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("testing count %d: val %d, min %d, max %d\n",
32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       trans->count, count, counter->min,  counter->max);
32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
32595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = ((count >= counter->min) && (count <= counter->max));
32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((ret) && (counter->min != counter->max))
32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    deter = 0;
32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (atom == NULL) {
32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		fprintf(stderr, "epsilon transition left at runtime\n");
32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->status = -2;
32655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (exec->inputString[exec->index] != 0) {
32675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len);
32685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = xmlRegCheckCharacter(atom, codepoint);
32695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((ret == 1) && (atom->min >= 0) && (atom->max > 0)) {
32705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRegStatePtr to = comp->states[trans->to];
32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
32735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * this is a multiple input sequence
32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * If there is a counter associated increment it now.
32755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * before potentially saving and rollback
32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * do not increment if the counter is already over the
32775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * maximum limit in which case get to next transition
32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
32795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (trans->counter >= 0) {
32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlRegCounterPtr counter;
32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ((exec->counts == NULL) ||
32835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    (exec->comp == NULL) ||
32845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    (exec->comp->counters == NULL)) {
32855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->status = -1;
32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    goto error;
32875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			counter = &exec->comp->counters[trans->counter];
32895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exec->counts[trans->counter] >= counter->max)
32905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    continue; /* for loop on transitions */
32915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
32935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("Increasing count %d\n", trans->counter);
32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exec->counts[trans->counter]++;
32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (exec->state->nbTrans > exec->transno + 1) {
32985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFARegExecSave(exec);
32995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
33005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->transcount = 1;
33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    do {
33025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/*
33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * Try to progress as much as possible on the input
33045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 */
33055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exec->transcount == atom->max) {
33065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    break;
33075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
33085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exec->index += len;
33095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/*
33105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * End of input: stop here
33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 */
33125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exec->inputString[exec->index] == 0) {
33135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->index -= len;
33145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    break;
33155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
33165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exec->transcount >= atom->min) {
33175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    int transno = exec->transno;
33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlRegStatePtr state = exec->state;
33195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    /*
33215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     * The transition is acceptable save it
33225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     */
33235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->transno = -1; /* trick */
33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->state = to;
33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlFARegExecSave(exec);
33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->transno = transno;
33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->state = state;
33285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
33295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			codepoint = CUR_SCHAR(&(exec->inputString[exec->index]),
33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				              len);
33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ret = xmlRegCheckCharacter(atom, codepoint);
33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exec->transcount++;
33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } while (ret == 1);
33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (exec->transcount < atom->min)
33355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ret = 0;
33365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
33385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * If the last check failed but one transition was found
33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * possible, rollback
33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (ret < 0)
33425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ret = 0;
33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (ret == 0) {
33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
33455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (trans->counter >= 0) {
33475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exec->counts == NULL) {
33485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->status = -1;
33495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    goto error;
33505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
33515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
33525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("Decreasing count %d\n", trans->counter);
33535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
33545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exec->counts[trans->counter]--;
33555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
33565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if ((ret == 0) && (atom->min == 0) && (atom->max > 0)) {
33575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
33585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * we don't match on the codepoint, but minOccurs of 0
33595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * says that's ok.  Setting len to 0 inhibits stepping
33605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * over the codepoint.
33615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
33625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->transcount = 1;
33635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    len = 0;
33645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = 1;
33655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
33665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if ((atom->min == 0) && (atom->max > 0)) {
33675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        /* another spot to match when minOccurs is 0 */
33685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->transcount = 1;
33695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		len = 0;
33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = 1;
33715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
33725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret == 1) {
33735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((trans->nd == 1) ||
33745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ((trans->count >= 0) && (deter == 0) &&
33755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     (exec->state->nbTrans > exec->transno + 1))) {
33765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
33775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (trans->nd == 1)
33785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        printf("Saving on nd transition atom %d for %c at %d\n",
33795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       trans->atom->no, codepoint, exec->index);
33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    else
33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        printf("Saving on counted transition count %d for %c at %d\n",
33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       trans->count, codepoint, exec->index);
33835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFARegExecSave(exec);
33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (trans->counter >= 0) {
33875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRegCounterPtr counter;
33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /* make sure we don't go over the counter maximum value */
33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((exec->counts == NULL) ||
33915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(exec->comp == NULL) ||
33925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(exec->comp->counters == NULL)) {
33935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exec->status = -1;
33945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto error;
33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    counter = &exec->comp->counters[trans->counter];
33975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (exec->counts[trans->counter] >= counter->max)
33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			continue; /* for loop on transitions */
33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Increasing count %d\n", trans->counter);
34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->counts[trans->counter]++;
34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((trans->count >= 0) &&
34055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (trans->count < REGEXP_ALL_COUNTER)) {
34065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (exec->counts == NULL) {
34075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        exec->status = -1;
34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto error;
34095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("resetting count %d on transition\n",
34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		           trans->count);
34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->counts[trans->count] = 0;
34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("entering state %d\n", trans->to);
34185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
34195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->state = comp->states[trans->to];
34205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->transno = 0;
34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (trans->atom != NULL) {
34225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->index += len;
34235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
34245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto progress;
34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (ret < 0) {
34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->status = -4;
34275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
34285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
34295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
34305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((exec->transno != 0) || (exec->state->nbTrans == 0)) {
34315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)rollback:
34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
34335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Failed to find a way out
34345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
34355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exec->determinist = 0;
34365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
34375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("rollback from state %d on %d:%c\n", exec->state->no,
34385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	           codepoint,codepoint);
34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
34405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFARegExecRollBack(exec);
34415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)progress:
34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	continue;
34445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
34455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error:
34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->rollbacks != NULL) {
34475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (exec->counts != NULL) {
34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int i;
34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i = 0;i < exec->maxRollbacks;i++)
34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (exec->rollbacks[i].counts != NULL)
34525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFree(exec->rollbacks[i].counts);
34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(exec->rollbacks);
34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->counts != NULL)
34575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(exec->counts);
34585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->status == 0)
34595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
34605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->status == -1) {
34615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (exec->nbPush > MAX_PUSH)
34625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
34635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
34655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(exec->status);
34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *	Progressive interface to the verifier one atom at a time	*
34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_ERR
34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void testerr(xmlRegExecCtxtPtr exec);
34755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
34785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegNewExecCtxt:
34795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: a precompiled regular expression
34805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @callback: a callback function used for handling progresses in the
34815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *            automata matching phase
34825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: the context data associated to the callback in this context
34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Build a context used for progressive evaluation of a regexp.
34855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
34865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new context
34875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
34885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecCtxtPtr
34895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegNewExecCtxt(xmlRegexpPtr comp, xmlRegExecCallbacks callback, void *data) {
34905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegExecCtxtPtr exec;
34915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (comp == NULL)
34935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
34945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((comp->compact == NULL) && (comp->states == NULL))
34955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
34965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec = (xmlRegExecCtxtPtr) xmlMalloc(sizeof(xmlRegExecCtxt));
34975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec == NULL) {
34985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegexpErrMemory(NULL, "creating execution context");
34995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
35005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
35015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(exec, 0, sizeof(xmlRegExecCtxt));
35025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->inputString = NULL;
35035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->index = 0;
35045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->determinist = 1;
35055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->maxRollbacks = 0;
35065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->nbRollbacks = 0;
35075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->rollbacks = NULL;
35085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->status = 0;
35095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->comp = comp;
35105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (comp->compact == NULL)
35115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->state = comp->states[0];
35125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->transno = 0;
35135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->transcount = 0;
35145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->callback = callback;
35155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->data = data;
35165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (comp->nbCounters > 0) {
35175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
35185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * For error handling, exec->counts is allocated twice the size
35195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * the second half is used to store the data in case of rollback
35205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
35215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int)
35225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                                 * 2);
35235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (exec->counts == NULL) {
35245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(NULL, "creating execution context");
35255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(exec);
35265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
35275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
35285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        memset(exec->counts, 0, comp->nbCounters * sizeof(int) * 2);
35295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->errCounts = &exec->counts[comp->nbCounters];
35305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
35315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->counts = NULL;
35325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->errCounts = NULL;
35335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
35345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->inputStackMax = 0;
35355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->inputStackNr = 0;
35365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->inputStack = NULL;
35375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->errStateNo = -1;
35385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->errString = NULL;
35395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->nbPush = 0;
35405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(exec);
35415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
35445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegFreeExecCtxt:
35455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regular expression evaulation context
35465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
35475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free the structures associated to a regular expression evaulation context.
35485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
35495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
35505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegFreeExecCtxt(xmlRegExecCtxtPtr exec) {
35515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec == NULL)
35525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
35535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->rollbacks != NULL) {
35555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (exec->counts != NULL) {
35565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int i;
35575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i = 0;i < exec->maxRollbacks;i++)
35595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (exec->rollbacks[i].counts != NULL)
35605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFree(exec->rollbacks[i].counts);
35615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
35625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(exec->rollbacks);
35635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
35645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->counts != NULL)
35655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(exec->counts);
35665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->inputStack != NULL) {
35675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i;
35685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < exec->inputStackNr;i++) {
35705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exec->inputStack[i].value != NULL)
35715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlFree(exec->inputStack[i].value);
35725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
35735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(exec->inputStack);
35745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
35755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->errString != NULL)
35765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlFree(exec->errString);
35775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(exec);
35785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFARegExecSaveInputString(xmlRegExecCtxtPtr exec, const xmlChar *value,
35825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                    void *data) {
35835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
35845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("saving value: %d:%s\n", exec->inputStackNr, value);
35855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
35865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->inputStackMax == 0) {
35875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->inputStackMax = 4;
35885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->inputStack = (xmlRegInputTokenPtr)
35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlMalloc(exec->inputStackMax * sizeof(xmlRegInputToken));
35905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (exec->inputStack == NULL) {
35915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(NULL, "pushing input string");
35925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exec->inputStackMax = 0;
35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
35945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
35955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (exec->inputStackNr + 1 >= exec->inputStackMax) {
35965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegInputTokenPtr tmp;
35975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->inputStackMax *= 2;
35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = (xmlRegInputTokenPtr) xmlRealloc(exec->inputStack,
36005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exec->inputStackMax * sizeof(xmlRegInputToken));
36015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == NULL) {
36025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegexpErrMemory(NULL, "pushing input string");
36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exec->inputStackMax /= 2;
36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
36065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->inputStack = tmp;
36075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
36085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->inputStack[exec->inputStackNr].value = xmlStrdup(value);
36095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->inputStack[exec->inputStackNr].data = data;
36105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->inputStackNr++;
36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->inputStack[exec->inputStackNr].value = NULL;
36125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->inputStack[exec->inputStackNr].data = NULL;
36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
36165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegStrEqualWildcard:
36175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @expStr:  the string to be evaluated
36185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @valStr:  the validation string
36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Checks if both strings are equal or have the same content. "*"
36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * can be used as a wildcard in @valStr; "|" is used as a seperator of
36225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * substrings in both @expStr and @valStr.
36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
36245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if the comparison is satisfied and the number of substrings
36255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is equal, 0 otherwise.
36265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
36275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
36295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegStrEqualWildcard(const xmlChar *expStr, const xmlChar *valStr) {
36305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expStr == valStr) return(1);
36315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expStr == NULL) return(0);
36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (valStr == NULL) return(0);
36335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    do {
36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	* Eval if we have a wildcard for the current item.
36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*/
36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (*expStr != *valStr) {
36385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* if one of them starts with a wildcard make valStr be it */
36395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (*valStr == '*') {
36405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        const xmlChar *tmp;
36415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tmp = valStr;
36435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		valStr = expStr;
36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		expStr = tmp;
36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
36465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((*valStr != 0) && (*expStr != 0) && (*expStr++ == '*')) {
36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		do {
36485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (*valStr == XML_REG_STRING_SEPARATOR)
36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
36505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    valStr++;
36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} while (*valStr != 0);
36525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
36535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else
36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(0);
36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
36565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	expStr++;
36575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	valStr++;
36585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while (*valStr != 0);
36595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (*expStr != 0)
36605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (0);
36615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
36625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (1);
36635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegCompactPushString:
36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context
36685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp:  the precompiled exec with a compact table
36695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value: a string token input
36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data associated to the token to reuse in callbacks
36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
36725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Push one input token in the execution context
36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 1 if the regexp reached a final state, 0 if non-final, and
36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     a negative value in case of error.
36765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
36775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
36785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegCompactPushString(xmlRegExecCtxtPtr exec,
36795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                xmlRegexpPtr comp,
36805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                const xmlChar *value,
36815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                void *data) {
36825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int state = exec->index;
36835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i, target;
36845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((comp == NULL) || (comp->compact == NULL) || (comp->stringMap == NULL))
36865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value == NULL) {
36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * are we at a final state ?
36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
36925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (comp->compact[state * (comp->nbstrings + 1)] ==
36935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            XML_REGEXP_FINAL_STATE)
36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(1);
36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
36975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("value pushed: %s\n", value);
37005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
37015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Examine all outside transitions from current state
37045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
37055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < comp->nbstrings;i++) {
37065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	target = comp->compact[state * (comp->nbstrings + 1) + i + 1];
37075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((target > 0) && (target <= comp->nbstates)) {
37085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    target--; /* to avoid 0 */
37095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (xmlRegStrEqualWildcard(comp->stringMap[i], value)) {
37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->index = target;
37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((exec->callback != NULL) && (comp->transdata != NULL)) {
37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->callback(exec->data, value,
37135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  comp->transdata[state * comp->nbstrings + i], data);
37145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
37155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("entering state %d\n", target);
37175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
37185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (comp->compact[target * (comp->nbstrings + 1)] ==
37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    XML_REGEXP_SINK_STATE)
37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto error;
37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (comp->compact[target * (comp->nbstrings + 1)] ==
37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    XML_REGEXP_FINAL_STATE)
37245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(1);
37255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(0);
37265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
37275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
37285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
37295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
37305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Failed to find an exit transition out from current state for the
37315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * current token
37325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
37335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
37345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("failed to find a transition for %s on state %d\n", value, state);
37355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
37365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error:
37375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->errString != NULL)
37385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlFree(exec->errString);
37395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->errString = xmlStrdup(value);
37405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->errStateNo = state;
37415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exec->status = -1;
37425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_ERR
37435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testerr(exec);
37445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
37455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(-1);
37465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
37495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegExecPushStringInternal:
37505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context or NULL to indicate the end
37515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value: a string token input
37525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data associated to the token to reuse in callbacks
37535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @compound: value was assembled from 2 strings
37545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
37555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Push one input token in the execution context
37565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
37575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 1 if the regexp reached a final state, 0 if non-final, and
37585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     a negative value in case of error.
37595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
37605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
37615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value,
37625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                     void *data, int compound) {
37635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegTransPtr trans;
37645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr atom;
37655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret;
37665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int final = 0;
37675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int progress = 1;
37685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec == NULL)
37705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
37715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->comp == NULL)
37725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
37735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->status != 0)
37745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(exec->status);
37755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->comp->compact != NULL)
37775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(xmlRegCompactPushString(exec, exec->comp, value, data));
37785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value == NULL) {
37805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (exec->state->type == XML_REGEXP_FINAL_STATE)
37815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(1);
37825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	final = 1;
37835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
37845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
37865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("value pushed: %s\n", value);
37875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
37885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
37895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * If we have an active rollback stack push the new value there
37905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * and get back to where we were left
37915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
37925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((value != NULL) && (exec->inputStackNr > 0)) {
37935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFARegExecSaveInputString(exec, value, data);
37945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	value = exec->inputStack[exec->index].value;
37955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	data = exec->inputStack[exec->index].data;
37965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
37975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("value loaded: %s\n", value);
37985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
37995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
38005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((exec->status == 0) &&
38025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   ((value != NULL) ||
38035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ((final == 1) &&
38045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     (exec->state->type != XML_REGEXP_FINAL_STATE)))) {
38055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
38075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * End of input on non-terminal state, rollback, however we may
38085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * still have epsilon like transition for counted transitions
38095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * on counters, in that case don't break too early.
38105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
38115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((value == NULL) && (exec->counts == NULL))
38125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto rollback;
38135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->transcount = 0;
38155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (;exec->transno < exec->state->nbTrans;exec->transno++) {
38165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    trans = &exec->state->trans[exec->transno];
38175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (trans->to < 0)
38185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
38195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    atom = trans->atom;
38205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
38215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (trans->count == REGEXP_ALL_LAX_COUNTER) {
38225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int i;
38235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int count;
38245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegTransPtr t;
38255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegCounterPtr counter;
38265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = 0;
38285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
38305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("testing all lax %d\n", trans->count);
38315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
38325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
38335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * Check all counted transitions from the current state
38345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
38355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((value == NULL) && (final)) {
38365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = 1;
38375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if (value != NULL) {
38385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    for (i = 0;i < exec->state->nbTrans;i++) {
38395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			t = &exec->state->trans[i];
38405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ((t->counter < 0) || (t == trans))
38415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    continue;
38425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			counter = &exec->comp->counters[t->counter];
38435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			count = exec->counts[t->counter];
38445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ((count < counter->max) &&
38455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		            (t->atom != NULL) &&
38465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    (xmlStrEqual(value, t->atom->valuep))) {
38475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    ret = 0;
38485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    break;
38495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
38505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ((count >= counter->min) &&
38515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    (count < counter->max) &&
38525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    (t->atom != NULL) &&
38535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    (xmlStrEqual(value, t->atom->valuep))) {
38545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    ret = 1;
38555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    break;
38565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
38575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
38585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
38595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (trans->count == REGEXP_ALL_COUNTER) {
38605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int i;
38615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int count;
38625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegTransPtr t;
38635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegCounterPtr counter;
38645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = 1;
38665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
38685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("testing all %d\n", trans->count);
38695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
38705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
38715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * Check all counted transitions from the current state
38725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
38735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		for (i = 0;i < exec->state->nbTrans;i++) {
38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    t = &exec->state->trans[i];
38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((t->counter < 0) || (t == trans))
38765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			continue;
38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    counter = &exec->comp->counters[t->counter];
38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    count = exec->counts[t->counter];
38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((count < counter->min) || (count > counter->max)) {
38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ret = 0;
38815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
38825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
38835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
38845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (trans->count >= 0) {
38855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int count;
38865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegCounterPtr counter;
38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * A counted transition.
38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
38915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		count = exec->counts[trans->count];
38935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		counter = &exec->comp->counters[trans->count];
38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("testing count %d: val %d, min %d, max %d\n",
38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       trans->count, count, counter->min,  counter->max);
38975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
38985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = ((count >= counter->min) && (count <= counter->max));
38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (atom == NULL) {
39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		fprintf(stderr, "epsilon transition left at runtime\n");
39015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->status = -2;
39025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
39035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (value != NULL) {
39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = xmlRegStrEqualWildcard(atom->valuep, value);
39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (atom->neg) {
39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = !ret;
39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (!compound)
39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        ret = 0;
39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((ret == 1) && (trans->counter >= 0)) {
39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRegCounterPtr counter;
39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int count;
39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    count = exec->counts[trans->counter];
39155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    counter = &exec->comp->counters[trans->counter];
39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (count >= counter->max)
39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ret = 0;
39185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) {
39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRegStatePtr to = exec->comp->states[trans->to];
39225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
39245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * this is a multiple input sequence
39255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (exec->state->nbTrans > exec->transno + 1) {
39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exec->inputStackNr <= 0) {
39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlFARegExecSaveInputString(exec, value, data);
39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFARegExecSave(exec);
39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->transcount = 1;
39335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    do {
39345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/*
39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * Try to progress as much as possible on the input
39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 */
39375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exec->transcount == atom->max) {
39385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    break;
39395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
39405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exec->index++;
39415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			value = exec->inputStack[exec->index].value;
39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			data = exec->inputStack[exec->index].data;
39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("value loaded: %s\n", value);
39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/*
39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * End of input: stop here
39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 */
39505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (value == NULL) {
39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->index --;
39525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    break;
39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
39545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exec->transcount >= atom->min) {
39555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    int transno = exec->transno;
39565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlRegStatePtr state = exec->state;
39575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    /*
39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     * The transition is acceptable save it
39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     */
39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->transno = -1; /* trick */
39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->state = to;
39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (exec->inputStackNr <= 0) {
39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				xmlFARegExecSaveInputString(exec, value, data);
39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    }
39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlFARegExecSave(exec);
39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->transno = transno;
39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->state = state;
39695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ret = xmlStrEqual(value, atom->valuep);
39715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exec->transcount++;
39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } while (ret == 1);
39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (exec->transcount < atom->min)
39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ret = 0;
39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
39775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * If the last check failed but one transition was found
39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * possible, rollback
39795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
39805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (ret < 0)
39815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ret = 0;
39825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (ret == 0) {
39835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret == 1) {
39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((exec->callback != NULL) && (atom != NULL) &&
39895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(data != NULL)) {
39905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->callback(exec->data, atom->valuep,
39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			           atom->data, data);
39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (exec->state->nbTrans > exec->transno + 1) {
39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (exec->inputStackNr <= 0) {
39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFARegExecSaveInputString(exec, value, data);
39965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
39975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFARegExecSave(exec);
39985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (trans->counter >= 0) {
40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Increasing count %d\n", trans->counter);
40025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
40035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->counts[trans->counter]++;
40045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((trans->count >= 0) &&
40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (trans->count < REGEXP_ALL_COUNTER)) {
40075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
40085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("resetting count %d on transition\n",
40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		           trans->count);
40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->counts[trans->count] = 0;
40125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("entering state %d\n", trans->to);
40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
40165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if ((exec->comp->states[trans->to] != NULL) &&
40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (exec->comp->states[trans->to]->type ==
40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     XML_REGEXP_SINK_STATE)) {
40195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
40205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * entering a sink state, save the current state as error
40215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * state.
40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (exec->errString != NULL)
40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFree(exec->errString);
40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->errString = xmlStrdup(value);
40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->errState = exec->state;
40275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    memcpy(exec->errCounts, exec->counts,
40285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   exec->comp->nbCounters * sizeof(int));
40295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
40305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->state = exec->comp->states[trans->to];
40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->transno = 0;
40325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (trans->atom != NULL) {
40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (exec->inputStack != NULL) {
40345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exec->index++;
40355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exec->index < exec->inputStackNr) {
40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    value = exec->inputStack[exec->index].value;
40375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    data = exec->inputStack[exec->index].data;
40385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
40395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    printf("value loaded: %s\n", value);
40405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
40415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			} else {
40425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    value = NULL;
40435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    data = NULL;
40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
40455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    printf("end of input\n");
40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
40475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			value = NULL;
40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			data = NULL;
40515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("end of input\n");
40535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
40555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto progress;
40575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (ret < 0) {
40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->status = -4;
40595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
40615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((exec->transno != 0) || (exec->state->nbTrans == 0)) {
40635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)rollback:
40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
40655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * if we didn't yet rollback on the current input
40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * store the current state as the error state.
40675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((progress) && (exec->state != NULL) &&
40695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (exec->state->type != XML_REGEXP_SINK_STATE)) {
40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        progress = 0;
40715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (exec->errString != NULL)
40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFree(exec->errString);
40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->errString = xmlStrdup(value);
40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->errState = exec->state;
40755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		memcpy(exec->errCounts, exec->counts,
40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       exec->comp->nbCounters * sizeof(int));
40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Failed to find a way out
40815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
40825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exec->determinist = 0;
40835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFARegExecRollBack(exec);
40845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exec->status == 0) {
40855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		value = exec->inputStack[exec->index].value;
40865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		data = exec->inputStack[exec->index].data;
40875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH
40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("value loaded: %s\n", value);
40895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
40915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
40925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	continue;
40935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)progress:
40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        progress = 1;
40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	continue;
40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
40975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->status == 0) {
40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(exec->state->type == XML_REGEXP_FINAL_STATE);
40995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_ERR
41015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->status < 0) {
41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	testerr(exec);
41035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
41055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(exec->status);
41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
41095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegExecPushString:
41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context or NULL to indicate the end
41115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value: a string token input
41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data associated to the token to reuse in callbacks
41135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Push one input token in the execution context
41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 1 if the regexp reached a final state, 0 if non-final, and
41175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     a negative value in case of error.
41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecPushString(xmlRegExecCtxtPtr exec, const xmlChar *value,
41215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	             void *data) {
41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(xmlRegExecPushStringInternal(exec, value, data, 0));
41235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
41265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegExecPushString2:
41275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context or NULL to indicate the end
41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value: the first string token input
41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value2: the second string token input
41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data associated to the token to reuse in callbacks
41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Push one input token in the execution context
41335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
41345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 1 if the regexp reached a final state, 0 if non-final, and
41355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     a negative value in case of error.
41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
41375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
41385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecPushString2(xmlRegExecCtxtPtr exec, const xmlChar *value,
41395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const xmlChar *value2, void *data) {
41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar buf[150];
41415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int lenn, lenp, ret;
41425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *str;
41435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec == NULL)
41455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
41465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->comp == NULL)
41475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
41485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->status != 0)
41495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(exec->status);
41505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value2 == NULL)
41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(xmlRegExecPushString(exec, value, data));
41535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    lenn = strlen((char *) value2);
41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    lenp = strlen((char *) value);
41565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (150 < lenn + lenp + 2) {
41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (str == NULL) {
41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exec->status = -1;
41615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
41625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
41635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
41645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str = buf;
41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&str[0], value, lenp);
41675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str[lenp] = XML_REG_STRING_SEPARATOR;
41685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&str[lenp + 1], value2, lenn);
41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str[lenn + lenp + 1] = 0;
41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->comp->compact != NULL)
41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlRegCompactPushString(exec, exec->comp, str, data);
41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = xmlRegExecPushStringInternal(exec, str, data, 1);
41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (str != buf)
41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlFree(str);
41785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
41825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegExecGetValues:
41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context
41845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @err: error extraction or normal one
41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nbval: pointer to the number of accepted values IN/OUT
41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nbneg: return number of negative transitions
41875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @values: pointer to the array of acceptable values
41885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @terminal: return value if this was a terminal state
41895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
41905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extract informations from the regexp execution, internal routine to
41915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * implement xmlRegExecNextValues() and xmlRegExecErrInfo()
41925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
41935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 0 in case of success or -1 in case of error.
41945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
41955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
41965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecGetValues(xmlRegExecCtxtPtr exec, int err,
41975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int *nbval, int *nbneg,
41985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlChar **values, int *terminal) {
41995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int maxval;
42005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nb = 0;
42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((exec == NULL) || (nbval == NULL) || (nbneg == NULL) ||
42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (values == NULL) || (*nbval <= 0))
42045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(-1);
42055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    maxval = *nbval;
42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *nbval = 0;
42085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *nbneg = 0;
42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((exec->comp != NULL) && (exec->comp->compact != NULL)) {
42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlRegexpPtr comp;
42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int target, i, state;
42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        comp = exec->comp;
42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (err) {
42165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exec->errStateNo == -1) return(-1);
42175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    state = exec->errStateNo;
42185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    state = exec->index;
42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (terminal != NULL) {
42225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (comp->compact[state * (comp->nbstrings + 1)] ==
42235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        XML_REGEXP_FINAL_STATE)
42245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*terminal = 1;
42255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
42265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*terminal = 0;
42275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
42285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;(i < comp->nbstrings) && (nb < maxval);i++) {
42295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    target = comp->compact[state * (comp->nbstrings + 1) + i + 1];
42305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((target > 0) && (target <= comp->nbstates) &&
42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (comp->compact[(target - 1) * (comp->nbstrings + 1)] !=
42325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 XML_REGEXP_SINK_STATE)) {
42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        values[nb++] = comp->stringMap[i];
42345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(*nbval)++;
42355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
42365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
42375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;(i < comp->nbstrings) && (nb < maxval);i++) {
42385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    target = comp->compact[state * (comp->nbstrings + 1) + i + 1];
42395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((target > 0) && (target <= comp->nbstates) &&
42405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (comp->compact[(target - 1) * (comp->nbstrings + 1)] ==
42415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 XML_REGEXP_SINK_STATE)) {
42425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        values[nb++] = comp->stringMap[i];
42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(*nbneg)++;
42445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
42455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
42465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
42475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int transno;
42485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegTransPtr trans;
42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegAtomPtr atom;
42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStatePtr state;
42515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (terminal != NULL) {
42535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exec->state->type == XML_REGEXP_FINAL_STATE)
42545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*terminal = 1;
42555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*terminal = 0;
42575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (err) {
42605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exec->errState == NULL) return(-1);
42615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    state = exec->errState;
42625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
42635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exec->state == NULL) return(-1);
42645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    state = exec->state;
42655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
42665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (transno = 0;
42675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     (transno < state->nbTrans) && (nb < maxval);
42685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     transno++) {
42695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    trans = &state->trans[transno];
42705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (trans->to < 0)
42715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
42725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    atom = trans->atom;
42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((atom == NULL) || (atom->valuep == NULL))
42745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
42755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (trans->count == REGEXP_ALL_LAX_COUNTER) {
42765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        /* this should not be reached but ... */
42775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        TODO;
42785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (trans->count == REGEXP_ALL_COUNTER) {
42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        /* this should not be reached but ... */
42805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        TODO;
42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (trans->counter >= 0) {
42825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegCounterPtr counter = NULL;
42835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int count;
42845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (err)
42865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    count = exec->errCounts[trans->counter];
42875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
42885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    count = exec->counts[trans->counter];
42895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (exec->comp != NULL)
42905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    counter = &exec->comp->counters[trans->counter];
42915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((counter == NULL) || (count < counter->max)) {
42925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (atom->neg)
42935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			values[nb++] = (xmlChar *) atom->valuep2;
42945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    else
42955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			values[nb++] = (xmlChar *) atom->valuep;
42965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (*nbval)++;
42975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
42985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
42995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if ((exec->comp->states[trans->to] != NULL) &&
43005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (exec->comp->states[trans->to]->type !=
43015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     XML_REGEXP_SINK_STATE)) {
43025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (atom->neg)
43035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			values[nb++] = (xmlChar *) atom->valuep2;
43045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    else
43055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			values[nb++] = (xmlChar *) atom->valuep;
43065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (*nbval)++;
43075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
43085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
43105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (transno = 0;
43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     (transno < state->nbTrans) && (nb < maxval);
43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     transno++) {
43135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    trans = &state->trans[transno];
43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (trans->to < 0)
43155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
43165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    atom = trans->atom;
43175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((atom == NULL) || (atom->valuep == NULL))
43185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
43195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (trans->count == REGEXP_ALL_LAX_COUNTER) {
43205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        continue;
43215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (trans->count == REGEXP_ALL_COUNTER) {
43225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        continue;
43235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (trans->counter >= 0) {
43245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        continue;
43255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
43265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if ((exec->comp->states[trans->to] != NULL) &&
43275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (exec->comp->states[trans->to]->type ==
43285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     XML_REGEXP_SINK_STATE)) {
43295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (atom->neg)
43305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			values[nb++] = (xmlChar *) atom->valuep2;
43315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    else
43325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			values[nb++] = (xmlChar *) atom->valuep;
43335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (*nbneg)++;
43345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
43355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
43365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
43375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
43385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
43395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
43425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegExecNextValues:
43435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context
43445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nbval: pointer to the number of accepted values IN/OUT
43455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nbneg: return number of negative transitions
43465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @values: pointer to the array of acceptable values
43475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @terminal: return value if this was a terminal state
43485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
43495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extract informations from the regexp execution,
43505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the parameter @values must point to an array of @nbval string pointers
43515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on return nbval will contain the number of possible strings in that
43525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * state and the @values array will be updated with them. The string values
43535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * returned will be freed with the @exec context and don't need to be
43545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * deallocated.
43555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
43565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 0 in case of success or -1 in case of error.
43575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
43585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
43595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecNextValues(xmlRegExecCtxtPtr exec, int *nbval, int *nbneg,
43605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     xmlChar **values, int *terminal) {
43615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(xmlRegExecGetValues(exec, 0, nbval, nbneg, values, terminal));
43625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
43655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegExecErrInfo:
43665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context generating an error
43675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @string: return value for the error string
43685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nbval: pointer to the number of accepted values IN/OUT
43695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nbneg: return number of negative transitions
43705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @values: pointer to the array of acceptable values
43715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @terminal: return value if this was a terminal state
43725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
43735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extract error informations from the regexp execution, the parameter
43745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @string will be updated with the value pushed and not accepted,
43755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the parameter @values must point to an array of @nbval string pointers
43765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on return nbval will contain the number of possible strings in that
43775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * state and the @values array will be updated with them. The string values
43785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * returned will be freed with the @exec context and don't need to be
43795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * deallocated.
43805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
43815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 0 in case of success or -1 in case of error.
43825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
43835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
43845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecErrInfo(xmlRegExecCtxtPtr exec, const xmlChar **string,
43855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  int *nbval, int *nbneg, xmlChar **values, int *terminal) {
43865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec == NULL)
43875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(-1);
43885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (string != NULL) {
43895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (exec->status != 0)
43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *string = exec->errString;
43915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
43925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *string = NULL;
43935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
43945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(xmlRegExecGetValues(exec, 1, nbval, nbneg, values, terminal));
43955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_ERR
43985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void testerr(xmlRegExecCtxtPtr exec) {
43995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *string;
44005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *values[5];
44015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nb = 5;
44025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbneg;
44035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int terminal;
44045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegExecErrInfo(exec, &string, &nb, &nbneg, &values[0], &terminal);
44055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
44075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
44095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecPushChar(xmlRegExecCtxtPtr exec, int UCS) {
44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegTransPtr trans;
44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr atom;
44135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret;
44145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int codepoint, len;
44155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec == NULL)
44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
44185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exec->status != 0)
44195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(exec->status);
44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((exec->status == 0) &&
44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   ((exec->inputString[exec->index] != 0) ||
44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (exec->state->type != XML_REGEXP_FINAL_STATE))) {
44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
44265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * End of input on non-terminal state, rollback, however we may
44275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * still have epsilon like transition for counted transitions
44285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * on counters, in that case don't break too early.
44295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
44305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL))
44315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto rollback;
44325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exec->transcount = 0;
44345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (;exec->transno < exec->state->nbTrans;exec->transno++) {
44355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    trans = &exec->state->trans[exec->transno];
44365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (trans->to < 0)
44375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
44385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    atom = trans->atom;
44395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
44405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (trans->count >= 0) {
44415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int count;
44425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRegCounterPtr counter;
44435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
44455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * A counted transition.
44465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
44475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		count = exec->counts[trans->count];
44495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		counter = &exec->comp->counters[trans->count];
44505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
44515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("testing count %d: val %d, min %d, max %d\n",
44525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       trans->count, count, counter->min,  counter->max);
44535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
44545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = ((count >= counter->min) && (count <= counter->max));
44555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (atom == NULL) {
44565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		fprintf(stderr, "epsilon transition left at runtime\n");
44575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->status = -2;
44585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
44595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (exec->inputString[exec->index] != 0) {
44605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len);
44615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = xmlRegCheckCharacter(atom, codepoint);
44625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) {
44635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRegStatePtr to = exec->comp->states[trans->to];
44645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
44665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * this is a multiple input sequence
44675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
44685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (exec->state->nbTrans > exec->transno + 1) {
44695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFARegExecSave(exec);
44705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
44715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->transcount = 1;
44725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    do {
44735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/*
44745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * Try to progress as much as possible on the input
44755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 */
44765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exec->transcount == atom->max) {
44775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    break;
44785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
44795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exec->index += len;
44805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/*
44815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * End of input: stop here
44825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 */
44835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exec->inputString[exec->index] == 0) {
44845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->index -= len;
44855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    break;
44865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
44875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exec->transcount >= atom->min) {
44885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    int transno = exec->transno;
44895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlRegStatePtr state = exec->state;
44905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    /*
44925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     * The transition is acceptable save it
44935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     */
44945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->transno = -1; /* trick */
44955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->state = to;
44965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlFARegExecSave(exec);
44975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->transno = transno;
44985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    exec->state = state;
44995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
45005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			codepoint = CUR_SCHAR(&(exec->inputString[exec->index]),
45015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				              len);
45025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ret = xmlRegCheckCharacter(atom, codepoint);
45035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exec->transcount++;
45045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } while (ret == 1);
45055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (exec->transcount < atom->min)
45065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ret = 0;
45075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
45095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * If the last check failed but one transition was found
45105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * possible, rollback
45115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
45125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (ret < 0)
45135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ret = 0;
45145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (ret == 0) {
45155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
45165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
45175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
45185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
45195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret == 1) {
45205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (exec->state->nbTrans > exec->transno + 1) {
45215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFARegExecSave(exec);
45225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
45235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
45245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * restart count for expressions like this ((abc){2})*
45255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
45265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (trans->count >= 0) {
45275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
45285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Reset count %d\n", trans->count);
45295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
45305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->counts[trans->count] = 0;
45315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
45325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (trans->counter >= 0) {
45335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
45345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Increasing count %d\n", trans->counter);
45355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
45365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->counts[trans->counter]++;
45375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
45385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC
45395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("entering state %d\n", trans->to);
45405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
45415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->state = exec->comp->states[trans->to];
45425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->transno = 0;
45435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (trans->atom != NULL) {
45445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exec->index += len;
45455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
45465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto progress;
45475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (ret < 0) {
45485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exec->status = -4;
45495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
45505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
45515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
45525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((exec->transno != 0) || (exec->state->nbTrans == 0)) {
45535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)rollback:
45545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
45555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Failed to find a way out
45565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
45575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exec->determinist = 0;
45585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFARegExecRollBack(exec);
45595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
45605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)progress:
45615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	continue;
45625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
45635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
45645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
45655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
45665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
45675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *	Parser for the Schemas Datatype Regular Expressions		*
45685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *	http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#regexs	*
45695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
45705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
45715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
45735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAIsChar:
45745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
45755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [10]   Char   ::=   [^.\?*+()|#x5B#x5D]
45775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
45785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
45795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAIsChar(xmlRegParserCtxtPtr ctxt) {
45805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int cur;
45815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int len;
45825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = CUR_SCHAR(ctxt->cur, len);
45845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((cur == '.') || (cur == '\\') || (cur == '?') ||
45855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur == '*') || (cur == '+') || (cur == '(') ||
45865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur == ')') || (cur == '|') || (cur == 0x5B) ||
45875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur == 0x5D) || (cur == 0))
45885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
45895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(cur);
45905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
45915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
45935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseCharProp:
45945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
45955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [27]   charProp   ::=   IsCategory | IsBlock
45975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [28]   IsCategory ::= Letters | Marks | Numbers | Punctuation |
45985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *                       Separators | Symbols | Others
45995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [29]   Letters   ::=   'L' [ultmo]?
46005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [30]   Marks   ::=   'M' [nce]?
46015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [31]   Numbers   ::=   'N' [dlo]?
46025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [32]   Punctuation   ::=   'P' [cdseifo]?
46035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [33]   Separators   ::=   'Z' [slp]?
46045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [34]   Symbols   ::=   'S' [mcko]?
46055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [35]   Others   ::=   'C' [cfon]?
46065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [36]   IsBlock   ::=   'Is' [a-zA-Z0-9#x2D]+
46075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
46085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
46095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) {
46105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int cur;
46115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomType type = (xmlRegAtomType) 0;
46125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *blockName = NULL;
46135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = CUR;
46155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == 'L') {
46165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
46175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = CUR;
46185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur == 'u') {
46195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_LETTER_UPPERCASE;
46215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'l') {
46225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_LETTER_LOWERCASE;
46245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 't') {
46255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_LETTER_TITLECASE;
46275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'm') {
46285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_LETTER_MODIFIER;
46305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'o') {
46315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_LETTER_OTHERS;
46335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
46345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_LETTER;
46355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
46365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (cur == 'M') {
46375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
46385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = CUR;
46395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur == 'n') {
46405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* nonspacing */
46425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_MARK_NONSPACING;
46435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'c') {
46445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* spacing combining */
46465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_MARK_SPACECOMBINING;
46475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'e') {
46485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* enclosing */
46505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_MARK_ENCLOSING;
46515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
46525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* all marks */
46535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_MARK;
46545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
46555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (cur == 'N') {
46565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
46575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = CUR;
46585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur == 'd') {
46595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* digital */
46615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_NUMBER_DECIMAL;
46625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'l') {
46635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* letter */
46655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_NUMBER_LETTER;
46665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'o') {
46675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* other */
46695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_NUMBER_OTHERS;
46705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
46715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* all numbers */
46725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_NUMBER;
46735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
46745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (cur == 'P') {
46755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
46765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = CUR;
46775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur == 'c') {
46785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* connector */
46805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_PUNCT_CONNECTOR;
46815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'd') {
46825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* dash */
46845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_PUNCT_DASH;
46855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 's') {
46865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* open */
46885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_PUNCT_OPEN;
46895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'e') {
46905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* close */
46925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_PUNCT_CLOSE;
46935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'i') {
46945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* initial quote */
46965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_PUNCT_INITQUOTE;
46975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'f') {
46985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
46995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* final quote */
47005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_PUNCT_FINQUOTE;
47015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'o') {
47025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
47035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* other */
47045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_PUNCT_OTHERS;
47055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
47065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* all punctuation */
47075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_PUNCT;
47085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
47095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (cur == 'Z') {
47105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
47115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = CUR;
47125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur == 's') {
47135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
47145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* space */
47155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_SEPAR_SPACE;
47165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'l') {
47175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
47185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* line */
47195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_SEPAR_LINE;
47205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'p') {
47215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
47225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* paragraph */
47235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_SEPAR_PARA;
47245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
47255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* all separators */
47265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_SEPAR;
47275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
47285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (cur == 'S') {
47295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
47305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = CUR;
47315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur == 'm') {
47325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
47335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_SYMBOL_MATH;
47345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* math */
47355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'c') {
47365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
47375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_SYMBOL_CURRENCY;
47385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* currency */
47395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'k') {
47405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
47415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_SYMBOL_MODIFIER;
47425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* modifiers */
47435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'o') {
47445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
47455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_SYMBOL_OTHERS;
47465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* other */
47475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
47485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* all symbols */
47495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_SYMBOL;
47505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
47515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (cur == 'C') {
47525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
47535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = CUR;
47545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur == 'c') {
47555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
47565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* control */
47575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_OTHER_CONTROL;
47585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'f') {
47595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
47605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* format */
47615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_OTHER_FORMAT;
47625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'o') {
47635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
47645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* private use */
47655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_OTHER_PRIVATE;
47665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (cur == 'n') {
47675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
47685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* not assigned */
47695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_OTHER_NA;
47705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
47715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* all others */
47725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    type = XML_REGEXP_OTHER;
47735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
47745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (cur == 'I') {
47755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const xmlChar *start;
47765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
47775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = CUR;
47785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur != 's') {
47795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ERROR("IsXXXX expected");
47805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
47815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
47825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
47835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	start = ctxt->cur;
47845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = CUR;
47855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (((cur >= 'a') && (cur <= 'z')) ||
47865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ((cur >= 'A') && (cur <= 'Z')) ||
47875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ((cur >= '0') && (cur <= '9')) ||
47885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (cur == 0x2D)) {
47895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
47905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cur = CUR;
47915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    while (((cur >= 'a') && (cur <= 'z')) ||
47925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		((cur >= 'A') && (cur <= 'Z')) ||
47935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		((cur >= '0') && (cur <= '9')) ||
47945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(cur == 0x2D)) {
47955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		NEXT;
47965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		cur = CUR;
47975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
47985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
47995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	type = XML_REGEXP_BLOCK_NAME;
48005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	blockName = xmlStrndup(start, ctxt->cur - start);
48015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
48025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("Unknown char property");
48035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
48045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
48055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->atom == NULL) {
48065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->atom = xmlRegNewAtom(ctxt, type);
48075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->atom != NULL)
48085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->atom->valuep = blockName;
48095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (ctxt->atom->type == XML_REGEXP_RANGES) {
48105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
48115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		           type, 0, 0, blockName);
48125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
48135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
48145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
48165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseCharClassEsc:
48175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
48185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
48195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [23] charClassEsc ::= ( SingleCharEsc | MultiCharEsc | catEsc | complEsc )
48205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [24] SingleCharEsc ::= '\' [nrt\|.?*+(){}#x2D#x5B#x5D#x5E]
48215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [25] catEsc   ::=   '\p{' charProp '}'
48225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [26] complEsc ::=   '\P{' charProp '}'
48235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [37] MultiCharEsc ::= '.' | ('\' [sSiIcCdDwW])
48245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
48255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
48265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseCharClassEsc(xmlRegParserCtxtPtr ctxt) {
48275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int cur;
48285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR == '.') {
48305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->atom == NULL) {
48315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_ANYCHAR);
48325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (ctxt->atom->type == XML_REGEXP_RANGES) {
48335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
48345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       XML_REGEXP_ANYCHAR, 0, 0, NULL);
48355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
48365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
48375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
48385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
48395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR != '\\') {
48405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("Escaped sequence: expecting \\");
48415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
48425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
48435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEXT;
48445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = CUR;
48455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == 'p') {
48465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
48475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != '{') {
48485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ERROR("Expecting '{'");
48495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
48505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
48515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
48525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFAParseCharProp(ctxt);
48535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != '}') {
48545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ERROR("Expecting '}'");
48555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
48565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
48575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
48585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (cur == 'P') {
48595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
48605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != '{') {
48615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ERROR("Expecting '{'");
48625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
48635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
48645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
48655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFAParseCharProp(ctxt);
48665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->atom->neg = 1;
48675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != '}') {
48685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ERROR("Expecting '}'");
48695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
48705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
48715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
48725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((cur == 'n') || (cur == 'r') || (cur == 't') || (cur == '\\') ||
48735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur == '|') || (cur == '.') || (cur == '?') || (cur == '*') ||
48745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur == '+') || (cur == '(') || (cur == ')') || (cur == '{') ||
48755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur == '}') || (cur == 0x2D) || (cur == 0x5B) || (cur == 0x5D) ||
48765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur == 0x5E)) {
48775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->atom == NULL) {
48785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL);
48795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ctxt->atom != NULL) {
48805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        switch (cur) {
48815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case 'n':
48825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        ctxt->atom->codepoint = '\n';
48835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
48845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case 'r':
48855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        ctxt->atom->codepoint = '\r';
48865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
48875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case 't':
48885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        ctxt->atom->codepoint = '\t';
48895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
48905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    default:
48915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ctxt->atom->codepoint = cur;
48925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
48935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
48945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (ctxt->atom->type == XML_REGEXP_RANGES) {
48955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            switch (cur) {
48965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case 'n':
48975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    cur = '\n';
48985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
48995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case 'r':
49005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    cur = '\r';
49015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
49025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                case 't':
49035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    cur = '\t';
49045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
49055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
49065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
49075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       XML_REGEXP_CHARVAL, cur, cur, NULL);
49085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
49095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
49105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((cur == 's') || (cur == 'S') || (cur == 'i') || (cur == 'I') ||
49115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur == 'c') || (cur == 'C') || (cur == 'd') || (cur == 'D') ||
49125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur == 'w') || (cur == 'W')) {
49135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegAtomType type = XML_REGEXP_ANYSPACE;
49145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (cur) {
49165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 's':
49175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		type = XML_REGEXP_ANYSPACE;
49185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
49195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 'S':
49205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		type = XML_REGEXP_NOTSPACE;
49215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
49225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 'i':
49235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		type = XML_REGEXP_INITNAME;
49245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
49255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 'I':
49265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		type = XML_REGEXP_NOTINITNAME;
49275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
49285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 'c':
49295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		type = XML_REGEXP_NAMECHAR;
49305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
49315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 'C':
49325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		type = XML_REGEXP_NOTNAMECHAR;
49335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
49345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 'd':
49355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		type = XML_REGEXP_DECIMAL;
49365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
49375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 'D':
49385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		type = XML_REGEXP_NOTDECIMAL;
49395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
49405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 'w':
49415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		type = XML_REGEXP_REALCHAR;
49425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
49435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 'W':
49445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		type = XML_REGEXP_NOTREALCHAR;
49455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
49465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
49475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
49485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->atom == NULL) {
49495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->atom = xmlRegNewAtom(ctxt, type);
49505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (ctxt->atom->type == XML_REGEXP_RANGES) {
49515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
49525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       type, 0, 0, NULL);
49535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
49545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
49555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("Wrong escape sequence, misuse of character '\\'");
49565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
49575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
49585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
49605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseCharRange:
49615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
49625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
49635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [17]   charRange   ::=     seRange | XmlCharRef | XmlCharIncDash
49645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [18]   seRange   ::=   charOrEsc '-' charOrEsc
49655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [20]   charOrEsc   ::=   XmlChar | SingleCharEsc
49665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [21]   XmlChar   ::=   [^\#x2D#x5B#x5D]
49675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [22]   XmlCharIncDash   ::=   [^\#x5B#x5D]
49685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
49695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
49705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseCharRange(xmlRegParserCtxtPtr ctxt) {
49715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int cur, len;
49725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int start = -1;
49735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int end = -1;
49745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR == '\0') {
49765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ERROR("Expecting ']'");
49775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
49785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
49795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = CUR;
49815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == '\\') {
49825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
49835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = CUR;
49845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (cur) {
49855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 'n': start = 0xA; break;
49865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 'r': start = 0xD; break;
49875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 't': start = 0x9; break;
49885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case '\\': case '|': case '.': case '-': case '^': case '?':
49895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case '*': case '+': case '{': case '}': case '(': case ')':
49905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case '[': case ']':
49915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		start = cur; break;
49925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    default:
49935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ERROR("Invalid escape value");
49945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
49955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
49965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	end = start;
49975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len = 1;
49985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((cur != 0x5B) && (cur != 0x5D)) {
49995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        end = start = CUR_SCHAR(ctxt->cur, len);
50005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
50015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("Expecting a char range");
50025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
50035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
50045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
50055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Since we are "inside" a range, we can assume ctxt->cur is past
50065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * the start of ctxt->string, and PREV should be safe
50075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
50085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((start == '-') && (NXT(1) != ']') && (PREV != '[') && (PREV != '^')) {
50095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXTL(len);
50105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
50115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
50125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEXTL(len);
50135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = CUR;
50145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((cur != '-') || (NXT(1) == ']')) {
50155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
50165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		              XML_REGEXP_CHARVAL, start, end, NULL);
50175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
50185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
50195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEXT;
50205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = CUR;
50215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == '\\') {
50225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
50235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = CUR;
50245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (cur) {
50255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 'n': end = 0xA; break;
50265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 'r': end = 0xD; break;
50275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case 't': end = 0x9; break;
50285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case '\\': case '|': case '.': case '-': case '^': case '?':
50295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case '*': case '+': case '{': case '}': case '(': case ')':
50305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case '[': case ']':
50315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		end = cur; break;
50325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    default:
50335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ERROR("Invalid escape value");
50345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
50355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
50365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len = 1;
50375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((cur != 0x5B) && (cur != 0x5D)) {
50385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        end = CUR_SCHAR(ctxt->cur, len);
50395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
50405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("Expecting the end of a char range");
50415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
50425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
50435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEXTL(len);
50445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* TODO check that the values are acceptable character ranges for XML */
50455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (end < start) {
50465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("End of range is before start of range");
50475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
50485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
50495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		           XML_REGEXP_CHARVAL, start, end, NULL);
50505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
50515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
50525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
50535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
50555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParsePosCharGroup:
50565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
50575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
50585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [14]   posCharGroup ::= ( charRange | charClassEsc  )+
50595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
50605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
50615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParsePosCharGroup(xmlRegParserCtxtPtr ctxt) {
50625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    do {
50635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR == '\\') {
50645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFAParseCharClassEsc(ctxt);
50655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
50665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFAParseCharRange(ctxt);
50675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
50685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while ((CUR != ']') && (CUR != '^') && (CUR != '-') &&
50695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             (CUR != 0) && (ctxt->error == 0));
50705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
50715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
50735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseCharGroup:
50745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
50755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
50765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [13]   charGroup    ::= posCharGroup | negCharGroup | charClassSub
50775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [15]   negCharGroup ::= '^' posCharGroup
50785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [16]   charClassSub ::= ( posCharGroup | negCharGroup ) '-' charClassExpr
50795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [12]   charClassExpr ::= '[' charGroup ']'
50805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
50815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
50825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseCharGroup(xmlRegParserCtxtPtr ctxt) {
50835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int n = ctxt->neg;
50845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((CUR != ']') && (ctxt->error == 0)) {
50855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR == '^') {
50865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int neg = ctxt->neg;
50875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
50895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->neg = !ctxt->neg;
50905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFAParsePosCharGroup(ctxt);
50915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->neg = neg;
50925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if ((CUR == '-') && (NXT(1) == '[')) {
50935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int neg = ctxt->neg;
50945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->neg = 2;
50955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;	/* eat the '-' */
50965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;	/* eat the '[' */
50975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFAParseCharGroup(ctxt);
50985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (CUR == ']') {
50995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		NEXT;
51005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
51015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ERROR("charClassExpr: ']' expected");
51025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
51035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
51045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->neg = neg;
51055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
51065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (CUR != ']') {
51075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFAParsePosCharGroup(ctxt);
51085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
51095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
51105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->neg = n;
51115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
51125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
51145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseCharClass:
51155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
51165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
51175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [11]   charClass   ::=     charClassEsc | charClassExpr
51185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [12]   charClassExpr   ::=   '[' charGroup ']'
51195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
51205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
51215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseCharClass(xmlRegParserCtxtPtr ctxt) {
51225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR == '[') {
51235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
51245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_RANGES);
51255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->atom == NULL)
51265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
51275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFAParseCharGroup(ctxt);
51285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR == ']') {
51295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
51305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
51315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ERROR("xmlFAParseCharClass: ']' expected");
51325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
51335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
51345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFAParseCharClassEsc(ctxt);
51355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
51365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
51375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
51395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseQuantExact:
51405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
51415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
51425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [8]   QuantExact   ::=   [0-9]+
51435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
51445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 0 if success or -1 in case of error
51455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
51465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
51475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseQuantExact(xmlRegParserCtxtPtr ctxt) {
51485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret = 0;
51495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ok = 0;
51505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((CUR >= '0') && (CUR <= '9')) {
51525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = ret * 10 + (CUR - '0');
51535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ok = 1;
51545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
51555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
51565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ok != 1) {
51575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
51585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
51595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
51605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
51615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
51635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseQuantifier:
51645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
51655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
51665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [4]   quantifier   ::=   [?*+] | ( '{' quantity '}' )
51675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [5]   quantity   ::=   quantRange | quantMin | QuantExact
51685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [6]   quantRange   ::=   QuantExact ',' QuantExact
51695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [7]   quantMin   ::=   QuantExact ','
51705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [8]   QuantExact   ::=   [0-9]+
51715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
51725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
51735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseQuantifier(xmlRegParserCtxtPtr ctxt) {
51745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int cur;
51755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = CUR;
51775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((cur == '?') || (cur == '*') || (cur == '+')) {
51785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->atom != NULL) {
51795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (cur == '?')
51805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ctxt->atom->quant = XML_REGEXP_QUANT_OPT;
51815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else if (cur == '*')
51825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ctxt->atom->quant = XML_REGEXP_QUANT_MULT;
51835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else if (cur == '+')
51845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ctxt->atom->quant = XML_REGEXP_QUANT_PLUS;
51855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
51865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
51875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
51885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
51895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == '{') {
51905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int min = 0, max = 0;
51915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
51935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = xmlFAParseQuantExact(ctxt);
51945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur >= 0)
51955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    min = cur;
51965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR == ',') {
51975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
51985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (CUR == '}')
51995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        max = INT_MAX;
52005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else {
52015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        cur = xmlFAParseQuantExact(ctxt);
52025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        if (cur >= 0)
52035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    max = cur;
52045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else {
52055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ERROR("Improper quantifier");
52065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
52075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
52085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
52095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR == '}') {
52105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
52115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
52125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ERROR("Unterminated quantifier");
52135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
52145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (max == 0)
52155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    max = min;
52165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->atom != NULL) {
52175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->atom->quant = XML_REGEXP_QUANT_RANGE;
52185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->atom->min = min;
52195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->atom->max = max;
52205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
52215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
52225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
52235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
52245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
52255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
52275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseAtom:
52285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
52295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
52305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [9]   atom   ::=   Char | charClass | ( '(' regExp ')' )
52315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
52325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
52335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseAtom(xmlRegParserCtxtPtr ctxt) {
52345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int codepoint, len;
52355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    codepoint = xmlFAIsChar(ctxt);
52375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (codepoint > 0) {
52385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL);
52395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->atom == NULL)
52405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
52415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	codepoint = CUR_SCHAR(ctxt->cur, len);
52425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->atom->codepoint = codepoint;
52435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXTL(len);
52445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
52455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (CUR == '|') {
52465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
52475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (CUR == 0) {
52485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
52495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (CUR == ')') {
52505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
52515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (CUR == '(') {
52525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStatePtr start, oldend, start0;
52535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
52555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
52565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * this extra Epsilon transition is needed if we count with 0 allowed
52575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * unfortunately this can't be known at that point
52585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
52595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, NULL);
52605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	start0 = ctxt->state;
52615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, NULL);
52625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	start = ctxt->state;
52635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	oldend = ctxt->end;
52645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->end = NULL;
52655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->atom = NULL;
52665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFAParseRegExp(ctxt, 0);
52675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR == ')') {
52685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
52695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
52705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ERROR("xmlFAParseAtom: expecting ')'");
52715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
52725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_SUBREG);
52735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->atom == NULL)
52745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
52755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->atom->start = start;
52765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->atom->start0 = start0;
52775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->atom->stop = ctxt->state;
52785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->end = oldend;
52795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
52805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((CUR == '[') || (CUR == '\\') || (CUR == '.')) {
52815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFAParseCharClass(ctxt);
52825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
52835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
52845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
52855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
52865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
52885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParsePiece:
52895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
52905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
52915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [3]   piece   ::=   atom quantifier?
52925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
52935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
52945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParsePiece(xmlRegParserCtxtPtr ctxt) {
52955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret;
52965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->atom = NULL;
52985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlFAParseAtom(ctxt);
52995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == 0)
53005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
53015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->atom == NULL) {
53025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("internal: no atom generated");
53035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
53045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFAParseQuantifier(ctxt);
53055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(1);
53065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
53075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
53095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseBranch:
53105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
53115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: optional target to the end of the branch
53125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
53135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to is used to optimize by removing duplicate path in automata
53145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in expressions like (a|b)(c|d)
53155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
53165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [2]   branch   ::=   piece*
53175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
53185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
53195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) {
53205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr previous;
53215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret;
53225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    previous = ctxt->state;
53245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlFAParsePiece(ctxt);
53255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret != 0) {
53265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (xmlFAGenerateTransitions(ctxt, previous,
53275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0)
53285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
53295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	previous = ctxt->state;
53305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->atom = NULL;
53315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
53325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((ret != 0) && (ctxt->error == 0)) {
53335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlFAParsePiece(ctxt);
53345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret != 0) {
53355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (xmlFAGenerateTransitions(ctxt, previous,
53365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	            (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0)
53375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(-1);
53385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    previous = ctxt->state;
53395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->atom = NULL;
53405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
53415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
53425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
53435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
53445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
53465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseRegExp:
53475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a regexp parser context
53485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @top:  is this the top-level expression ?
53495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
53505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [1]   regExp   ::=     branch  ( '|' branch )*
53515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
53525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
53535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) {
53545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePtr start, end;
53555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* if not top start should have been generated by an epsilon trans */
53575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    start = ctxt->state;
53585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->end = NULL;
53595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFAParseBranch(ctxt, NULL);
53605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (top) {
53615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH
53625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("State %d is final\n", ctxt->state->no);
53635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
53645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->state->type = XML_REGEXP_FINAL_STATE;
53655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
53665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR != '|') {
53675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->end = ctxt->state;
53685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
53695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
53705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    end = ctxt->state;
53715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((CUR == '|') && (ctxt->error == 0)) {
53725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
53735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->state = start;
53745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->end = NULL;
53755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFAParseBranch(ctxt, end);
53765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
53775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!top) {
53785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->state = end;
53795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->end = end;
53805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
53815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
53825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
53845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
53855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 			The basic API					*
53865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
53875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
53885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
53905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegexpPrint:
53915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @output: the file for the output debug
53925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @regexp: the compiled regexp
53935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
53945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Print the content of the compiled regular expression
53955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
53965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
53975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpPrint(FILE *output, xmlRegexpPtr regexp) {
53985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
53995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (output == NULL)
54015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
54025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, " regexp: ");
54035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (regexp == NULL) {
54045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, "NULL\n");
54055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
54065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
54075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "'%s' ", regexp->string);
54085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "\n");
54095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "%d atoms:\n", regexp->nbAtoms);
54105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < regexp->nbAtoms; i++) {
54115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, " %02d ", i);
54125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegPrintAtom(output, regexp->atoms[i]);
54135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
54145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "%d states:", regexp->nbStates);
54155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "\n");
54165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < regexp->nbStates; i++) {
54175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegPrintState(output, regexp->states[i]);
54185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
54195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(output, "%d counters:\n", regexp->nbCounters);
54205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < regexp->nbCounters; i++) {
54215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fprintf(output, " %d: min %d max %d\n", i, regexp->counters[i].min,
54225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                                regexp->counters[i].max);
54235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
54245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
54255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
54275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegexpCompile:
54285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @regexp:  a regular expression string
54295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
54305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parses a regular expression conforming to XML Schemas Part 2 Datatype
54315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Appendix F and builds an automata suitable for testing strings against
54325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * that regular expression
54335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
54345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the compiled expression or NULL in case of error
54355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
54365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpPtr
54375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpCompile(const xmlChar *regexp) {
54385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegexpPtr ret;
54395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegParserCtxtPtr ctxt;
54405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt = xmlRegNewParserCtxt(regexp);
54425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL)
54435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
54445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* initialize the parser */
54465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->end = NULL;
54475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->start = ctxt->state = xmlRegNewState(ctxt);
54485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePush(ctxt, ctxt->start);
54495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* parse the expression building an automata */
54515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFAParseRegExp(ctxt, 1);
54525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR != 0) {
54535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ERROR("xmlFAParseRegExp: extra characters");
54545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
54555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->error != 0) {
54565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegFreeParserCtxt(ctxt);
54575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
54585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
54595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->end = ctxt->state;
54605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->start->type = XML_REGEXP_START_STATE;
54615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->end->type = XML_REGEXP_FINAL_STATE;
54625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* remove the Epsilon except for counted transitions */
54645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFAEliminateEpsilonTransitions(ctxt);
54655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->error != 0) {
54685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegFreeParserCtxt(ctxt);
54695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
54705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
54715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlRegEpxFromParse(ctxt);
54725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegFreeParserCtxt(ctxt);
54735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
54745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
54755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
54775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegexpExec:
54785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp:  the compiled regular expression
54795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @content:  the value to check against the regular expression
54805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
54815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check if the regular expression generates the value
54825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
54835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if it matches, 0 if not and a negative value in case of error
54845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
54855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
54865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpExec(xmlRegexpPtr comp, const xmlChar *content) {
54875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((comp == NULL) || (content == NULL))
54885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
54895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(xmlFARegExec(comp, content));
54905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
54915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
54935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegexpIsDeterminist:
54945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp:  the compiled regular expression
54955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
54965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check if the regular expression is determinist
54975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
54985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if it yes, 0 if not and a negative value in case of error
54995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
55005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
55015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpIsDeterminist(xmlRegexpPtr comp) {
55025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlAutomataPtr am;
55035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret;
55045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (comp == NULL)
55065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
55075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (comp->determinist != -1)
55085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(comp->determinist);
55095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am = xmlNewAutomata();
55115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (am->states != NULL) {
55125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i;
55135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < am->nbStates;i++)
55155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegFreeState(am->states[i]);
55165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(am->states);
55175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
55185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->nbAtoms = comp->nbAtoms;
55195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->atoms = comp->atoms;
55205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->nbStates = comp->nbStates;
55215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->states = comp->states;
55225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->determinist = -1;
55235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->flags = comp->flags;
55245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlFAComputesDeterminism(am);
55255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->atoms = NULL;
55265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->states = NULL;
55275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFreeAutomata(am);
55285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    comp->determinist = ret;
55295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
55305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
55315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
55335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegFreeRegexp:
55345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @regexp:  the regexp
55355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
55365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free a regexp
55375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
55385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
55395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegFreeRegexp(xmlRegexpPtr regexp) {
55405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
55415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (regexp == NULL)
55425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
55435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (regexp->string != NULL)
55455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(regexp->string);
55465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (regexp->states != NULL) {
55475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < regexp->nbStates;i++)
55485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegFreeState(regexp->states[i]);
55495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(regexp->states);
55505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
55515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (regexp->atoms != NULL) {
55525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < regexp->nbAtoms;i++)
55535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegFreeAtom(regexp->atoms[i]);
55545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(regexp->atoms);
55555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
55565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (regexp->counters != NULL)
55575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(regexp->counters);
55585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (regexp->compact != NULL)
55595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(regexp->compact);
55605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (regexp->transdata != NULL)
55615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(regexp->transdata);
55625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (regexp->stringMap != NULL) {
55635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0; i < regexp->nbstrings;i++)
55645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(regexp->stringMap[i]);
55655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(regexp->stringMap);
55665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
55675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(regexp);
55695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
55705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_AUTOMATA_ENABLED
55725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
55735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
55745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 			The Automata interface				*
55755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
55765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
55775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
55795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNewAutomata:
55805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
55815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new automata
55825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
55835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new object or NULL in case of failure
55845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
55855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataPtr
55865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNewAutomata(void) {
55875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlAutomataPtr ctxt;
55885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt = xmlRegNewParserCtxt(NULL);
55905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL)
55915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
55925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* initialize the parser */
55945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->end = NULL;
55955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->start = ctxt->state = xmlRegNewState(ctxt);
55965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->start == NULL) {
55975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFreeAutomata(ctxt);
55985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
55995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
56005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->start->type = XML_REGEXP_START_STATE;
56015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xmlRegStatePush(ctxt, ctxt->start) < 0) {
56025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlRegFreeState(ctxt->start);
56035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFreeAutomata(ctxt);
56045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
56055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
56065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->flags = 0;
56075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ctxt);
56095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
56105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
56125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFreeAutomata:
56135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
56145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
56155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free an automata
56165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
56175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
56185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFreeAutomata(xmlAutomataPtr am) {
56195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (am == NULL)
56205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
56215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegFreeParserCtxt(am);
56225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
56235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
56255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataSetFlags:
56265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
56275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @flags:  a set of internal flags
56285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
56295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Set some flags on the automata
56305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
56315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
56325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataSetFlags(xmlAutomataPtr am, int flags) {
56335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (am == NULL)
56345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
56355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->flags |= flags;
56365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
56375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
56395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataGetInitState:
56405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
56415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
56425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Initial state lookup
56435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
56445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the initial state of the automata
56455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
56465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr
56475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataGetInitState(xmlAutomataPtr am) {
56485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (am == NULL)
56495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
56505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(am->start);
56515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
56525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
56545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataSetFinalState:
56555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
56565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @state: a state in this automata
56575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
56585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Makes that state a final state
56595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
56605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 0 or -1 in case of error
56615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
56625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
56635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataSetFinalState(xmlAutomataPtr am, xmlAutomataStatePtr state) {
56645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((am == NULL) || (state == NULL))
56655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
56665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state->type = XML_REGEXP_FINAL_STATE;
56675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
56685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
56695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
56715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewTransition:
56725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
56735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition
56745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL
56755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the input string associated to that transition
56765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data passed to the callback function if the transition is activated
56775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
56785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata
56795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state
56805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by the value of @token
56815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
56825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error
56835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
56845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr
56855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewTransition(xmlAutomataPtr am, xmlAutomataStatePtr from,
56865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 xmlAutomataStatePtr to, const xmlChar *token,
56875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 void *data) {
56885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr atom;
56895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((am == NULL) || (from == NULL) || (token == NULL))
56915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
56925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
56935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom == NULL)
56945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
56955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->data = data;
56965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom == NULL)
56975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
56985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->valuep = xmlStrdup(token);
56995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xmlFAGenerateTransitions(am, from, to, atom) < 0) {
57015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlRegFreeAtom(atom);
57025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
57035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
57045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL)
57055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(am->state);
57065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(to);
57075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
57085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
57105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewTransition2:
57115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
57125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition
57135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL
57145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the first input string associated to that transition
57155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token2: the second input string associated to that transition
57165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data passed to the callback function if the transition is activated
57175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
57185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata
57195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state
57205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by the value of @token
57215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
57225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error
57235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
57245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr
57255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewTransition2(xmlAutomataPtr am, xmlAutomataStatePtr from,
57265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  xmlAutomataStatePtr to, const xmlChar *token,
57275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  const xmlChar *token2, void *data) {
57285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr atom;
57295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((am == NULL) || (from == NULL) || (token == NULL))
57315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
57325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
57335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom == NULL)
57345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
57355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->data = data;
57365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((token2 == NULL) || (*token2 == 0)) {
57375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->valuep = xmlStrdup(token);
57385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
57395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int lenn, lenp;
57405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlChar *str;
57415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	lenn = strlen((char *) token2);
57435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	lenp = strlen((char *) token);
57445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
57465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (str == NULL) {
57475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegFreeAtom(atom);
57485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
57495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
57505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memcpy(&str[0], token, lenp);
57515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str[lenp] = '|';
57525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memcpy(&str[lenp + 1], token2, lenn);
57535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str[lenn + lenp + 1] = 0;
57545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->valuep = str;
57565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
57575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xmlFAGenerateTransitions(am, from, to, atom) < 0) {
57595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlRegFreeAtom(atom);
57605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
57615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
57625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL)
57635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(am->state);
57645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(to);
57655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
57665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
57685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewNegTrans:
57695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
57705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition
57715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL
57725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the first input string associated to that transition
57735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token2: the second input string associated to that transition
57745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data passed to the callback function if the transition is activated
57755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
57765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata
57775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state
57785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by any value except (@token,@token2)
57795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note that if @token2 is not NULL, then (X, NULL) won't match to follow
57805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # the semantic of XSD ##other
57815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
57825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error
57835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
57845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr
57855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewNegTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
57865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       xmlAutomataStatePtr to, const xmlChar *token,
57875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       const xmlChar *token2, void *data) {
57885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr atom;
57895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar err_msg[200];
57905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((am == NULL) || (from == NULL) || (token == NULL))
57925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
57935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
57945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom == NULL)
57955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
57965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->data = data;
57975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->neg = 1;
57985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((token2 == NULL) || (*token2 == 0)) {
57995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->valuep = xmlStrdup(token);
58005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
58015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int lenn, lenp;
58025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlChar *str;
58035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	lenn = strlen((char *) token2);
58055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	lenp = strlen((char *) token);
58065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
58085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (str == NULL) {
58095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegFreeAtom(atom);
58105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
58115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
58125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memcpy(&str[0], token, lenp);
58135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str[lenp] = '|';
58145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memcpy(&str[lenp + 1], token2, lenn);
58155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str[lenn + lenp + 1] = 0;
58165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->valuep = str;
58185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
58195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    snprintf((char *) err_msg, 199, "not %s", (const char *) atom->valuep);
58205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    err_msg[199] = 0;
58215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->valuep2 = xmlStrdup(err_msg);
58225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xmlFAGenerateTransitions(am, from, to, atom) < 0) {
58245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlRegFreeAtom(atom);
58255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
58265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
58275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->negs++;
58285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL)
58295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(am->state);
58305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(to);
58315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
58325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
58345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewCountTrans2:
58355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
58365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition
58375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL
58385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the input string associated to that transition
58395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token2: the second input string associated to that transition
58405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @min:  the minimum successive occurences of token
58415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @max:  the maximum successive occurences of token
58425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data:  data associated to the transition
58435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
58445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata
58455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state
58465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by a succession of input of value @token and @token2 and
58475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * whose number is between @min and @max
58485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
58495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error
58505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
58515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr
58525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
58535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 xmlAutomataStatePtr to, const xmlChar *token,
58545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 const xmlChar *token2,
58555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 int min, int max, void *data) {
58565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr atom;
58575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int counter;
58585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((am == NULL) || (from == NULL) || (token == NULL))
58605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
58615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (min < 0)
58625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
58635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((max < min) || (max < 1))
58645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
58655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
58665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom == NULL)
58675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
58685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((token2 == NULL) || (*token2 == 0)) {
58695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->valuep = xmlStrdup(token);
58705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
58715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int lenn, lenp;
58725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlChar *str;
58735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	lenn = strlen((char *) token2);
58755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	lenp = strlen((char *) token);
58765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
58785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (str == NULL) {
58795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegFreeAtom(atom);
58805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
58815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
58825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memcpy(&str[0], token, lenp);
58835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str[lenp] = '|';
58845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memcpy(&str[lenp + 1], token2, lenn);
58855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str[lenn + lenp + 1] = 0;
58865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->valuep = str;
58885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
58895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->data = data;
58905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (min == 0)
58915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->min = 1;
58925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
58935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->min = min;
58945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->max = max;
58955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
58975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * associate a counter to the transition.
58985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
58995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counter = xmlRegGetCounter(am);
59005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->counters[counter].min = min;
59015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->counters[counter].max = max;
59025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* xmlFAGenerateTransitions(am, from, to, atom); */
59045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL) {
59055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        to = xmlRegNewState(am);
59065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStatePush(am, to);
59075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
59085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStateAddTrans(am, from, atom, to, counter, -1);
59095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPush(am, atom);
59105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->state = to;
59115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL)
59135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to = am->state;
59145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL)
59155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
59165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (min == 0)
59175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFAGenerateEpsilonTransition(am, from, to);
59185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(to);
59195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
59205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
59225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewCountTrans:
59235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
59245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition
59255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL
59265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the input string associated to that transition
59275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @min:  the minimum successive occurences of token
59285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @max:  the maximum successive occurences of token
59295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data:  data associated to the transition
59305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
59315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata
59325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state
59335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by a succession of input of value @token and whose number
59345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is between @min and @max
59355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
59365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error
59375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
59385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr
59395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
59405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 xmlAutomataStatePtr to, const xmlChar *token,
59415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 int min, int max, void *data) {
59425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr atom;
59435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int counter;
59445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((am == NULL) || (from == NULL) || (token == NULL))
59465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
59475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (min < 0)
59485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
59495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((max < min) || (max < 1))
59505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
59515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
59525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom == NULL)
59535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
59545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->valuep = xmlStrdup(token);
59555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->data = data;
59565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (min == 0)
59575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->min = 1;
59585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
59595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->min = min;
59605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->max = max;
59615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
59635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * associate a counter to the transition.
59645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
59655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counter = xmlRegGetCounter(am);
59665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->counters[counter].min = min;
59675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->counters[counter].max = max;
59685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* xmlFAGenerateTransitions(am, from, to, atom); */
59705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL) {
59715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        to = xmlRegNewState(am);
59725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStatePush(am, to);
59735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
59745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStateAddTrans(am, from, atom, to, counter, -1);
59755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPush(am, atom);
59765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->state = to;
59775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL)
59795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to = am->state;
59805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL)
59815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
59825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (min == 0)
59835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFAGenerateEpsilonTransition(am, from, to);
59845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(to);
59855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
59865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
59885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewOnceTrans2:
59895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
59905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition
59915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL
59925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the input string associated to that transition
59935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token2: the second input string associated to that transition
59945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @min:  the minimum successive occurences of token
59955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @max:  the maximum successive occurences of token
59965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data:  data associated to the transition
59975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
59985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata
59995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state
60005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by a succession of input of value @token and @token2 and whose
60015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * number is between @min and @max, moreover that transition can only be
60025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * crossed once.
60035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
60045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error
60055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
60065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr
60075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
60085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 xmlAutomataStatePtr to, const xmlChar *token,
60095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 const xmlChar *token2,
60105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 int min, int max, void *data) {
60115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr atom;
60125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int counter;
60135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((am == NULL) || (from == NULL) || (token == NULL))
60155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
60165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (min < 1)
60175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
60185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((max < min) || (max < 1))
60195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
60205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
60215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom == NULL)
60225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
60235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((token2 == NULL) || (*token2 == 0)) {
60245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->valuep = xmlStrdup(token);
60255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
60265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int lenn, lenp;
60275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlChar *str;
60285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	lenn = strlen((char *) token2);
60305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	lenp = strlen((char *) token);
60315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
60335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (str == NULL) {
60345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlRegFreeAtom(atom);
60355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
60365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
60375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memcpy(&str[0], token, lenp);
60385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str[lenp] = '|';
60395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memcpy(&str[lenp + 1], token2, lenn);
60405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str[lenn + lenp + 1] = 0;
60415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	atom->valuep = str;
60435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
60445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->data = data;
60455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->quant = XML_REGEXP_QUANT_ONCEONLY;
60465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->min = min;
60475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->max = max;
60485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
60495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * associate a counter to the transition.
60505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
60515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counter = xmlRegGetCounter(am);
60525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->counters[counter].min = 1;
60535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->counters[counter].max = 1;
60545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* xmlFAGenerateTransitions(am, from, to, atom); */
60565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL) {
60575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to = xmlRegNewState(am);
60585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStatePush(am, to);
60595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
60605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStateAddTrans(am, from, atom, to, counter, -1);
60615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPush(am, atom);
60625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->state = to;
60635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(to);
60645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
60655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
60695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewOnceTrans:
60705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
60715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition
60725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL
60735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the input string associated to that transition
60745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @min:  the minimum successive occurences of token
60755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @max:  the maximum successive occurences of token
60765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data:  data associated to the transition
60775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
60785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata
60795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state
60805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by a succession of input of value @token and whose number
60815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is between @min and @max, moreover that transition can only be crossed
60825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * once.
60835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
60845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error
60855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
60865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr
60875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
60885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 xmlAutomataStatePtr to, const xmlChar *token,
60895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 int min, int max, void *data) {
60905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPtr atom;
60915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int counter;
60925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((am == NULL) || (from == NULL) || (token == NULL))
60945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
60955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (min < 1)
60965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
60975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((max < min) || (max < 1))
60985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
60995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
61005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (atom == NULL)
61015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
61025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->valuep = xmlStrdup(token);
61035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->data = data;
61045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->quant = XML_REGEXP_QUANT_ONCEONLY;
61055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->min = min;
61065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    atom->max = max;
61075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
61085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * associate a counter to the transition.
61095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
61105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counter = xmlRegGetCounter(am);
61115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->counters[counter].min = 1;
61125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->counters[counter].max = 1;
61135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* xmlFAGenerateTransitions(am, from, to, atom); */
61155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL) {
61165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	to = xmlRegNewState(am);
61175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRegStatePush(am, to);
61185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
61195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStateAddTrans(am, from, atom, to, counter, -1);
61205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegAtomPush(am, atom);
61215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->state = to;
61225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(to);
61235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
61245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
61265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewState:
61275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
61285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
61295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new disconnected state in the automata
61305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
61315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new state or NULL in case of error
61325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
61335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr
61345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewState(xmlAutomataPtr am) {
61355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlAutomataStatePtr to;
61365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (am == NULL)
61385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
61395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to = xmlRegNewState(am);
61405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegStatePush(am, to);
61415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(to);
61425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
61435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
61455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewEpsilon:
61465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
61475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition
61485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL
61495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
61505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata
61515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds an epsilon transition from the @from state to the
61525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * target state
61535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
61545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error
61555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
61565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr
61575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewEpsilon(xmlAutomataPtr am, xmlAutomataStatePtr from,
61585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      xmlAutomataStatePtr to) {
61595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((am == NULL) || (from == NULL))
61605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
61615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFAGenerateEpsilonTransition(am, from, to);
61625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL)
61635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(am->state);
61645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(to);
61655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
61665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
61685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewAllTrans:
61695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
61705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition
61715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL
61725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @lax: allow to transition if not all all transitions have been activated
61735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
61745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata
61755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a an ALL transition from the @from state to the
61765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * target state. That transition is an epsilon transition allowed only when
61775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all transitions from the @from node have been activated.
61785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
61795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error
61805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
61815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr
61825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewAllTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
61835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       xmlAutomataStatePtr to, int lax) {
61845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((am == NULL) || (from == NULL))
61855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
61865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFAGenerateAllTransition(am, from, to, lax);
61875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL)
61885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(am->state);
61895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(to);
61905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
61915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
61935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewCounter:
61945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
61955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @min:  the minimal value on the counter
61965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @max:  the maximal value on the counter
61975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
61985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new counter
61995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
62005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the counter number or -1 in case of error
62015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
62025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
62035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewCounter(xmlAutomataPtr am, int min, int max) {
62045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret;
62055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (am == NULL)
62075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
62085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlRegGetCounter(am);
62105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret < 0)
62115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
62125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->counters[ret].min = min;
62135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    am->counters[ret].max = max;
62145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
62155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
62185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewCountedTrans:
62195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
62205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition
62215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL
62225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @counter: the counter associated to that transition
62235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
62245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata
62255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds an epsilon transition from the @from state to the target state
62265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * which will increment the counter provided
62275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
62285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error
62295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
62305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr
62315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewCountedTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
62325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlAutomataStatePtr to, int counter) {
62335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((am == NULL) || (from == NULL) || (counter < 0))
62345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
62355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFAGenerateCountedEpsilonTransition(am, from, to, counter);
62365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL)
62375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(am->state);
62385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(to);
62395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
62425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewCounterTrans:
62435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
62445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition
62455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL
62465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @counter: the counter associated to that transition
62475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
62485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata
62495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds an epsilon transition from the @from state to the target state
62505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * which will be allowed only if the counter is within the right range.
62515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
62525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error
62535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
62545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr
62555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewCounterTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
62565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlAutomataStatePtr to, int counter) {
62575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((am == NULL) || (from == NULL) || (counter < 0))
62585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
62595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFAGenerateCountedTransition(am, from, to, counter);
62605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (to == NULL)
62615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(am->state);
62625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(to);
62635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
62665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataCompile:
62675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
62685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
62695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the automata into a Reg Exp ready for being executed.
62705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The automata should be free after this point.
62715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
62725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the compiled regexp or NULL in case of error
62735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
62745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpPtr
62755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataCompile(xmlAutomataPtr am) {
62765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRegexpPtr ret;
62775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((am == NULL) || (am->error != 0)) return(NULL);
62795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFAEliminateEpsilonTransitions(am);
62805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* xmlFAComputesDeterminism(am); */
62815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlRegEpxFromParse(am);
62825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
62845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
62875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataIsDeterminist:
62885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata
62895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
62905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Checks if an automata is determinist.
62915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
62925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if true, 0 if not, and -1 in case of error
62935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
62945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
62955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataIsDeterminist(xmlAutomataPtr am) {
62965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret;
62975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (am == NULL)
62995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
63005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlFAComputesDeterminism(am);
63025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
63035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
63045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* LIBXML_AUTOMATA_ENABLED */
63055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_EXPR_ENABLED
63075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
63085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
63095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *		Formal Expression handling code				*
63105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
63115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
63125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
63135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
63145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *		Expression handling context				*
63155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
63165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
63175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlExpCtxt {
63195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlDictPtr dict;
63205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr *table;
63215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int size;
63225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbElems;
63235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nb_nodes;
63245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int maxNodes;
63255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *expr;
63265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *cur;
63275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nb_cons;
63285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int tabSize;
63295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
63305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
63325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpNewCtxt:
63335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @maxNodes:  the maximum number of nodes
63345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @dict:  optional dictionnary to use internally
63355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
63365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Creates a new context for manipulating expressions
63375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
63385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the context or NULL in case of error
63395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
63405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpCtxtPtr
63415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNewCtxt(int maxNodes, xmlDictPtr dict) {
63425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpCtxtPtr ret;
63435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int size = 256;
63445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (maxNodes <= 4096)
63465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        maxNodes = 4096;
63475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlExpCtxtPtr) xmlMalloc(sizeof(xmlExpCtxt));
63495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL)
63505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
63515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0, sizeof(xmlExpCtxt));
63525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->size = size;
63535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->nbElems = 0;
63545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->maxNodes = maxNodes;
63555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->table = xmlMalloc(size * sizeof(xmlExpNodePtr));
63565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret->table == NULL) {
63575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlFree(ret);
63585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
63595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
63605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret->table, 0, size * sizeof(xmlExpNodePtr));
63615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dict == NULL) {
63625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret->dict = xmlDictCreate();
63635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret->dict == NULL) {
63645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(ret->table);
63655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(ret);
63665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
63675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
63685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
63695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret->dict = dict;
63705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlDictReference(ret->dict);
63715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
63725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
63735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
63745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
63765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpFreeCtxt:
63775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  an expression context
63785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
63795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free an expression context
63805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
63815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
63825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpFreeCtxt(xmlExpCtxtPtr ctxt) {
63835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL)
63845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
63855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlDictFree(ctxt->dict);
63865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->table != NULL)
63875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(ctxt->table);
63885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(ctxt);
63895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
63905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
63925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
63935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *		Structure associated to an expression node		*
63945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
63955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
63965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX_NODES 10000
63975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_DERIV */
63995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
64015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO:
64025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - Wildcards
64035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - public API for creation
64045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
64055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Started
64065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - regression testing
64075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
64085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Done
64095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - split into module and test tool
64105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - memleaks
64115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
64125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum {
64145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_EXP_NILABLE = (1 << 0)
64155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xmlExpNodeInfo;
64165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IS_NILLABLE(node) ((node)->info & XML_EXP_NILABLE)
64185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlExpNode {
64205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char type;/* xmlExpNodeType */
64215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char info;/* OR of xmlExpNodeInfo */
64225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned short key;	/* the hash key */
64235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int ref;	/* The number of references */
64245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int c_max;		/* the maximum length it can consume */
64255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr exp_left;
64265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr next;/* the next node in the hash table or free list */
64275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    union {
64285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
64295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int f_min;
64305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int f_max;
64315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} count;
64325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
64335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpNodePtr f_right;
64345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} children;
64355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const xmlChar *f_str;
64365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } field;
64375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
64385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define exp_min field.count.f_min
64405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define exp_max field.count.f_max
64415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define exp_left field.children.f_left */
64425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define exp_right field.children.f_right
64435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define exp_str field.f_str
64445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr xmlExpNewNode(xmlExpCtxtPtr ctxt, xmlExpNodeType type);
64465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNode forbiddenExpNode = {
64475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_EXP_FORBID, 0, 0, 0, 0, NULL, NULL, {{ 0, 0}}
64485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
64495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr forbiddenExp = &forbiddenExpNode;
64505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNode emptyExpNode = {
64515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XML_EXP_EMPTY, 1, 0, 0, 0, NULL, NULL, {{ 0, 0}}
64525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
64535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr emptyExp = &emptyExpNode;
64545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
64565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
64575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  The custom hash table for unicity and canonicalization		*
64585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  of sub-expressions pointers						*
64595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
64605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
64615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
64625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpHashNameComputeKey:
64635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Calculate the hash key for a token
64645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
64655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned short
64665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpHashNameComputeKey(const xmlChar *name) {
64675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned short value = 0L;
64685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char ch;
64695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name != NULL) {
64715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	value += 30 * (*name);
64725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while ((ch = *name++) != 0) {
64735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    value = value ^ ((value << 5) + (value >> 3) + (unsigned short)ch);
64745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
64755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
64765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (value);
64775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
64785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
64805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpHashComputeKey:
64815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Calculate the hash key for a compound expression
64825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
64835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned short
64845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpHashComputeKey(xmlExpNodeType type, xmlExpNodePtr left,
64855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     xmlExpNodePtr right) {
64865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long value;
64875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned short ret;
64885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (type) {
64905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_SEQ:
64915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    value = left->key;
64925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    value += right->key;
64935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    value *= 3;
64945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = (unsigned short) value;
64955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
64965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_OR:
64975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    value = left->key;
64985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    value += right->key;
64995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    value *= 7;
65005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = (unsigned short) value;
65015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
65025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_COUNT:
65035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    value = left->key;
65045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    value += right->key;
65055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = (unsigned short) value;
65065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
65075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
65085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
65095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
65105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
65115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
65125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr
65155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNewNode(xmlExpCtxtPtr ctxt, xmlExpNodeType type) {
65165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr ret;
65175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->nb_nodes >= MAX_NODES)
65195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
65205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlExpNodePtr) xmlMalloc(sizeof(xmlExpNode));
65215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL)
65225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
65235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0, sizeof(xmlExpNode));
65245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = type;
65255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->next = NULL;
65265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->nb_nodes++;
65275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->nb_cons++;
65285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
65295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
65305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
65325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpHashGetEntry:
65335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @table: the hash table
65345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the unique entry from the hash table. The entry is created if
65365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * needed. @left and @right are consumed, i.e. their ref count will
65375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * be decremented by the operation.
65385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the pointer or NULL in case of error
65405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
65415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr
65425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpHashGetEntry(xmlExpCtxtPtr ctxt, xmlExpNodeType type,
65435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   xmlExpNodePtr left, xmlExpNodePtr right,
65445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   const xmlChar *name, int min, int max) {
65455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned short kbase, key;
65465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr entry;
65475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr insert;
65485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL)
65505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
65515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
65535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Check for duplicate and insertion location.
65545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
65555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (type == XML_EXP_ATOM) {
65565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	kbase = xmlExpHashNameComputeKey(name);
65575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (type == XML_EXP_COUNT) {
65585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* COUNT reduction rule 1 */
65595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* a{1} -> a */
65605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (min == max) {
65615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (min == 1) {
65625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(left);
65635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
65645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (min == 0) {
65655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlExpFree(ctxt, left);
65665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(emptyExp);
65675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
65685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
65695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (min < 0) {
65705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, left);
65715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(forbiddenExp);
65725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
65735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (max == -1)
65745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    kbase = min + 79;
65755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
65765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    kbase = max - min;
65775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	kbase += left->key;
65785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (type == XML_EXP_OR) {
65795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Forbid reduction rules */
65805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (left->type == XML_EXP_FORBID) {
65815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, left);
65825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(right);
65835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
65845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (right->type == XML_EXP_FORBID) {
65855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, right);
65865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(left);
65875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
65885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* OR reduction rule 1 */
65905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* a | a reduced to a */
65915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (left == right) {
65925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    left->ref--;
65935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(left);
65945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
65955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* OR canonicalization rule 1 */
65965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* linearize (a | b) | c into a | (b | c) */
65975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ((left->type == XML_EXP_OR) && (right->type != XML_EXP_OR)) {
65985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpNodePtr tmp = left;
65995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            left = right;
66005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    right = tmp;
66015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
66025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* OR reduction rule 2 */
66035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* a | (a | b) and b | (a | b) are reduced to a | b */
66045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (right->type == XML_EXP_OR) {
66055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((left == right->exp_left) ||
66065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (left == right->exp_right)) {
66075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlExpFree(ctxt, left);
66085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(right);
66095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
66105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
66115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* OR canonicalization rule 2 */
66125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* linearize (a | b) | c into a | (b | c) */
66135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (left->type == XML_EXP_OR) {
66145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpNodePtr tmp;
66155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* OR canonicalization rule 2 */
66175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((left->exp_right->type != XML_EXP_OR) &&
66185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (left->exp_right->key < left->exp_left->key)) {
66195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        tmp = left->exp_right;
66205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		left->exp_right = left->exp_left;
66215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		left->exp_left = tmp;
66225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
66235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    left->exp_right->ref++;
66245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left->exp_right, right,
66255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                             NULL, 0, 0);
66265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    left->exp_left->ref++;
66275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left->exp_left, tmp,
66285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                             NULL, 0, 0);
66295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, left);
66315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(tmp);
66325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
66335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (right->type == XML_EXP_OR) {
66345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Ordering in the tree */
66355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* C | (A | B) -> A | (B | C) */
66365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (left->key > right->exp_right->key) {
66375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlExpNodePtr tmp;
66385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		right->exp_right->ref++;
66395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_right,
66405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                         left, NULL, 0, 0);
66415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		right->exp_left->ref++;
66425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_left,
66435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                         tmp, NULL, 0, 0);
66445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlExpFree(ctxt, right);
66455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(tmp);
66465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
66475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Ordering in the tree */
66485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* B | (A | C) -> A | (B | C) */
66495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (left->key > right->exp_left->key) {
66505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlExpNodePtr tmp;
66515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		right->exp_right->ref++;
66525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left,
66535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                         right->exp_right, NULL, 0, 0);
66545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		right->exp_left->ref++;
66555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_left,
66565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                         tmp, NULL, 0, 0);
66575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlExpFree(ctxt, right);
66585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(tmp);
66595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
66605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
66615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* we know both types are != XML_EXP_OR here */
66625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else if (left->key > right->key) {
66635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpNodePtr tmp = left;
66645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            left = right;
66655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    right = tmp;
66665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
66675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	kbase = xmlExpHashComputeKey(type, left, right);
66685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (type == XML_EXP_SEQ) {
66695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Forbid reduction rules */
66705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (left->type == XML_EXP_FORBID) {
66715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, right);
66725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(left);
66735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
66745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (right->type == XML_EXP_FORBID) {
66755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, left);
66765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(right);
66775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
66785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Empty reduction rules */
66795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (right->type == XML_EXP_EMPTY) {
66805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(left);
66815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
66825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (left->type == XML_EXP_EMPTY) {
66835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(right);
66845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
66855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	kbase = xmlExpHashComputeKey(type, left, right);
66865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else
66875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
66885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key = kbase % ctxt->size;
66905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->table[key] != NULL) {
66915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (insert = ctxt->table[key]; insert != NULL;
66925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     insert = insert->next) {
66935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((insert->key == kbase) &&
66945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (insert->type == type)) {
66955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (type == XML_EXP_ATOM) {
66965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (name == insert->exp_str) {
66975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			insert->ref++;
66985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return(insert);
66995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
67005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if (type == XML_EXP_COUNT) {
67015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((insert->exp_min == min) && (insert->exp_max == max) &&
67025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        (insert->exp_left == left)) {
67035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			insert->ref++;
67045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			left->ref--;
67055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return(insert);
67065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
67075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if ((insert->exp_left == left) &&
67085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   (insert->exp_right == right)) {
67095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    insert->ref++;
67105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    left->ref--;
67115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    right->ref--;
67125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(insert);
67135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
67145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
67155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
67165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
67175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry = xmlExpNewNode(ctxt, type);
67195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (entry == NULL)
67205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
67215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry->key = kbase;
67225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (type == XML_EXP_ATOM) {
67235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry->exp_str = name;
67245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry->c_max = 1;
67255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (type == XML_EXP_COUNT) {
67265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entry->exp_min = min;
67275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entry->exp_max = max;
67285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry->exp_left = left;
67295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((min == 0) || (IS_NILLABLE(left)))
67305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    entry->info |= XML_EXP_NILABLE;
67315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (max < 0)
67325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    entry->c_max = -1;
67335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
67345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    entry->c_max = max * entry->exp_left->c_max;
67355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
67365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry->exp_left = left;
67375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry->exp_right = right;
67385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (type == XML_EXP_OR) {
67395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((IS_NILLABLE(left)) || (IS_NILLABLE(right)))
67405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		entry->info |= XML_EXP_NILABLE;
67415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((entry->exp_left->c_max == -1) ||
67425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (entry->exp_right->c_max == -1))
67435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		entry->c_max = -1;
67445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else if (entry->exp_left->c_max > entry->exp_right->c_max)
67455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        entry->c_max = entry->exp_left->c_max;
67465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
67475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        entry->c_max = entry->exp_right->c_max;
67485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
67495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((IS_NILLABLE(left)) && (IS_NILLABLE(right)))
67505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		entry->info |= XML_EXP_NILABLE;
67515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((entry->exp_left->c_max == -1) ||
67525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (entry->exp_right->c_max == -1))
67535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		entry->c_max = -1;
67545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
67555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        entry->c_max = entry->exp_left->c_max + entry->exp_right->c_max;
67565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
67575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
67585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry->ref = 1;
67595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->table[key] != NULL)
67605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entry->next = ctxt->table[key];
67615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->table[key] = entry;
67635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->nbElems++;
67645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(entry);
67665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
67675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
67695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpFree:
67705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context
67715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the expression
67725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
67735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Dereference the expression
67745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
67755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
67765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpFree(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp) {
67775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((exp == NULL) || (exp == forbiddenExp) || (exp == emptyExp))
67785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
67795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exp->ref--;
67805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exp->ref == 0) {
67815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned short key;
67825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Unlink it first from the hash table */
67845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	key = exp->key % ctxt->size;
67855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->table[key] == exp) {
67865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->table[key] = exp->next;
67875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
67885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpNodePtr tmp;
67895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = ctxt->table[key];
67915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    while (tmp != NULL) {
67925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        if (tmp->next == exp) {
67935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    tmp->next = exp->next;
67945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
67955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
67965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        tmp = tmp->next;
67975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
67985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
67995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ((exp->type == XML_EXP_SEQ) || (exp->type == XML_EXP_OR)) {
68015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, exp->exp_left);
68025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, exp->exp_right);
68035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (exp->type == XML_EXP_COUNT) {
68045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, exp->exp_left);
68055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
68065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlFree(exp);
68075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->nb_nodes--;
68085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
68095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
68125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpRef:
68135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the expression
68145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
68155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Increase the reference count of the expression
68165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
68175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
68185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpRef(xmlExpNodePtr exp) {
68195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exp != NULL)
68205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        exp->ref++;
68215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
68245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpNewAtom:
68255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context
68265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name: the atom name
68275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: the atom name lenght in byte (or -1);
68285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
68295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the atom associated to this name from that context
68305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
68315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the node or NULL in case of error
68325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
68335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr
68345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNewAtom(xmlExpCtxtPtr ctxt, const xmlChar *name, int len) {
68355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt == NULL) || (name == NULL))
68365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
68375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name = xmlDictLookup(ctxt->dict, name, len);
68385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name == NULL)
68395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
68405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(xmlExpHashGetEntry(ctxt, XML_EXP_ATOM, NULL, NULL, name, 0, 0));
68415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
68445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpNewOr:
68455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context
68465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @left: left expression
68475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @right: right expression
68485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
68495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the atom associated to the choice @left | @right
68505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note that @left and @right are consumed in the operation, to keep
68515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * an handle on them use xmlExpRef() and use xmlExpFree() to release them,
68525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is true even in case of failure (unless ctxt == NULL).
68535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
68545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the node or NULL in case of error
68555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
68565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr
68575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNewOr(xmlExpCtxtPtr ctxt, xmlExpNodePtr left, xmlExpNodePtr right) {
68585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL)
68595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
68605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((left == NULL) || (right == NULL)) {
68615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlExpFree(ctxt, left);
68625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlExpFree(ctxt, right);
68635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
68645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
68655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, left, right, NULL, 0, 0));
68665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
68695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpNewSeq:
68705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context
68715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @left: left expression
68725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @right: right expression
68735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
68745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the atom associated to the sequence @left , @right
68755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note that @left and @right are consumed in the operation, to keep
68765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * an handle on them use xmlExpRef() and use xmlExpFree() to release them,
68775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is true even in case of failure (unless ctxt == NULL).
68785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
68795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the node or NULL in case of error
68805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
68815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr
68825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNewSeq(xmlExpCtxtPtr ctxt, xmlExpNodePtr left, xmlExpNodePtr right) {
68835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL)
68845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
68855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((left == NULL) || (right == NULL)) {
68865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlExpFree(ctxt, left);
68875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlExpFree(ctxt, right);
68885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
68895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
68905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, left, right, NULL, 0, 0));
68915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
68945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpNewRange:
68955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context
68965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @subset: the expression to be repeated
68975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @min: the lower bound for the repetition
68985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @max: the upper bound for the repetition, -1 means infinite
68995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
69005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the atom associated to the range (@subset){@min, @max}
69015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note that @subset is consumed in the operation, to keep
69025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * an handle on it use xmlExpRef() and use xmlExpFree() to release it,
69035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is true even in case of failure (unless ctxt == NULL).
69045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
69055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the node or NULL in case of error
69065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
69075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr
69085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNewRange(xmlExpCtxtPtr ctxt, xmlExpNodePtr subset, int min, int max) {
69095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL)
69105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
69115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((subset == NULL) || (min < 0) || (max < -1) ||
69125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ((max >= 0) && (min > max))) {
69135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlExpFree(ctxt, subset);
69145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
69155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
69165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, subset,
69175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              NULL, NULL, min, max));
69185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
69215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
69225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *		Public API for operations on expressions		*
69235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
69245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
69255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
69275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpGetLanguageInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp,
69285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const xmlChar**list, int len, int nb) {
69295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int tmp, tmp2;
69305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)tail:
69315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (exp->type) {
69325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_EMPTY:
69335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
69345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_ATOM:
69355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (tmp = 0;tmp < nb;tmp++)
69365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        if (list[tmp] == exp->exp_str)
69375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(0);
69385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (nb >= len)
69395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(-2);
69405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    list[nb] = exp->exp_str;
69415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(1);
69425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_COUNT:
69435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exp = exp->exp_left;
69445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto tail;
69455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_SEQ:
69465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_OR:
69475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = xmlExpGetLanguageInt(ctxt, exp->exp_left, list, len, nb);
69485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp < 0)
69495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(tmp);
69505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp2 = xmlExpGetLanguageInt(ctxt, exp->exp_right, list, len,
69515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                                nb + tmp);
69525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp2 < 0)
69535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(tmp2);
69545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return(tmp + tmp2);
69555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
69565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(-1);
69575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
69605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpGetLanguage:
69615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context
69625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the expression
69635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @langList: where to store the tokens
69645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: the allocated lenght of @list
69655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
69665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Find all the strings used in @exp and store them in @list
69675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
69685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of unique strings found, -1 in case of errors and
69695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *         -2 if there is more than @len strings
69705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
69715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
69725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpGetLanguage(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp,
69735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const xmlChar**langList, int len) {
69745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt == NULL) || (exp == NULL) || (langList == NULL) || (len <= 0))
69755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(-1);
69765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(xmlExpGetLanguageInt(ctxt, exp, langList, len, 0));
69775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
69805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpGetStartInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp,
69815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const xmlChar**list, int len, int nb) {
69825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int tmp, tmp2;
69835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)tail:
69845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (exp->type) {
69855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_FORBID:
69865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
69875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_EMPTY:
69885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
69895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_ATOM:
69905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (tmp = 0;tmp < nb;tmp++)
69915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        if (list[tmp] == exp->exp_str)
69925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(0);
69935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (nb >= len)
69945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(-2);
69955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    list[nb] = exp->exp_str;
69965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(1);
69975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_COUNT:
69985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exp = exp->exp_left;
69995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto tail;
70005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_SEQ:
70015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = xmlExpGetStartInt(ctxt, exp->exp_left, list, len, nb);
70025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp < 0)
70035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(tmp);
70045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (IS_NILLABLE(exp->exp_left)) {
70055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tmp2 = xmlExpGetStartInt(ctxt, exp->exp_right, list, len,
70065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    nb + tmp);
70075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (tmp2 < 0)
70085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(tmp2);
70095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tmp += tmp2;
70105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
70115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return(tmp);
70125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_OR:
70135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = xmlExpGetStartInt(ctxt, exp->exp_left, list, len, nb);
70145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp < 0)
70155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(tmp);
70165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp2 = xmlExpGetStartInt(ctxt, exp->exp_right, list, len,
70175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                                nb + tmp);
70185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp2 < 0)
70195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(tmp2);
70205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return(tmp + tmp2);
70215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
70225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(-1);
70235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
70265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpGetStart:
70275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context
70285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the expression
70295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @tokList: where to store the tokens
70305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: the allocated lenght of @list
70315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
70325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Find all the strings that appears at the start of the languages
70335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * accepted by @exp and store them in @list. E.g. for (a, b) | c
70345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it will return the list [a, c]
70355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
70365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of unique strings found, -1 in case of errors and
70375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *         -2 if there is more than @len strings
70385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
70395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
70405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpGetStart(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp,
70415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const xmlChar**tokList, int len) {
70425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt == NULL) || (exp == NULL) || (tokList == NULL) || (len <= 0))
70435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(-1);
70445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(xmlExpGetStartInt(ctxt, exp, tokList, len, 0));
70455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
70485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpIsNillable:
70495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the expression
70505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
70515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Finds if the expression is nillable, i.e. if it accepts the empty sequqnce
70525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
70535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if nillable, 0 if not and -1 in case of error
70545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
70555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
70565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpIsNillable(xmlExpNodePtr exp) {
70575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exp == NULL)
70585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(-1);
70595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(IS_NILLABLE(exp) != 0);
70605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr
70635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpStringDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, const xmlChar *str)
70645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
70655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr ret;
70665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (exp->type) {
70685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_EXP_EMPTY:
70695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(forbiddenExp);
70705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_EXP_FORBID:
70715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(forbiddenExp);
70725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_EXP_ATOM:
70735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exp->exp_str == str) {
70745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
70755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("deriv atom: equal => Empty\n");
70765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
70775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ret = emptyExp;
70785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
70795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
70805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("deriv atom: mismatch => forbid\n");
70815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
70825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        /* TODO wildcards here */
70835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = forbiddenExp;
70845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
70855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(ret);
70865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_EXP_OR: {
70875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpNodePtr tmp;
70885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
70905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("deriv or: => or(derivs)\n");
70915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
70925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = xmlExpStringDeriveInt(ctxt, exp->exp_left, str);
70935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp == NULL) {
70945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(NULL);
70955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
70965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlExpStringDeriveInt(ctxt, exp->exp_right, str);
70975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret == NULL) {
70985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlExpFree(ctxt, tmp);
70995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(NULL);
71005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
71015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, tmp, ret,
71025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     NULL, 0, 0);
71035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(ret);
71045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
71055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_EXP_SEQ:
71065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
71075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("deriv seq: starting with left\n");
71085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
71095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlExpStringDeriveInt(ctxt, exp->exp_left, str);
71105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret == NULL) {
71115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(NULL);
71125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (ret == forbiddenExp) {
71135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        if (IS_NILLABLE(exp->exp_left)) {
71145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
71155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("deriv seq: left failed but nillable\n");
71165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
71175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = xmlExpStringDeriveInt(ctxt, exp->exp_right, str);
71185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
71195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
71205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
71215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("deriv seq: left match => sequence\n");
71225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
71235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        exp->exp_right->ref++;
71245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, exp->exp_right,
71255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                         NULL, 0, 0);
71265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
71275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(ret);
71285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XML_EXP_COUNT: {
71295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int min, max;
71305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpNodePtr tmp;
71315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exp->exp_max == 0)
71335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(forbiddenExp);
71345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlExpStringDeriveInt(ctxt, exp->exp_left, str);
71355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret == NULL)
71365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(NULL);
71375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret == forbiddenExp) {
71385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
71395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("deriv count: pattern mismatch => forbid\n");
71405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
71415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(ret);
71425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
71435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exp->exp_max == 1)
71445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(ret);
71455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exp->exp_max < 0) /* unbounded */
71465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		max = -1;
71475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
71485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		max = exp->exp_max - 1;
71495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exp->exp_min > 0)
71505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		min = exp->exp_min - 1;
71515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
71525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		min = 0;
71535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exp->exp_left->ref++;
71545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left, NULL,
71555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				     NULL, min, max);
71565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret == emptyExp) {
71575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
71585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("deriv count: match to empty => new count\n");
71595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
71605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(tmp);
71615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
71625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
71635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("deriv count: match => sequence with new count\n");
71645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
71655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, tmp,
71665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                              NULL, 0, 0));
71675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
71685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
71695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(NULL);
71705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
71715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
71735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpStringDerive:
71745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context
71755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the expression
71765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @str: the string
71775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: the string len in bytes if available
71785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
71795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Do one step of Brzozowski derivation of the expression @exp with
71805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * respect to the input string
71815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
71825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the resulting expression or NULL in case of internal error
71835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
71845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr
71855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpStringDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp,
71865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const xmlChar *str, int len) {
71875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *input;
71885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((exp == NULL) || (ctxt == NULL) || (str == NULL)) {
71905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
71915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
71925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
71935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * check the string is in the dictionnary, if yes use an interned
71945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * copy, otherwise we know it's not an acceptable input
71955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
71965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    input = xmlDictExists(ctxt->dict, str, len);
71975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (input == NULL) {
71985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(forbiddenExp);
71995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
72005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(xmlExpStringDeriveInt(ctxt, exp, input));
72015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
72025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
72045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpCheckCard(xmlExpNodePtr exp, xmlExpNodePtr sub) {
72055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret = 1;
72065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sub->c_max == -1) {
72085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (exp->c_max != -1)
72095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = 0;
72105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((exp->c_max >= 0) && (exp->c_max < sub->c_max)) {
72115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = 0;
72125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
72135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
72145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((IS_NILLABLE(sub)) && (!IS_NILLABLE(exp)))
72155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = 0;
72165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
72175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
72185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
72195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp,
72215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        xmlExpNodePtr sub);
72225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
72235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpDivide:
72245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expressions context
72255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the englobing expression
72265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @sub: the subexpression
72275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @mult: the multiple expression
72285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @remain: the remain from the derivation of the multiple
72295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
72305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check if exp is a multiple of sub, i.e. if there is a finite number n
72315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * so that sub{n} subsume exp
72325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
72335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the multiple value if successful, 0 if it is not a multiple
72345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *         and -1 in case of internel error.
72355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
72365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
72385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpDivide(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub,
72395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             xmlExpNodePtr *mult, xmlExpNodePtr *remain) {
72405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
72415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr tmp, tmp2;
72425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mult != NULL) *mult = NULL;
72445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (remain != NULL) *remain = NULL;
72455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exp->c_max == -1) return(0);
72465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IS_NILLABLE(exp) && (!IS_NILLABLE(sub))) return(0);
72475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 1;i <= exp->c_max;i++) {
72495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sub->ref++;
72505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tmp = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT,
72515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 sub, NULL, NULL, i, i);
72525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == NULL) {
72535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
72545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
72555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!xmlExpCheckCard(tmp, exp)) {
72565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, tmp);
72575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
72585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
72595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp2 = xmlExpExpDeriveInt(ctxt, tmp, exp);
72605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp2 == NULL) {
72615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, tmp);
72625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
72635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
72645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((tmp2 != forbiddenExp) && (IS_NILLABLE(tmp2))) {
72655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (remain != NULL)
72665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        *remain = tmp2;
72675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
72685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlExpFree(ctxt, tmp2);
72695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (mult != NULL)
72705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        *mult = tmp;
72715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
72725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlExpFree(ctxt, tmp);
72735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
72745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("Divide succeeded %d\n", i);
72755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
72765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(i);
72775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
72785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlExpFree(ctxt, tmp);
72795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlExpFree(ctxt, tmp2);
72805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
72815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
72825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("Divide failed\n");
72835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
72845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
72855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
72865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
72885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpExpDeriveInt:
72895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expressions context
72905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the englobing expression
72915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @sub: the subexpression
72925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
72935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Try to do a step of Brzozowski derivation but at a higher level
72945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the input being a subexpression.
72955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
72965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the resulting expression or NULL in case of internal error
72975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
72985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr
72995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
73005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr ret, tmp, tmp2, tmp3;
73015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar **tab;
73025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int len, i;
73035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
73055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * In case of equality and if the expression can only consume a finite
73065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * amount, then the derivation is empty
73075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
73085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((exp == sub) && (exp->c_max >= 0)) {
73095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
73105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf("Equal(exp, sub) and finite -> Empty\n");
73115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
73125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(emptyExp);
73135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
73145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
73155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * decompose sub sequence first
73165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
73175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sub->type == XML_EXP_EMPTY) {
73185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
73195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf("Empty(sub) -> Empty\n");
73205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
73215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exp->ref++;
73225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(exp);
73235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
73245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sub->type == XML_EXP_SEQ) {
73255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
73265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf("Seq(sub) -> decompose\n");
73275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
73285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tmp = xmlExpExpDeriveInt(ctxt, exp, sub->exp_left);
73295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == NULL)
73305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
73315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == forbiddenExp)
73325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(tmp);
73335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlExpExpDeriveInt(ctxt, tmp, sub->exp_right);
73345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlExpFree(ctxt, tmp);
73355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(ret);
73365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
73375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sub->type == XML_EXP_OR) {
73385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
73395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf("Or(sub) -> decompose\n");
73405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
73415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tmp = xmlExpExpDeriveInt(ctxt, exp, sub->exp_left);
73425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == forbiddenExp)
73435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(tmp);
73445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == NULL)
73455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
73465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlExpExpDeriveInt(ctxt, exp, sub->exp_right);
73475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((ret == NULL) || (ret == forbiddenExp)) {
73485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, tmp);
73495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(ret);
73505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
73515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, tmp, ret, NULL, 0, 0));
73525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
73535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!xmlExpCheckCard(exp, sub)) {
73545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
73555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf("CheckCard(exp, sub) failed -> Forbid\n");
73565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
73575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(forbiddenExp);
73585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
73595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (exp->type) {
73605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_EMPTY:
73615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (sub == emptyExp)
73625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(emptyExp);
73635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
73645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("Empty(exp) -> Forbid\n");
73655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
73665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(forbiddenExp);
73675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_FORBID:
73685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
73695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("Forbid(exp) -> Forbid\n");
73705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
73715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(forbiddenExp);
73725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_ATOM:
73735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (sub->type == XML_EXP_ATOM) {
73745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        /* TODO: handle wildcards */
73755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        if (exp->exp_str == sub->exp_str) {
73765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
73775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Atom match -> Empty\n");
73785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
73795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(emptyExp);
73805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
73815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
73825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("Atom mismatch -> Forbid\n");
73835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
73845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(forbiddenExp);
73855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
73865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((sub->type == XML_EXP_COUNT) &&
73875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (sub->exp_max == 1) &&
73885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (sub->exp_left->type == XML_EXP_ATOM)) {
73895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        /* TODO: handle wildcards */
73905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        if (exp->exp_str == sub->exp_left->exp_str) {
73915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
73925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Atom match -> Empty\n");
73935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
73945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(emptyExp);
73955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
73965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
73975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("Atom mismatch -> Forbid\n");
73985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
73995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(forbiddenExp);
74005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
74015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
74025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("Compex exp vs Atom -> Forbid\n");
74035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
74045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(forbiddenExp);
74055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_SEQ:
74065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* try to get the sequence consumed only if possible */
74075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (xmlExpCheckCard(exp->exp_left, sub)) {
74085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* See if the sequence can be consumed directly */
74095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
74105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("Seq trying left only\n");
74115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
74125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub);
74135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((ret != forbiddenExp) && (ret != NULL)) {
74145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
74155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Seq trying left only worked\n");
74165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
74175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
74185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * TODO: assumption here that we are determinist
74195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     *       i.e. we won't get to a nillable exp left
74205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     *       subset which could be matched by the right
74215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     *       part too.
74225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * e.g.: (a | b)+,(a | c) and 'a+,a'
74235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
74245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exp->exp_right->ref++;
74255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret,
74265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					      exp->exp_right, NULL, 0, 0));
74275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
74285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
74295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
74305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("Seq: left too short\n");
74315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
74325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
74335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Try instead to decompose */
74345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (sub->type == XML_EXP_COUNT) {
74355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int min, max;
74365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
74385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("Seq: sub is a count\n");
74395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
74405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub->exp_left);
74415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (ret == NULL)
74425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(NULL);
74435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (ret != forbiddenExp) {
74445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
74455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Seq , Count match on left\n");
74465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
74475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (sub->exp_max < 0)
74485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        max = -1;
74495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	            else
74505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        max = sub->exp_max -1;
74515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (sub->exp_min > 0)
74525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        min = sub->exp_min -1;
74535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    else
74545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        min = 0;
74555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    exp->exp_right->ref++;
74565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    tmp = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret,
74575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                             exp->exp_right, NULL, 0, 0);
74585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (tmp == NULL)
74595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        return(NULL);
74605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sub->exp_left->ref++;
74625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT,
74635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				      sub->exp_left, NULL, NULL, min, max);
74645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (tmp2 == NULL) {
74655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        xmlExpFree(ctxt, tmp);
74665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return(NULL);
74675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
74685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = xmlExpExpDeriveInt(ctxt, tmp, tmp2);
74695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlExpFree(ctxt, tmp);
74705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlExpFree(ctxt, tmp2);
74715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(ret);
74725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
74735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
74745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* we made no progress on structured operations */
74755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
74765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_OR:
74775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
74785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("Or , trying both side\n");
74795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
74805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub);
74815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret == NULL)
74825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(NULL);
74835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = xmlExpExpDeriveInt(ctxt, exp->exp_right, sub);
74845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp == NULL) {
74855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlExpFree(ctxt, ret);
74865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(NULL);
74875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
74885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, tmp, NULL, 0, 0));
74895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_COUNT: {
74905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int min, max;
74915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (sub->type == XML_EXP_COUNT) {
74935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        /*
74945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * Try to see if the loop is completely subsumed
74955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
74965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        tmp = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub->exp_left);
74975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (tmp == NULL)
74985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(NULL);
74995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (tmp == forbiddenExp) {
75005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int mult;
75015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
75035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Count, Count inner don't subsume\n");
75045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
75055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    mult = xmlExpDivide(ctxt, sub->exp_left, exp->exp_left,
75065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                        NULL, &tmp);
75075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (mult <= 0) {
75085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
75095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("Count, Count not multiple => forbidden\n");
75105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
75115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        return(forbiddenExp);
75125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
75135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (sub->exp_max == -1) {
75145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        max = -1;
75155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exp->exp_max == -1) {
75165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (exp->exp_min <= sub->exp_min * mult)
75175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			        min = 0;
75185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    else
75195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			        min = exp->exp_min - sub->exp_min * mult;
75205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			} else {
75215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
75225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    printf("Count, Count finite can't subsume infinite\n");
75235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
75245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            xmlExpFree(ctxt, tmp);
75255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    return(forbiddenExp);
75265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
75275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
75285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (exp->exp_max == -1) {
75295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
75305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    printf("Infinite loop consume mult finite loop\n");
75315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
75325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (exp->exp_min > sub->exp_min * mult) {
75335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				max = -1;
75345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				min = exp->exp_min - sub->exp_min * mult;
75355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    } else {
75365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				max = -1;
75375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				min = 0;
75385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    }
75395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			} else {
75405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (exp->exp_max < sub->exp_max * mult) {
75415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
75425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				printf("loops max mult mismatch => forbidden\n");
75435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
75445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				xmlExpFree(ctxt, tmp);
75455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				return(forbiddenExp);
75465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    }
75475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (sub->exp_max * mult > exp->exp_min)
75485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				min = 0;
75495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    else
75505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				min = exp->exp_min - sub->exp_max * mult;
75515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    max = exp->exp_max - sub->exp_max * mult;
75525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
75535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
75545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if (!IS_NILLABLE(tmp)) {
75555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
75565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * TODO: loop here to try to grow if working on finite
75575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     *       blocks.
75585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
75595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
75605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Count, Count remain not nillable => forbidden\n");
75615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
75625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlExpFree(ctxt, tmp);
75635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(forbiddenExp);
75645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if (sub->exp_max == -1) {
75655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (exp->exp_max == -1) {
75665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        if (exp->exp_min <= sub->exp_min) {
75675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
75685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    printf("Infinite loops Okay => COUNT(0,Inf)\n");
75695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
75705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            max = -1;
75715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    min = 0;
75725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			} else {
75735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
75745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    printf("Infinite loops min => Count(X,Inf)\n");
75755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
75765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            max = -1;
75775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    min = exp->exp_min - sub->exp_min;
75785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
75795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else if (exp->exp_min > sub->exp_min) {
75805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
75815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("loops min mismatch 1 => forbidden ???\n");
75825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
75835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        xmlExpFree(ctxt, tmp);
75845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        return(forbiddenExp);
75855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
75865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			max = -1;
75875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			min = 0;
75885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
75895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
75905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (exp->exp_max == -1) {
75915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
75925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("Infinite loop consume finite loop\n");
75935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
75945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        if (exp->exp_min > sub->exp_min) {
75955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    max = -1;
75965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    min = exp->exp_min - sub->exp_min;
75975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			} else {
75985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    max = -1;
75995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    min = 0;
76005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
76015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
76025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        if (exp->exp_max < sub->exp_max) {
76035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
76045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    printf("loops max mismatch => forbidden\n");
76055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
76065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlExpFree(ctxt, tmp);
76075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    return(forbiddenExp);
76085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
76095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (sub->exp_max > exp->exp_min)
76105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    min = 0;
76115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			else
76125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    min = exp->exp_min - sub->exp_max;
76135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			max = exp->exp_max - sub->exp_max;
76145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
76155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
76165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
76175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("loops match => SEQ(COUNT())\n");
76185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
76195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exp->exp_left->ref++;
76205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left,
76215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                          NULL, NULL, min, max);
76225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (tmp2 == NULL) {
76235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(NULL);
76245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
76255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, tmp, tmp2,
76265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                         NULL, 0, 0);
76275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(ret);
76285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
76295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub);
76305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp == NULL)
76315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(NULL);
76325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp == forbiddenExp) {
76335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
76345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf("loop mismatch => forbidden\n");
76355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
76365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(forbiddenExp);
76375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
76385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exp->exp_min > 0)
76395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		min = exp->exp_min - 1;
76405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
76415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		min = 0;
76425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (exp->exp_max < 0)
76435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		max = -1;
76445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
76455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		max = exp->exp_max - 1;
76465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
76485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("loop match => SEQ(COUNT())\n");
76495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
76505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    exp->exp_left->ref++;
76515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left,
76525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				      NULL, NULL, min, max);
76535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp2 == NULL)
76545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(NULL);
76555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, tmp, tmp2,
76565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				     NULL, 0, 0);
76575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(ret);
76585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
76595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
76605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
76625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("Fallback to derivative\n");
76635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
76645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IS_NILLABLE(sub)) {
76655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!(IS_NILLABLE(exp)))
76665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(forbiddenExp);
76675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
76685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = emptyExp;
76695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else
76705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = NULL;
76715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
76725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * here the structured derivation made no progress so
76735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * we use the default token based derivation to force one more step
76745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
76755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->tabSize == 0)
76765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ctxt->tabSize = 40;
76775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tab = (const xmlChar **) xmlMalloc(ctxt->tabSize *
76795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                               sizeof(const xmlChar *));
76805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tab == NULL) {
76815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
76825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
76835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
76855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * collect all the strings accepted by the subexpression on input
76865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
76875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0);
76885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (len < 0) {
76895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const xmlChar **temp;
76905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = (const xmlChar **) xmlRealloc((xmlChar **) tab, ctxt->tabSize * 2 *
76915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                                     sizeof(const xmlChar *));
76925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp == NULL) {
76935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree((xmlChar **) tab);
76945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
76955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
76965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tab = temp;
76975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->tabSize *= 2;
76985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0);
76995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
77005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < len;i++) {
77015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tmp = xmlExpStringDeriveInt(ctxt, exp, tab[i]);
77025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((tmp == NULL) || (tmp == forbiddenExp)) {
77035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, ret);
77045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree((xmlChar **) tab);
77055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(tmp);
77065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
77075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp2 = xmlExpStringDeriveInt(ctxt, sub, tab[i]);
77085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((tmp2 == NULL) || (tmp2 == forbiddenExp)) {
77095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, tmp);
77105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, ret);
77115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree((xmlChar **) tab);
77125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(tmp);
77135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
77145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp3 = xmlExpExpDeriveInt(ctxt, tmp, tmp2);
77155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlExpFree(ctxt, tmp);
77165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlExpFree(ctxt, tmp2);
77175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((tmp3 == NULL) || (tmp3 == forbiddenExp)) {
77195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, ret);
77205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree((xmlChar **) tab);
77215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(tmp3);
77225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
77235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret == NULL)
77255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = tmp3;
77265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else {
77275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, tmp3, NULL, 0, 0);
77285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ret == NULL) {
77295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlFree((xmlChar **) tab);
77305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        return(NULL);
77315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
77325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
77335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
77345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree((xmlChar **) tab);
77355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
77365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
77375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
77395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpExpDerive:
77405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expressions context
77415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the englobing expression
77425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @sub: the subexpression
77435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
77445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Evaluates the expression resulting from @exp consuming a sub expression @sub
77455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Based on algebraic derivation and sometimes direct Brzozowski derivation
77465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it usually tatkes less than linear time and can handle expressions generating
77475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * infinite languages.
77485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
77495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the resulting expression or NULL in case of internal error, the
77505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *         result must be freed
77515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
77525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr
77535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpExpDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
77545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((exp == NULL) || (ctxt == NULL) || (sub == NULL))
77555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
77565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
77585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * O(1) speedups
77595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
77605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IS_NILLABLE(sub) && (!IS_NILLABLE(exp))) {
77615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
77625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("Sub nillable and not exp : can't subsume\n");
77635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
77645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(forbiddenExp);
77655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
77665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xmlExpCheckCard(exp, sub) == 0) {
77675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
77685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("sub generate longuer sequances than exp : can't subsume\n");
77695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
77705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(forbiddenExp);
77715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
77725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(xmlExpExpDeriveInt(ctxt, exp, sub));
77735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
77745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
77765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpSubsume:
77775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expressions context
77785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the englobing expression
77795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @sub: the subexpression
77805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
77815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check whether @exp accepts all the languages accexpted by @sub
77825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the input being a subexpression.
77835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
77845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if true 0 if false and -1 in case of failure.
77855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
77865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
77875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpSubsume(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
77885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr tmp;
77895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((exp == NULL) || (ctxt == NULL) || (sub == NULL))
77915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(-1);
77925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
77945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * TODO: speedup by checking the language of sub is a subset of the
77955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *       language of exp
77965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
77975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
77985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * O(1) speedups
77995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
78005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IS_NILLABLE(sub) && (!IS_NILLABLE(exp))) {
78015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
78025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("Sub nillable and not exp : can't subsume\n");
78035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
78045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(0);
78055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
78065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xmlExpCheckCard(exp, sub) == 0) {
78075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
78085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("sub generate longuer sequances than exp : can't subsume\n");
78095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
78105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(0);
78115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
78125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tmp = xmlExpExpDeriveInt(ctxt, exp, sub);
78135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV
78145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("Result derivation :\n");
78155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRINT_EXP(tmp);
78165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
78175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tmp == NULL)
78185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(-1);
78195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tmp == forbiddenExp)
78205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
78215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tmp == emptyExp)
78225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
78235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((tmp != NULL) && (IS_NILLABLE(tmp))) {
78245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlExpFree(ctxt, tmp);
78255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(1);
78265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
78275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpFree(ctxt, tmp);
78285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
78295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
78325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
78335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *			Parsing expression 				*
78345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
78355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
78365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr xmlExpParseExpr(xmlExpCtxtPtr ctxt);
78385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef CUR
78405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CUR (*ctxt->cur)
78415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef NEXT
78425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEXT ctxt->cur++;
78435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef IS_BLANK
78445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IS_BLANK(c) ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))
78455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SKIP_BLANKS while (IS_BLANK(*ctxt->cur)) ctxt->cur++;
78465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
78485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpParseNumber(xmlExpCtxtPtr ctxt) {
78495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret = 0;
78505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS
78525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR == '*') {
78535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT
78545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
78555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
78565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((CUR < '0') || (CUR > '9'))
78575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(-1);
78585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((CUR >= '0') && (CUR <= '9')) {
78595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = ret * 10 + (CUR - '0');
78605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT
78615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
78625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
78635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr
78665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpParseOr(xmlExpCtxtPtr ctxt) {
78675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *base;
78685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr ret;
78695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *val;
78705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS
78725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base = ctxt->cur;
78735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (*ctxt->cur == '(') {
78745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NEXT
78755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlExpParseExpr(ctxt);
78765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS
78775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (*ctxt->cur != ')') {
78785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(stderr, "unbalanced '(' : %s\n", base);
78795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, ret);
78805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
78815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
78825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
78835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS
78845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto parse_quantifier;
78855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
78865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((CUR != 0) && (!(IS_BLANK(CUR))) && (CUR != '(') &&
78875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           (CUR != ')') && (CUR != '|') && (CUR != ',') && (CUR != '{') &&
78885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   (CUR != '*') && (CUR != '+') && (CUR != '?') && (CUR != '}'))
78895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
78905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    val = xmlDictLookup(ctxt->dict, BAD_CAST base, ctxt->cur - base);
78915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (val == NULL)
78925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
78935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlExpHashGetEntry(ctxt, XML_EXP_ATOM, NULL, NULL, val, 0, 0);
78945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL)
78955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
78965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS
78975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)parse_quantifier:
78985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR == '{') {
78995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int min, max;
79005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NEXT
79025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	min = xmlExpParseNumber(ctxt);
79035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (min < 0) {
79045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, ret);
79055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
79065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
79075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS
79085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR == ',') {
79095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT
79105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    max = xmlExpParseNumber(ctxt);
79115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SKIP_BLANKS
79125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else
79135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    max = min;
79145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != '}') {
79155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, ret);
79165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
79175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
79185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NEXT
79195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL,
79205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                         min, max);
79215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS
79225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (CUR == '?') {
79235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NEXT
79245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL,
79255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                         0, 1);
79265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS
79275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (CUR == '+') {
79285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NEXT
79295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL,
79305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                         1, -1);
79315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS
79325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (CUR == '*') {
79335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NEXT
79345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL,
79355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                         0, -1);
79365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS
79375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
79385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
79395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
79405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr
79435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpParseSeq(xmlExpCtxtPtr ctxt) {
79445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr ret, right;
79455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlExpParseOr(ctxt);
79475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS
79485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (CUR == '|') {
79495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NEXT
79505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	right = xmlExpParseOr(ctxt);
79515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (right == NULL) {
79525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, ret);
79535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
79545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
79555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, right, NULL, 0, 0);
79565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret == NULL)
79575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
79585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
79595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
79605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
79615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr
79635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpParseExpr(xmlExpCtxtPtr ctxt) {
79645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr ret, right;
79655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlExpParseSeq(ctxt);
79675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS
79685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (CUR == ',') {
79695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NEXT
79705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	right = xmlExpParseSeq(ctxt);
79715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (right == NULL) {
79725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlExpFree(ctxt, ret);
79735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
79745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
79755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, right, NULL, 0, 0);
79765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret == NULL)
79775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
79785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
79795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
79805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
79815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
79835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpParse:
79845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expressions context
79855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @expr: the 0 terminated string
79865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
79875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Minimal parser for regexps, it understand the following constructs
79885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  - string terminals
79895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  - choice operator |
79905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  - sequence operator ,
79915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  - subexpressions (...)
79925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  - usual cardinality operators + * and ?
79935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  - finite sequences  { min, max }
79945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  - infinite sequences { min, * }
79955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * There is minimal checkings made especially no checking on strings values
79965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
79975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a new expression or NULL in case of failure
79985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
79995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr
80005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpParse(xmlExpCtxtPtr ctxt, const char *expr) {
80015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr ret;
80025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->expr = expr;
80045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->cur = expr;
80055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlExpParseExpr(ctxt);
80075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS
80085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (*ctxt->cur != 0) {
80095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlExpFree(ctxt, ret);
80105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(NULL);
80115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
80125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
80135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
80145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
80165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpDumpInt(xmlBufferPtr buf, xmlExpNodePtr expr, int glob) {
80175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpNodePtr c;
80185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expr == NULL) return;
80205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (glob) xmlBufferWriteChar(buf, "(");
80215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (expr->type) {
80225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_EMPTY:
80235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlBufferWriteChar(buf, "empty");
80245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
80255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_FORBID:
80265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlBufferWriteChar(buf, "forbidden");
80275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
80285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_ATOM:
80295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlBufferWriteCHAR(buf, expr->exp_str);
80305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
80315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_SEQ:
80325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    c = expr->exp_left;
80335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR))
80345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlExpDumpInt(buf, c, 1);
80355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
80365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlExpDumpInt(buf, c, 0);
80375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlBufferWriteChar(buf, " , ");
80385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    c = expr->exp_right;
80395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR))
80405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlExpDumpInt(buf, c, 1);
80415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
80425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlExpDumpInt(buf, c, 0);
80435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
80445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_OR:
80455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    c = expr->exp_left;
80465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR))
80475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlExpDumpInt(buf, c, 1);
80485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
80495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlExpDumpInt(buf, c, 0);
80505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlBufferWriteChar(buf, " | ");
80515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    c = expr->exp_right;
80525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR))
80535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlExpDumpInt(buf, c, 1);
80545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
80555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlExpDumpInt(buf, c, 0);
80565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
80575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_EXP_COUNT: {
80585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char rep[40];
80595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    c = expr->exp_left;
80615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR))
80625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlExpDumpInt(buf, c, 1);
80635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
80645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlExpDumpInt(buf, c, 0);
80655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((expr->exp_min == 0) && (expr->exp_max == 1)) {
80665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rep[0] = '?';
80675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rep[1] = 0;
80685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if ((expr->exp_min == 0) && (expr->exp_max == -1)) {
80695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rep[0] = '*';
80705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rep[1] = 0;
80715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if ((expr->exp_min == 1) && (expr->exp_max == -1)) {
80725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rep[0] = '+';
80735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rep[1] = 0;
80745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (expr->exp_max == expr->exp_min) {
80755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        snprintf(rep, 39, "{%d}", expr->exp_min);
80765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (expr->exp_max < 0) {
80775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        snprintf(rep, 39, "{%d,inf}", expr->exp_min);
80785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
80795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        snprintf(rep, 39, "{%d,%d}", expr->exp_min, expr->exp_max);
80805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
80815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rep[39] = 0;
80825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlBufferWriteChar(buf, rep);
80835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
80845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
80855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
80865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    fprintf(stderr, "Error in tree\n");
80875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
80885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (glob)
80895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlBufferWriteChar(buf, ")");
80905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
80915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
80925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpDump:
80935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @buf:  a buffer to receive the output
80945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @expr:  the compiled expression
80955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
80965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Serialize the expression as compiled to the buffer
80975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
80985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
80995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpDump(xmlBufferPtr buf, xmlExpNodePtr expr) {
81005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((buf == NULL) || (expr == NULL))
81015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
81025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlExpDumpInt(buf, expr, 0);
81035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
81065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpMaxToken:
81075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @expr: a compiled expression
81085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
81095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Indicate the maximum number of input a expression can accept
81105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
81115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the maximum length or -1 in case of error
81125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
81135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
81145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpMaxToken(xmlExpNodePtr expr) {
81155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expr == NULL)
81165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(-1);
81175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(expr->c_max);
81185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
81215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpCtxtNbNodes:
81225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an expression context
81235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
81245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Debugging facility provides the number of allocated nodes at a that point
81255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
81265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of nodes in use or -1 in case of error
81275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
81285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
81295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpCtxtNbNodes(xmlExpCtxtPtr ctxt) {
81305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL)
81315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(-1);
81325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ctxt->nb_nodes);
81335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
81365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpCtxtNbCons:
81375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an expression context
81385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
81395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Debugging facility provides the number of allocated nodes over lifetime
81405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
81415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of nodes ever allocated or -1 in case of error
81425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
81435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
81445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpCtxtNbCons(xmlExpCtxtPtr ctxt) {
81455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL)
81465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(-1);
81475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ctxt->nb_cons);
81485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* LIBXML_EXPR_ENABLED */
81515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define bottom_xmlregexp
81525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "elfgcchack.h"
81535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* LIBXML_REGEXP_ENABLED */
8154