xmlregexp.c revision 9543aee99b39f4de58641a66a5747cadd279d0b0
14255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/* 24255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * regexp.c: generic and extensible Regular Expression engine 34255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 44255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Basically designed with the purpose of compiling regexps for 54255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * the variety of validation/shemas mechanisms now available in 6ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * XML related specifications these include: 74255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * - XML-1.0 DTD validation 84255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * - XML Schemas structure part 1 94255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * - XML Schemas Datatypes part 2 especially Appendix F 104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * - RELAX-NG/TREX i.e. the counter proposal 114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * See Copyright for the status of this software. 134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Daniel Veillard <veillard@redhat.com> 154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define IN_LIBXML 184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include "libxml.h" 194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef LIBXML_REGEXP_ENABLED 214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 22cee2b3a5f124e19db46109132c22e1b8faec1c87Daniel Veillard/* #define DEBUG_ERR */ 23fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard 244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <stdio.h> 254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <string.h> 26ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard#ifdef HAVE_LIMITS_H 27ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard#include <limits.h> 28ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard#endif 29ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard 304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/tree.h> 314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/parserInternals.h> 324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/xmlregexp.h> 334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/xmlautomata.h> 344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/xmlunicode.h> 354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 36ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard#ifndef INT_MAX 37ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard#define INT_MAX 123456789 /* easy to flag and big enough for our needs */ 38ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard#endif 39ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard 40c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard/* #define DEBUG_REGEXP_GRAPH */ 4110752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard/* #define DEBUG_REGEXP_EXEC */ 424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/* #define DEBUG_PUSH */ 4323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard/* #define DEBUG_COMPACTION */ 444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 45567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard#define MAX_PUSH 10000000 4694cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard 47ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard#define ERROR(str) \ 48ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard ctxt->error = XML_REGEXP_COMPILE_ERROR; \ 49ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrCompile(ctxt, str); 504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define NEXT ctxt->cur++ 514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define CUR (*(ctxt->cur)) 524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define NXT(index) (ctxt->cur[index]) 534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l) 554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define NEXTL(l) ctxt->cur += l; 56c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard#define XML_REG_STRING_SEPARATOR '|' 57a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack/* 58a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack * Need PREV to check on a '-' within a Character Group. May only be used 59a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack * when it's guaranteed that cur is not at the beginning of ctxt->string! 60a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack */ 61a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack#define PREV (ctxt->cur[-1]) 624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 63e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard/** 64e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * TODO: 65e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 66e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * macro to flag unimplemented blocks 67e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 68e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard#define TODO \ 69e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard xmlGenericError(xmlGenericErrorContext, \ 70e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard "Unimplemented block at %s:%d\n", \ 71e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard __FILE__, __LINE__); 72e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Datatypes and structures * 764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 79fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard/* 80fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * Note: the order of the enums below is significant, do not shuffle 81fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard */ 824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef enum { 834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_EPSILON = 1, 844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_CHARVAL, 854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_RANGES, 86567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard XML_REGEXP_SUBREG, /* used for () sub regexps */ 874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_STRING, 884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_ANYCHAR, /* . */ 894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_ANYSPACE, /* \s */ 904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NOTSPACE, /* \S */ 914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_INITNAME, /* \l */ 92567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard XML_REGEXP_NOTINITNAME, /* \L */ 934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NAMECHAR, /* \c */ 944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NOTNAMECHAR, /* \C */ 954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_DECIMAL, /* \d */ 96567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard XML_REGEXP_NOTDECIMAL, /* \D */ 974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_REALCHAR, /* \w */ 98567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard XML_REGEXP_NOTREALCHAR, /* \W */ 99567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard XML_REGEXP_LETTER = 100, 1004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_LETTER_UPPERCASE, 1014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_LETTER_LOWERCASE, 1024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_LETTER_TITLECASE, 1034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_LETTER_MODIFIER, 1044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_LETTER_OTHERS, 1054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK, 1064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK_NONSPACING, 1074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK_SPACECOMBINING, 1084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK_ENCLOSING, 1094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NUMBER, 1104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NUMBER_DECIMAL, 1114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NUMBER_LETTER, 1124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NUMBER_OTHERS, 1134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT, 1144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_CONNECTOR, 1154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_DASH, 1164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_OPEN, 1174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_CLOSE, 1184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_INITQUOTE, 1194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_FINQUOTE, 1204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_OTHERS, 1214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SEPAR, 1224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SEPAR_SPACE, 1234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SEPAR_LINE, 1244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SEPAR_PARA, 1254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SYMBOL, 1264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SYMBOL_MATH, 1274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SYMBOL_CURRENCY, 1284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SYMBOL_MODIFIER, 1294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SYMBOL_OTHERS, 1304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_OTHER, 1314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_OTHER_CONTROL, 1324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_OTHER_FORMAT, 1334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_OTHER_PRIVATE, 1344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_OTHER_NA, 1354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_BLOCK_NAME 1364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} xmlRegAtomType; 1374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef enum { 1394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_QUANT_EPSILON = 1, 1404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_QUANT_ONCE, 1414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_QUANT_OPT, 1424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_QUANT_MULT, 1434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_QUANT_PLUS, 1447646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard XML_REGEXP_QUANT_ONCEONLY, 1457646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard XML_REGEXP_QUANT_ALL, 1464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_QUANT_RANGE 1474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} xmlRegQuantType; 1484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef enum { 1504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_START_STATE = 1, 1514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_FINAL_STATE, 152cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_TRANS_STATE, 1530e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard XML_REGEXP_SINK_STATE, 1540e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard XML_REGEXP_UNREACH_STATE 1554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} xmlRegStateType; 1564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef enum { 1584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK_NORMAL = 0, 1594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK_START, 1604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK_VISITED 1614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} xmlRegMarkedType; 1624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegRange xmlRegRange; 1644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegRange *xmlRegRangePtr; 1654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegRange { 167f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard int neg; /* 0 normal, 1 not, 2 exclude */ 1684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomType type; 1694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int start; 1704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int end; 1714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *blockName; 1724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 1734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegAtom xmlRegAtom; 1754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegAtom *xmlRegAtomPtr; 1764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlAutomataState xmlRegState; 1784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegState *xmlRegStatePtr; 1794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegAtom { 1814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int no; 1824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomType type; 1834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegQuantType quant; 1844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int min; 1854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int max; 1864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard void *valuep; 188a646cfdb14097f72d3b0ce9b0f43126934d8efd3Daniel Veillard void *valuep2; 1894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int neg; 1904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int codepoint; 1914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr start; 19276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegStatePtr start0; 1934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr stop; 1944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int maxRanges; 1954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbRanges; 1964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegRangePtr *ranges; 1974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard void *data; 1984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 1994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegCounter xmlRegCounter; 2014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegCounter *xmlRegCounterPtr; 2024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegCounter { 2044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int min; 2054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int max; 2064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 2074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegTrans xmlRegTrans; 2094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegTrans *xmlRegTransPtr; 2104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegTrans { 2124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 2134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int to; 2144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int counter; 2154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int count; 216567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int nd; 2174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 2184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlAutomataState { 2204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStateType type; 2214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegMarkedType mark; 22223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegMarkedType reached; 2234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int no; 2244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int maxTrans; 2254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbTrans; 2264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegTrans *trans; 227db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard /* knowing states ponting to us can speed things up */ 228db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int maxTransTo; 229db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int nbTransTo; 230db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int *transTo; 2314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 2324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlAutomata xmlRegParserCtxt; 2344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegParserCtxt *xmlRegParserCtxtPtr; 2354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2361ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard#define AM_AUTOMATA_RNG 1 2371ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard 2384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlAutomata { 2394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *string; 2404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *cur; 2414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int error; 2434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int neg; 2444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr start; 2464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr end; 2474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state; 2484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 2504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int maxAtoms; 2524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbAtoms; 2534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr *atoms; 2544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int maxStates; 2564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbStates; 2574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr *states; 2584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int maxCounters; 2604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbCounters; 2614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegCounter *counters; 262e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 263e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int determinist; 2646e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard int negs; 2651ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard int flags; 2664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 2674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegexp { 2694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *string; 2704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbStates; 2714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr *states; 2724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbAtoms; 2734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr *atoms; 2744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbCounters; 2754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegCounter *counters; 276e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int determinist; 2771ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard int flags; 27823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 27923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * That's the compact form for determinists automatas 28023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 28123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int nbstates; 28223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int *compact; 283118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard void **transdata; 28423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int nbstrings; 28523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlChar **stringMap; 2864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 2874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegExecRollback xmlRegExecRollback; 2894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegExecRollback *xmlRegExecRollbackPtr; 2904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegExecRollback { 2924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state;/* the current state */ 2934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int index; /* the index in the input stack */ 2944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nextbranch; /* the next transition to explore in that state */ 295ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack int *counts; /* save the automata state if it has some */ 2964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 2974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegInputToken xmlRegInputToken; 2994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegInputToken *xmlRegInputTokenPtr; 3004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegInputToken { 3024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *value; 3034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard void *data; 3044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 3054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegExecCtxt { 3074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int status; /* execution status != 0 indicate an error */ 308ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack int determinist; /* did we find an indeterministic behaviour */ 3094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegexpPtr comp; /* the compiled regexp */ 3104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegExecCallbacks callback; 3114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard void *data; 3124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state;/* the current state */ 3144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int transno; /* the current transition on that state */ 315ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack int transcount; /* the number of chars in char counted transitions */ 3164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 3184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * A stack of rollback states 3194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 3204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int maxRollbacks; 3214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbRollbacks; 3224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegExecRollback *rollbacks; 3234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 3254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The state of the automata if any 3264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 3274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int *counts; 3284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 3304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The input stack 3314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 3324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int inputStackMax; 3334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int inputStackNr; 3344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int index; 3354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int *charStack; 3364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard const xmlChar *inputString; /* when operating on characters */ 3374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegInputTokenPtr inputStack;/* when operating on strings */ 3384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3397bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard /* 3407bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * error handling 3417bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard */ 3427bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int errStateNo; /* the error state number */ 3437bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlRegStatePtr errState; /* the error state */ 3447bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlChar *errString; /* the string raising the error */ 3457bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int *errCounts; /* counters at the error state */ 34694cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard int nbPush; 3474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 3484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 349441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard#define REGEXP_ALL_COUNTER 0x123456 350441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard#define REGEXP_ALL_LAX_COUNTER 0x123457 3517646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard 3524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top); 35323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillardstatic void xmlRegFreeState(xmlRegStatePtr state); 35423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillardstatic void xmlRegFreeAtom(xmlRegAtomPtr atom); 3559efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillardstatic int xmlRegStrEqualWildcard(const xmlChar *expStr, const xmlChar *valStr); 356567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillardstatic int xmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint); 357567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillardstatic int xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, 358567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int neg, int start, int end, const xmlChar *blockName); 3594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3601ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillardvoid xmlAutomataSetFlags(xmlAutomataPtr am, int flags); 3611ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard 3624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 363ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * * 364ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * Regexp memory error handler * 365ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * * 366ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard ************************************************************************/ 367ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard/** 368ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * xmlRegexpErrMemory: 369ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * @extra: extra information 370ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * 371ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * Handle an out of memory condition 372ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard */ 373ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillardstatic void 374ff46a0443e6b999297e52c160b88536b8089ec56Daniel VeillardxmlRegexpErrMemory(xmlRegParserCtxtPtr ctxt, const char *extra) 375ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard{ 376ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard const char *regexp = NULL; 377ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard if (ctxt != NULL) { 378ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard regexp = (const char *) ctxt->string; 379ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard ctxt->error = XML_ERR_NO_MEMORY; 380ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard } 381659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_REGEXP, 382ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra, 383ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard regexp, NULL, 0, 0, 384ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard "Memory allocation failed : %s\n", extra); 385ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard} 386ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard 387ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard/** 388ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * xmlRegexpErrCompile: 389ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * @extra: extra information 390ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * 391ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Handle a compilation failure 392ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard */ 393ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillardstatic void 394ff46a0443e6b999297e52c160b88536b8089ec56Daniel VeillardxmlRegexpErrCompile(xmlRegParserCtxtPtr ctxt, const char *extra) 395ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard{ 396ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard const char *regexp = NULL; 397ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard int idx = 0; 398ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard 399ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard if (ctxt != NULL) { 400ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard regexp = (const char *) ctxt->string; 401ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard idx = ctxt->cur - ctxt->string; 402ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard ctxt->error = XML_REGEXP_COMPILE_ERROR; 403ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard } 404659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_REGEXP, 405ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard XML_REGEXP_COMPILE_ERROR, XML_ERR_FATAL, NULL, 0, extra, 406ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard regexp, NULL, idx, 0, 407ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard "failed to compile: %s\n", extra); 408ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard} 409ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard 410ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard/************************************************************************ 4114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 4124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Allocation/Deallocation * 4134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 4144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 4154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 41623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillardstatic int xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt); 4174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 4184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegEpxFromParse: 4194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @ctxt: the parser context used to build it 4204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 421ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Allocate a new regexp and fill it with the result from the parser 4224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 4234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new regexp or NULL in case of error 4244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 4254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegexpPtr 4264255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) { 4274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegexpPtr ret; 4284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 4294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = (xmlRegexpPtr) xmlMalloc(sizeof(xmlRegexp)); 430a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (ret == NULL) { 431ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "compiling regexp"); 4324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 433a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 4344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(ret, 0, sizeof(xmlRegexp)); 4354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->string = ctxt->string; 4364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->nbStates = ctxt->nbStates; 4374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->states = ctxt->states; 4384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->nbAtoms = ctxt->nbAtoms; 4394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->atoms = ctxt->atoms; 4404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->nbCounters = ctxt->nbCounters; 4414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->counters = ctxt->counters; 442e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard ret->determinist = ctxt->determinist; 4431ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard ret->flags = ctxt->flags; 444567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (ret->determinist == -1) { 445567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegexpIsDeterminist(ret); 446567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 44723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 44823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if ((ret->determinist != 0) && 44923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard (ret->nbCounters == 0) && 4506e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard (ctxt->negs == 0) && 451118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard (ret->atoms != NULL) && 45223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard (ret->atoms[0] != NULL) && 45323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard (ret->atoms[0]->type == XML_REGEXP_STRING)) { 45423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int i, j, nbstates = 0, nbatoms = 0; 45523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int *stateRemap; 45623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int *stringRemap; 45723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int *transitions; 458118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard void **transdata; 45923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlChar **stringMap; 46023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlChar *value; 46123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 46223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 46323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Switch to a compact representation 46423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * 1/ counting the effective number of states left 465ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * 2/ counting the unique number of atoms, and check that 46623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * they are all of the string type 46723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * 3/ build a table state x atom for the transitions 46823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 46923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 47023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stateRemap = xmlMalloc(ret->nbStates * sizeof(int)); 471a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (stateRemap == NULL) { 472ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "compiling regexp"); 473a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(ret); 474a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 475a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 47623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < ret->nbStates;i++) { 47723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (ret->states[i] != NULL) { 47823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stateRemap[i] = nbstates; 47923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard nbstates++; 48023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } else { 48123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stateRemap[i] = -1; 48223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 48323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 48423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_COMPACTION 48523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("Final: %d states\n", nbstates); 48623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 48723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stringMap = xmlMalloc(ret->nbAtoms * sizeof(char *)); 488a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (stringMap == NULL) { 489ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "compiling regexp"); 490a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stateRemap); 491a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(ret); 492a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 493a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 49423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stringRemap = xmlMalloc(ret->nbAtoms * sizeof(int)); 495a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (stringRemap == NULL) { 496ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "compiling regexp"); 497a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stringMap); 498a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stateRemap); 499a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(ret); 500a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 501a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 50223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < ret->nbAtoms;i++) { 50323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if ((ret->atoms[i]->type == XML_REGEXP_STRING) && 50423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard (ret->atoms[i]->quant == XML_REGEXP_QUANT_ONCE)) { 50523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard value = ret->atoms[i]->valuep; 50623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (j = 0;j < nbatoms;j++) { 50723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (xmlStrEqual(stringMap[j], value)) { 50823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stringRemap[i] = j; 50923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard break; 51023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 51123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 51223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (j >= nbatoms) { 51323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stringRemap[i] = nbatoms; 51423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stringMap[nbatoms] = xmlStrdup(value); 515a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (stringMap[nbatoms] == NULL) { 516a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard for (i = 0;i < nbatoms;i++) 517a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stringMap[i]); 518a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stringRemap); 519a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stringMap); 520a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stateRemap); 521a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(ret); 522a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 523a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 52423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard nbatoms++; 52523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 52623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } else { 52723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stateRemap); 52823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringRemap); 52923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < nbatoms;i++) 53023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringMap[i]); 53123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringMap); 532a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(ret); 533a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 53423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 53523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 53623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_COMPACTION 53723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("Final: %d atoms\n", nbatoms); 53823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 539a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard transitions = (int *) xmlMalloc((nbstates + 1) * 540a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard (nbatoms + 1) * sizeof(int)); 541a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (transitions == NULL) { 542a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stateRemap); 543a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stringRemap); 544a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stringMap); 545a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(ret); 546a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 547a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 548a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard memset(transitions, 0, (nbstates + 1) * (nbatoms + 1) * sizeof(int)); 54923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 55023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 55123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Allocate the transition table. The first entry for each 552ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * state corresponds to the state type. 55323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 554118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard transdata = NULL; 55523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 55623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < ret->nbStates;i++) { 55723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int stateno, atomno, targetno, prev; 55823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegStatePtr state; 55923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegTransPtr trans; 56023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 56123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stateno = stateRemap[i]; 56223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (stateno == -1) 56323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard continue; 56423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard state = ret->states[i]; 56523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 56623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard transitions[stateno * (nbatoms + 1)] = state->type; 56723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 56823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (j = 0;j < state->nbTrans;j++) { 56923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard trans = &(state->trans[j]); 57023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if ((trans->to == -1) || (trans->atom == NULL)) 57123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard continue; 57223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard atomno = stringRemap[trans->atom->no]; 573118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if ((trans->atom->data != NULL) && (transdata == NULL)) { 574118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard transdata = (void **) xmlMalloc(nbstates * nbatoms * 575118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard sizeof(void *)); 576118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if (transdata != NULL) 577118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard memset(transdata, 0, 578118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard nbstates * nbatoms * sizeof(void *)); 579a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard else { 580ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "compiling regexp"); 581a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard break; 582a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 583118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard } 58423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard targetno = stateRemap[trans->to]; 58523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 586ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * if the same atom can generate transitions to 2 different 58723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * states then it means the automata is not determinist and 58823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * the compact form can't be used ! 58923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 59023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard prev = transitions[stateno * (nbatoms + 1) + atomno + 1]; 59123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (prev != 0) { 59223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (prev != targetno + 1) { 59323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->determinist = 0; 59423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_COMPACTION 59523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("Indet: state %d trans %d, atom %d to %d : %d to %d\n", 59623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard i, j, trans->atom->no, trans->to, atomno, targetno); 59723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf(" previous to is %d\n", prev); 59823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 599118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if (transdata != NULL) 600118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard xmlFree(transdata); 60123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(transitions); 60223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stateRemap); 60323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringRemap); 60423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < nbatoms;i++) 60523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringMap[i]); 60623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringMap); 607a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard goto not_determ; 60823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 60923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } else { 61023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#if 0 61123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("State %d trans %d: atom %d to %d : %d to %d\n", 61223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard i, j, trans->atom->no, trans->to, atomno, targetno); 61323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 61423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard transitions[stateno * (nbatoms + 1) + atomno + 1] = 615118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard targetno + 1; /* to avoid 0 */ 616118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if (transdata != NULL) 617118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard transdata[stateno * nbatoms + atomno] = 618118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard trans->atom->data; 61923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 62023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 62123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 62223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->determinist = 1; 62323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_COMPACTION 62423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 62523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Debug 62623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 62723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < nbstates;i++) { 62823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (j = 0;j < nbatoms + 1;j++) { 62923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("%02d ", transitions[i * (nbatoms + 1) + j]); 63023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 63123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("\n"); 63223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 63323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("\n"); 63423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 63523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 63623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Cleanup of the old data 63723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 63823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (ret->states != NULL) { 63923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < ret->nbStates;i++) 64023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegFreeState(ret->states[i]); 64123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(ret->states); 64223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 64323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->states = NULL; 64423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->nbStates = 0; 64523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (ret->atoms != NULL) { 64623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < ret->nbAtoms;i++) 64723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegFreeAtom(ret->atoms[i]); 64823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(ret->atoms); 64923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 65023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->atoms = NULL; 65123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->nbAtoms = 0; 65223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 65323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->compact = transitions; 654118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard ret->transdata = transdata; 65523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->stringMap = stringMap; 65623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->nbstrings = nbatoms; 65723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->nbstates = nbstates; 65823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stateRemap); 65923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringRemap); 66023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 661a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillardnot_determ: 662a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->string = NULL; 663a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->nbStates = 0; 664a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->states = NULL; 665a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->nbAtoms = 0; 666a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->atoms = NULL; 667a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->nbCounters = 0; 668a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->counters = NULL; 6694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 6704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 6714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 6724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 6734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegNewParserCtxt: 6744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @string: the string to parse 6754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 6764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Allocate a new regexp parser context 6774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 6784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new context or NULL in case of error 6794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 6804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegParserCtxtPtr 6814255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewParserCtxt(const xmlChar *string) { 6824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegParserCtxtPtr ret; 6834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 6844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = (xmlRegParserCtxtPtr) xmlMalloc(sizeof(xmlRegParserCtxt)); 6854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == NULL) 6864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 6874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(ret, 0, sizeof(xmlRegParserCtxt)); 6884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (string != NULL) 6894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->string = xmlStrdup(string); 6904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->cur = ret->string; 6914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->neg = 0; 6926e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard ret->negs = 0; 6934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->error = 0; 694e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard ret->determinist = -1; 6954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 6964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 6974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 6984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 6994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegNewRange: 7004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @ctxt: the regexp parser context 7014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @neg: is that negative 7024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @type: the type of range 7034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @start: the start codepoint 7044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @end: the end codepoint 7054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 7064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Allocate a new regexp range 7074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 7084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new range or NULL in case of error 7094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 7104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegRangePtr 7114255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewRange(xmlRegParserCtxtPtr ctxt, 7124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int neg, xmlRegAtomType type, int start, int end) { 7134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegRangePtr ret; 7144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 7154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = (xmlRegRangePtr) xmlMalloc(sizeof(xmlRegRange)); 7164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == NULL) { 717ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating range"); 7184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 7194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 7204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->neg = neg; 7214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->type = type; 7224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->start = start; 7234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->end = end; 7244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 7254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 7264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 7274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 7284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeRange: 7294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @range: the regexp range 7304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 7314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp range 7324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 7334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 7344255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeRange(xmlRegRangePtr range) { 7354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (range == NULL) 7364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 7374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 7384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (range->blockName != NULL) 7394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(range->blockName); 7404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(range); 7414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 7424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 7434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 74476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * xmlRegCopyRange: 74576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * @range: the regexp range 74676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * 74776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * Copy a regexp range 74876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * 74976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * Returns the new copy or NULL in case of error. 75076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard */ 75176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillardstatic xmlRegRangePtr 75276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel VeillardxmlRegCopyRange(xmlRegParserCtxtPtr ctxt, xmlRegRangePtr range) { 75376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegRangePtr ret; 75476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 75576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (range == NULL) 75676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(NULL); 75776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 75876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret = xmlRegNewRange(ctxt, range->neg, range->type, range->start, 75976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard range->end); 76076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (ret == NULL) 76176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(NULL); 76276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (range->blockName != NULL) { 76376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->blockName = xmlStrdup(range->blockName); 76476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (ret->blockName == NULL) { 76576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating range"); 76676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegFreeRange(ret); 76776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(NULL); 76876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 76976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 77076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(ret); 77176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard} 77276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 77376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard/** 7744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegNewAtom: 7754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @ctxt: the regexp parser context 7764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @type: the type of atom 7774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 77876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * Allocate a new atom 7794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 7804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new atom or NULL in case of error 7814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 7824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegAtomPtr 7834255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewAtom(xmlRegParserCtxtPtr ctxt, xmlRegAtomType type) { 7844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr ret; 7854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 7864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = (xmlRegAtomPtr) xmlMalloc(sizeof(xmlRegAtom)); 7874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == NULL) { 788ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating atom"); 7894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 7904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 7914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(ret, 0, sizeof(xmlRegAtom)); 7924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->type = type; 7934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->quant = XML_REGEXP_QUANT_ONCE; 7944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->min = 0; 7954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->max = 0; 7964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 7974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 7984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 7994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 8004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeAtom: 8014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @atom: the regexp atom 8024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 8034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp atom 8044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 8054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 8064255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeAtom(xmlRegAtomPtr atom) { 8074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 8084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 8094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom == NULL) 8104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 8114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 8124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < atom->nbRanges;i++) 8134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeRange(atom->ranges[i]); 8144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->ranges != NULL) 8154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(atom->ranges); 816de0e498b426e8493ab9e7b22a2f88501e96db000Daniel Veillard if ((atom->type == XML_REGEXP_STRING) && (atom->valuep != NULL)) 817de0e498b426e8493ab9e7b22a2f88501e96db000Daniel Veillard xmlFree(atom->valuep); 81877005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard if ((atom->type == XML_REGEXP_STRING) && (atom->valuep2 != NULL)) 81977005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard xmlFree(atom->valuep2); 820de0e498b426e8493ab9e7b22a2f88501e96db000Daniel Veillard if ((atom->type == XML_REGEXP_BLOCK_NAME) && (atom->valuep != NULL)) 8214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(atom->valuep); 8224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(atom); 8234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 8244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 82576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard/** 82676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * xmlRegCopyAtom: 82776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * @ctxt: the regexp parser context 82876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * @atom: the oiginal atom 82976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * 83076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * Allocate a new regexp range 83176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * 83276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * Returns the new atom or NULL in case of error 83376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard */ 83476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillardstatic xmlRegAtomPtr 83576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel VeillardxmlRegCopyAtom(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) { 83676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegAtomPtr ret; 83776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 83876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret = (xmlRegAtomPtr) xmlMalloc(sizeof(xmlRegAtom)); 83976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (ret == NULL) { 84076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegexpErrMemory(ctxt, "copying atom"); 84176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(NULL); 84276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 84376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard memset(ret, 0, sizeof(xmlRegAtom)); 84476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->type = atom->type; 84576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->quant = atom->quant; 84676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->min = atom->min; 84776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->max = atom->max; 84876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (atom->nbRanges > 0) { 84976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard int i; 85076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 85176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->ranges = (xmlRegRangePtr *) xmlMalloc(sizeof(xmlRegRangePtr) * 85276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard atom->nbRanges); 85376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (ret->ranges == NULL) { 85476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegexpErrMemory(ctxt, "copying atom"); 85576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard goto error; 85676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 85776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard for (i = 0;i < atom->nbRanges;i++) { 85876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->ranges[i] = xmlRegCopyRange(ctxt, atom->ranges[i]); 85976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (ret->ranges[i] == NULL) 86076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard goto error; 86176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->nbRanges = i + 1; 86276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 86376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 86476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(ret); 86576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 86676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillarderror: 86776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegFreeAtom(ret); 86876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(NULL); 86976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard} 87076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 8714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegStatePtr 8724255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewState(xmlRegParserCtxtPtr ctxt) { 8734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr ret; 8744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 8754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = (xmlRegStatePtr) xmlMalloc(sizeof(xmlRegState)); 8764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == NULL) { 877ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating state"); 8784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 8794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 8804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(ret, 0, sizeof(xmlRegState)); 8814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->type = XML_REGEXP_TRANS_STATE; 8824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->mark = XML_REGEXP_MARK_NORMAL; 8834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 8844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 8854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 8864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 8874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeState: 8884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @state: the regexp state 8894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 8904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp state 8914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 8924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 8934255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeState(xmlRegStatePtr state) { 8944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state == NULL) 8954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 8964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 8974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state->trans != NULL) 8984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(state->trans); 899db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (state->transTo != NULL) 900db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlFree(state->transTo); 9014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(state); 9024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 9034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 9044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 9054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeParserCtxt: 9064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @ctxt: the regexp parser context 9074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 9084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp parser context 9094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 9104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 9114255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeParserCtxt(xmlRegParserCtxtPtr ctxt) { 9124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 9134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt == NULL) 9144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 9154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 9164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->string != NULL) 9174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(ctxt->string); 9184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->states != NULL) { 9194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < ctxt->nbStates;i++) 9204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeState(ctxt->states[i]); 9214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(ctxt->states); 9224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 9234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atoms != NULL) { 9244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < ctxt->nbAtoms;i++) 9254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeAtom(ctxt->atoms[i]); 9264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(ctxt->atoms); 9274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 9284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->counters != NULL) 9294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(ctxt->counters); 9304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(ctxt); 9314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 9324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 9334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 9344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 9354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Display of Data structures * 9364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 9374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 9384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 9394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 9404255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintAtomType(FILE *output, xmlRegAtomType type) { 9414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (type) { 9424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_EPSILON: 9434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "epsilon "); break; 9444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_CHARVAL: 9454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "charval "); break; 9464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_RANGES: 9474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "ranges "); break; 9484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SUBREG: 9494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "subexpr "); break; 9504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_STRING: 9514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "string "); break; 9524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_ANYCHAR: 9534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "anychar "); break; 9544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_ANYSPACE: 9554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "anyspace "); break; 9564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTSPACE: 9574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "notspace "); break; 9584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_INITNAME: 9594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "initname "); break; 9604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTINITNAME: 9614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "notinitname "); break; 9624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NAMECHAR: 9634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "namechar "); break; 9644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTNAMECHAR: 9654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "notnamechar "); break; 9664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_DECIMAL: 9674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "decimal "); break; 9684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTDECIMAL: 9694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "notdecimal "); break; 9704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_REALCHAR: 9714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "realchar "); break; 9724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTREALCHAR: 9734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "notrealchar "); break; 9744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER: 9754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "LETTER "); break; 9764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_UPPERCASE: 9774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "LETTER_UPPERCASE "); break; 9784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_LOWERCASE: 9794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "LETTER_LOWERCASE "); break; 9804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_TITLECASE: 9814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "LETTER_TITLECASE "); break; 9824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_MODIFIER: 9834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "LETTER_MODIFIER "); break; 9844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_OTHERS: 9854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "LETTER_OTHERS "); break; 9864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK: 9874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "MARK "); break; 9884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_NONSPACING: 9894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "MARK_NONSPACING "); break; 9904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_SPACECOMBINING: 9914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "MARK_SPACECOMBINING "); break; 9924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_ENCLOSING: 9934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "MARK_ENCLOSING "); break; 9944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER: 9954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NUMBER "); break; 9964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_DECIMAL: 9974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NUMBER_DECIMAL "); break; 9984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_LETTER: 9994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NUMBER_LETTER "); break; 10004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_OTHERS: 10014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NUMBER_OTHERS "); break; 10024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT: 10034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT "); break; 10044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_CONNECTOR: 10054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_CONNECTOR "); break; 10064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_DASH: 10074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_DASH "); break; 10084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_OPEN: 10094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_OPEN "); break; 10104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_CLOSE: 10114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_CLOSE "); break; 10124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_INITQUOTE: 10134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_INITQUOTE "); break; 10144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_FINQUOTE: 10154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_FINQUOTE "); break; 10164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_OTHERS: 10174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_OTHERS "); break; 10184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR: 10194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SEPAR "); break; 10204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_SPACE: 10214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SEPAR_SPACE "); break; 10224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_LINE: 10234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SEPAR_LINE "); break; 10244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_PARA: 10254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SEPAR_PARA "); break; 10264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL: 10274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SYMBOL "); break; 10284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_MATH: 10294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SYMBOL_MATH "); break; 10304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_CURRENCY: 10314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SYMBOL_CURRENCY "); break; 10324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_MODIFIER: 10334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SYMBOL_MODIFIER "); break; 10344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_OTHERS: 10354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SYMBOL_OTHERS "); break; 10364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER: 10374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "OTHER "); break; 10384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_CONTROL: 10394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "OTHER_CONTROL "); break; 10404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_FORMAT: 10414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "OTHER_FORMAT "); break; 10424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_PRIVATE: 10434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "OTHER_PRIVATE "); break; 10444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_NA: 10454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "OTHER_NA "); break; 10464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_BLOCK_NAME: 10474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "BLOCK "); break; 10484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 10494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 10504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 10514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 10524255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintQuantType(FILE *output, xmlRegQuantType type) { 10534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (type) { 10544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_EPSILON: 10554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "epsilon "); break; 10564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_ONCE: 10574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "once "); break; 10584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_OPT: 10594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "? "); break; 10604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_MULT: 10614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "* "); break; 10624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_PLUS: 10634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "+ "); break; 10644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_RANGE: 10654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "range "); break; 10667646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard case XML_REGEXP_QUANT_ONCEONLY: 10677646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard fprintf(output, "onceonly "); break; 10687646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard case XML_REGEXP_QUANT_ALL: 10697646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard fprintf(output, "all "); break; 10704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 10714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 10724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 10734255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintRange(FILE *output, xmlRegRangePtr range) { 10744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " range: "); 10754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (range->neg) 10764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "negative "); 10774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintAtomType(output, range->type); 10784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%c - %c\n", range->start, range->end); 10794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 10804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 10814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 10824255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintAtom(FILE *output, xmlRegAtomPtr atom) { 10834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " atom: "); 10844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom == NULL) { 10854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NULL\n"); 10864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 10874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 10889efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if (atom->neg) 10899efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard fprintf(output, "not "); 10904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintAtomType(output, atom->type); 10914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintQuantType(output, atom->quant); 10924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->quant == XML_REGEXP_QUANT_RANGE) 10934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d-%d ", atom->min, atom->max); 10944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->type == XML_REGEXP_STRING) 10954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "'%s' ", (char *) atom->valuep); 10964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->type == XML_REGEXP_CHARVAL) 10974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "char %c\n", atom->codepoint); 10984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else if (atom->type == XML_REGEXP_RANGES) { 10994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 11004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d entries\n", atom->nbRanges); 11014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0; i < atom->nbRanges;i++) 11024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintRange(output, atom->ranges[i]); 11034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (atom->type == XML_REGEXP_SUBREG) { 11044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "start %d end %d\n", atom->start->no, atom->stop->no); 11054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 11064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "\n"); 11074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 11094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 11104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 11114255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintTrans(FILE *output, xmlRegTransPtr trans) { 11124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " trans: "); 11134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans == NULL) { 11144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NULL\n"); 11154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 11164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->to < 0) { 11184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "removed\n"); 11194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 11204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 1121567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (trans->nd != 0) { 1122567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (trans->nd == 2) 1123567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard fprintf(output, "last not determinist, "); 1124567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else 1125567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard fprintf(output, "not determinist, "); 1126567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 11274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->counter >= 0) { 11284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "counted %d, ", trans->counter); 11294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11308a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard if (trans->count == REGEXP_ALL_COUNTER) { 11318a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard fprintf(output, "all transition, "); 11328a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard } else if (trans->count >= 0) { 11334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "count based %d, ", trans->count); 11344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->atom == NULL) { 11364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "epsilon to %d\n", trans->to); 11374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 11384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->atom->type == XML_REGEXP_CHARVAL) 11404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "char %c ", trans->atom->codepoint); 11414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "atom %d, to %d\n", trans->atom->no, trans->to); 11424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 11434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 11444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 11454255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintState(FILE *output, xmlRegStatePtr state) { 11464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 11474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 11484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " state: "); 11494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state == NULL) { 11504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NULL\n"); 11514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 11524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state->type == XML_REGEXP_START_STATE) 11544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "START "); 11554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state->type == XML_REGEXP_FINAL_STATE) 11564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "FINAL "); 11574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 11584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d, %d transitions:\n", state->no, state->nbTrans); 11594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < state->nbTrans; i++) { 11604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintTrans(output, &(state->trans[i])); 11614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 11634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 116423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 11654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 11664255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintCtxt(FILE *output, xmlRegParserCtxtPtr ctxt) { 11674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 11684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 11694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " ctxt: "); 11704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt == NULL) { 11714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NULL\n"); 11724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 11734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "'%s' ", ctxt->string); 11754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->error) 11764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "error "); 11774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->neg) 11784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "neg "); 11794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "\n"); 11804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d atoms:\n", ctxt->nbAtoms); 11814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < ctxt->nbAtoms; i++) { 11824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " %02d ", i); 11834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintAtom(output, ctxt->atoms[i]); 11844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom != NULL) { 11864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "current atom:\n"); 11874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintAtom(output, ctxt->atom); 11884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d states:", ctxt->nbStates); 11904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->start != NULL) 11914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " start: %d", ctxt->start->no); 11924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->end != NULL) 11934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " end: %d", ctxt->end->no); 11944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "\n"); 11954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < ctxt->nbStates; i++) { 11964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintState(output, ctxt->states[i]); 11974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d counters:\n", ctxt->nbCounters); 11994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < ctxt->nbCounters; i++) { 12004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " %d: min %d max %d\n", i, ctxt->counters[i].min, 12014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->counters[i].max); 12024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 120423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 12054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 12064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 12074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 12084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Finite Automata structures manipulations * 12094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 12104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 12114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 12124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 12134255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom, 12144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int neg, xmlRegAtomType type, int start, int end, 12154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *blockName) { 12164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegRangePtr range; 12174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 12184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom == NULL) { 12194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("add range: atom is NULL"); 12204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 12214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->type != XML_REGEXP_RANGES) { 12234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("add range: atom is not ranges"); 12244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 12254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->maxRanges == 0) { 12274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->maxRanges = 4; 12284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->ranges = (xmlRegRangePtr *) xmlMalloc(atom->maxRanges * 12294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegRangePtr)); 12304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->ranges == NULL) { 1231ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "adding ranges"); 12324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->maxRanges = 0; 12334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 12344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (atom->nbRanges >= atom->maxRanges) { 12364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegRangePtr *tmp; 12374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->maxRanges *= 2; 12384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegRangePtr *) xmlRealloc(atom->ranges, atom->maxRanges * 12394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegRangePtr)); 12404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 1241ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "adding ranges"); 12424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->maxRanges /= 2; 12434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 12444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->ranges = tmp; 12464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard range = xmlRegNewRange(ctxt, neg, type, start, end); 12484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (range == NULL) 12494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 12504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard range->blockName = blockName; 12514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->ranges[atom->nbRanges++] = range; 12524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 12534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 12544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 12554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 12564255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegGetCounter(xmlRegParserCtxtPtr ctxt) { 12574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->maxCounters == 0) { 12584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxCounters = 4; 12594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->counters = (xmlRegCounter *) xmlMalloc(ctxt->maxCounters * 12604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegCounter)); 12614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->counters == NULL) { 1262ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating counter"); 12634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxCounters = 0; 12644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 12654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->nbCounters >= ctxt->maxCounters) { 12674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegCounter *tmp; 12684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxCounters *= 2; 12694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegCounter *) xmlRealloc(ctxt->counters, ctxt->maxCounters * 12704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegCounter)); 12714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 1272ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating counter"); 12734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxCounters /= 2; 12744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 12754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->counters = tmp; 12774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->counters[ctxt->nbCounters].min = -1; 12794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->counters[ctxt->nbCounters].max = -1; 12804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ctxt->nbCounters++); 12814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 12824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1283a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillardstatic int 12844255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegAtomPush(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) { 12854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom == NULL) { 12864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("atom push: atom is NULL"); 1287a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 12884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->maxAtoms == 0) { 12904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxAtoms = 4; 12914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atoms = (xmlRegAtomPtr *) xmlMalloc(ctxt->maxAtoms * 12924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegAtomPtr)); 12934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atoms == NULL) { 1294ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "pushing atom"); 12954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxAtoms = 0; 1296a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 12974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->nbAtoms >= ctxt->maxAtoms) { 12994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr *tmp; 13004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxAtoms *= 2; 13014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegAtomPtr *) xmlRealloc(ctxt->atoms, ctxt->maxAtoms * 13024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegAtomPtr)); 13034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 1304ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating counter"); 13054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxAtoms /= 2; 1306a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 13074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 13084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atoms = tmp; 13094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 13104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->no = ctxt->nbAtoms; 13114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atoms[ctxt->nbAtoms++] = atom; 1312a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(0); 13134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 13144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 13154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 1316db68b74dc7ec531361a736de7769a3e8ce881f79Daniel VeillardxmlRegStateAddTransTo(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr target, 1317db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int from) { 1318db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (target->maxTransTo == 0) { 1319db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->maxTransTo = 8; 1320db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->transTo = (int *) xmlMalloc(target->maxTransTo * 1321db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard sizeof(int)); 1322db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (target->transTo == NULL) { 1323db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlRegexpErrMemory(ctxt, "adding transition"); 1324db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->maxTransTo = 0; 1325db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard return; 1326db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1327db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } else if (target->nbTransTo >= target->maxTransTo) { 1328db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int *tmp; 1329db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->maxTransTo *= 2; 1330db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard tmp = (int *) xmlRealloc(target->transTo, target->maxTransTo * 1331db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard sizeof(int)); 1332db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (tmp == NULL) { 1333db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlRegexpErrMemory(ctxt, "adding transition"); 1334db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->maxTransTo /= 2; 1335db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard return; 1336db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1337db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->transTo = tmp; 1338db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1339db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->transTo[target->nbTransTo] = from; 1340db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->nbTransTo++; 1341db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard} 1342db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard 1343db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillardstatic void 13444255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state, 13454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom, xmlRegStatePtr target, 13465de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard int counter, int count) { 1347f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack 1348f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack int nrtrans; 1349f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack 13504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state == NULL) { 13514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("add state: state is NULL"); 13524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 13534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 13544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (target == NULL) { 13554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("add state: target is NULL"); 13564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 13574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 1358f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack /* 1359f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack * Other routines follow the philosophy 'When in doubt, add a transition' 1360f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack * so we check here whether such a transition is already present and, if 1361f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack * so, silently ignore this request. 1362f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack */ 1363f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack 13645de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard for (nrtrans = state->nbTrans - 1; nrtrans >= 0; nrtrans--) { 13655de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegTransPtr trans = &(state->trans[nrtrans]); 13665de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard if ((trans->atom == atom) && 13675de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard (trans->to == target->no) && 13685de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard (trans->counter == counter) && 13695de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard (trans->count == count)) { 1370f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack#ifdef DEBUG_REGEXP_GRAPH 13715de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard printf("Ignoring duplicate transition from %d to %d\n", 13725de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard state->no, target->no); 1373f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack#endif 13745de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard return; 1375db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1376f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack } 1377f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack 13784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state->maxTrans == 0) { 1379db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard state->maxTrans = 8; 13804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans = (xmlRegTrans *) xmlMalloc(state->maxTrans * 13814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegTrans)); 13824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state->trans == NULL) { 1383ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "adding transition"); 13844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->maxTrans = 0; 13854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 13864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 13874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (state->nbTrans >= state->maxTrans) { 13884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegTrans *tmp; 13894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->maxTrans *= 2; 13904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegTrans *) xmlRealloc(state->trans, state->maxTrans * 13914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegTrans)); 13924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 1393ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "adding transition"); 13944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->maxTrans /= 2; 13954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 13964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 13974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans = tmp; 13984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 13994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 14004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Add trans from %d to %d ", state->no, target->no); 14018a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard if (count == REGEXP_ALL_COUNTER) 14022cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard printf("all transition\n"); 14034402ab420f68d9384bd6c2066c1676848d98d27cDaniel Veillard else if (count >= 0) 14042cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard printf("count based %d\n", count); 14054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else if (counter >= 0) 14062cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard printf("counted %d\n", counter); 14074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else if (atom == NULL) 14082cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard printf("epsilon transition\n"); 14092cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard else if (atom != NULL) 14102cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard xmlRegPrintAtom(stdout, atom); 14114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 14124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 14134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans[state->nbTrans].atom = atom; 14144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans[state->nbTrans].to = target->no; 14154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans[state->nbTrans].counter = counter; 14164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans[state->nbTrans].count = count; 1417567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard state->trans[state->nbTrans].nd = 0; 14184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->nbTrans++; 1419db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlRegStateAddTransTo(ctxt, target, state->no); 14204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 14214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1422a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillardstatic int 14234255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegStatePush(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state) { 1424a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (state == NULL) return(-1); 14254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->maxStates == 0) { 14264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxStates = 4; 14274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->states = (xmlRegStatePtr *) xmlMalloc(ctxt->maxStates * 14284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegStatePtr)); 14294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->states == NULL) { 1430ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "adding state"); 14314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxStates = 0; 1432a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 14334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 14344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->nbStates >= ctxt->maxStates) { 14354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr *tmp; 14364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxStates *= 2; 14374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegStatePtr *) xmlRealloc(ctxt->states, ctxt->maxStates * 14384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegStatePtr)); 14394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 1440ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "adding state"); 14414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxStates /= 2; 1442a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 14434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 14444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->states = tmp; 14454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 14464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->no = ctxt->nbStates; 14474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->states[ctxt->nbStates++] = state; 1448a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(0); 14494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 14504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 14514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 14527646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * xmlFAGenerateAllTransition: 1453441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 1454441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @from: the from state 1455441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @to: the target state or NULL for building a new one 1456441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @lax: 14577646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * 14587646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard */ 14597646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillardstatic void 14607646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlFAGenerateAllTransition(xmlRegParserCtxtPtr ctxt, 1461441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard xmlRegStatePtr from, xmlRegStatePtr to, 1462441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard int lax) { 14637646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if (to == NULL) { 14647646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard to = xmlRegNewState(ctxt); 14657646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard xmlRegStatePush(ctxt, to); 14667646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard ctxt->state = to; 14677646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard } 1468441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if (lax) 14695de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_LAX_COUNTER); 1470441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard else 14715de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_COUNTER); 14727646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard} 14737646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard 14747646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard/** 14754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAGenerateEpsilonTransition: 1476441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 1477441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @from: the from state 1478441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @to: the target state or NULL for building a new one 14794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 14804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 14814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 14824255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAGenerateEpsilonTransition(xmlRegParserCtxtPtr ctxt, 14834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr from, xmlRegStatePtr to) { 14844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) { 14854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to = xmlRegNewState(ctxt); 14864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePush(ctxt, to); 14874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->state = to; 14884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 14895de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, from, NULL, to, -1, -1); 14904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 14914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 14924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 14934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAGenerateCountedEpsilonTransition: 1494441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 1495441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @from: the from state 1496441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @to: the target state or NULL for building a new one 14974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * counter: the counter for that transition 14984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 14994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 15004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 15014255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAGenerateCountedEpsilonTransition(xmlRegParserCtxtPtr ctxt, 15024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr from, xmlRegStatePtr to, int counter) { 15034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) { 15044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to = xmlRegNewState(ctxt); 15054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePush(ctxt, to); 15064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->state = to; 15074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 15085de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, from, NULL, to, counter, -1); 15094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 15104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 15114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 15124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAGenerateCountedTransition: 1513441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 1514441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @from: the from state 1515441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @to: the target state or NULL for building a new one 15164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * counter: the counter for that transition 15174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 15184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 15194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 15204255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAGenerateCountedTransition(xmlRegParserCtxtPtr ctxt, 15214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr from, xmlRegStatePtr to, int counter) { 15224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) { 15234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to = xmlRegNewState(ctxt); 15244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePush(ctxt, to); 15254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->state = to; 15264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 15275de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, from, NULL, to, -1, counter); 15284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 15294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 15304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 15314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAGenerateTransitions: 1532441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 1533441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @from: the from state 1534441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @to: the target state or NULL for building a new one 1535441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @atom: the atom generating the transition 15364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 1537ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Returns 0 if success and -1 in case of error. 15384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 1539a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillardstatic int 15404255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, 15414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr to, xmlRegAtomPtr atom) { 154210bda629bf8fe279f02493f0921110c552be3171Daniel Veillard xmlRegStatePtr end; 154310bda629bf8fe279f02493f0921110c552be3171Daniel Veillard 15444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom == NULL) { 15454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("genrate transition: atom == NULL"); 1546a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 15474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 15484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->type == XML_REGEXP_SUBREG) { 15494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 15504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * this is a subexpression handling one should not need to 1551ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * create a new node except for XML_REGEXP_QUANT_RANGE. 15524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 1553a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (xmlRegAtomPush(ctxt, atom) < 0) { 1554a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 1555a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 15564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((to != NULL) && (atom->stop != to) && 15574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (atom->quant != XML_REGEXP_QUANT_RANGE)) { 15584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 15594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Generate an epsilon transition to link to the target 15604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 15614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to); 1562aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard#ifdef DV 1563aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard } else if ((to == NULL) && (atom->quant != XML_REGEXP_QUANT_RANGE) && 1564aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard (atom->quant != XML_REGEXP_QUANT_ONCE)) { 1565aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard to = xmlRegNewState(ctxt); 1566aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard xmlRegStatePush(ctxt, to); 1567aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard ctxt->state = to; 1568aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to); 1569aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard#endif 15704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 15714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (atom->quant) { 15724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_OPT: 15734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 157454eb0243c442292953b4a3df39568735039ebc82Daniel Veillard /* 157554eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * transition done to the state after end of atom. 157654eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * 1. set transition from atom start to new state 157754eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * 2. set transition from atom end to this state. 157854eb0243c442292953b4a3df39568735039ebc82Daniel Veillard */ 1579d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard if (to == NULL) { 1580d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->start, 0); 1581d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->stop, 1582d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard ctxt->state); 1583d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard } else { 1584d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->start, to); 1585d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard } 15864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 15874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_MULT: 15884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 15894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->start, atom->stop); 15904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start); 15914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 15924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_PLUS: 15934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 15944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start); 15954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 15964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_RANGE: { 15974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int counter; 159876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegStatePtr inter, newstate; 15994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 16004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 160176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * create the final state now if needed 16024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 160376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (to != NULL) { 160476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard newstate = to; 160576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } else { 1606ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack newstate = xmlRegNewState(ctxt); 1607ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack xmlRegStatePush(ctxt, newstate); 160876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 160976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 161076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* 161176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * The principle here is to use counted transition 161276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * to avoid explosion in the number of states in the 161376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * graph. This is clearly more complex but should not 161476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * be exploitable at runtime. 161576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard */ 161676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if ((atom->min == 0) && (atom->start0 == NULL)) { 161776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegAtomPtr copy; 161876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* 161976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * duplicate a transition based on atom to count next 162076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * occurences after 1. We cannot loop to atom->start 162176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * directly because we need an epsilon transition to 162276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * newstate. 162376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard */ 162476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* ???? For some reason it seems we never reach that 162576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard case, I suppose this got optimized out before when 162676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard building the automata */ 1627c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard copy = xmlRegCopyAtom(ctxt, atom); 162876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (copy == NULL) 162976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(-1); 163076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard copy->quant = XML_REGEXP_QUANT_ONCE; 163176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard copy->min = 0; 163276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard copy->max = 0; 163376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 163476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (xmlFAGenerateTransitions(ctxt, atom->start, NULL, copy) 163576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard < 0) 163676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(-1); 163776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard inter = ctxt->state; 163876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard counter = xmlRegGetCounter(ctxt); 163976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ctxt->counters[counter].min = atom->min - 1; 164076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ctxt->counters[counter].max = atom->max - 1; 164176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* count the number of times we see it again */ 164276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlFAGenerateCountedEpsilonTransition(ctxt, inter, 164376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard atom->stop, counter); 164476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* allow a way out based on the count */ 164576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlFAGenerateCountedTransition(ctxt, inter, 164676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard newstate, counter); 164776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* and also allow a direct exit for 0 */ 1648ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack xmlFAGenerateEpsilonTransition(ctxt, atom->start, 164976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard newstate); 165076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } else { 165176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* 165276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * either we need the atom at least once or there 165376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * is an atom->start0 allowing to easilly plug the 165476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * epsilon transition. 165576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard */ 165676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard counter = xmlRegGetCounter(ctxt); 165776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ctxt->counters[counter].min = atom->min - 1; 165876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ctxt->counters[counter].max = atom->max - 1; 165976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* count the number of times we see it again */ 166076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlFAGenerateCountedEpsilonTransition(ctxt, atom->stop, 166176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard atom->start, counter); 166276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* allow a way out based on the count */ 166376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlFAGenerateCountedTransition(ctxt, atom->stop, 166476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard newstate, counter); 166576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* and if needed allow a direct exit for 0 */ 166676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (atom->min == 0) 166776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->start0, 166876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard newstate); 166976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 1670ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack } 16714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->min = 0; 16724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->max = 0; 16734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 16749a00fd2991433a6ce04075c91b3ac6b976bdd806Daniel Veillard ctxt->state = newstate; 16754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 16764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard default: 16774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 16784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 1679a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(0); 1680567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 1681567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((atom->min == 0) && (atom->max == 0) && 168299c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard (atom->quant == XML_REGEXP_QUANT_RANGE)) { 168399c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard /* 168499c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard * we can discard the atom and generate an epsilon transition instead 168599c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard */ 168699c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard if (to == NULL) { 168799c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard to = xmlRegNewState(ctxt); 168899c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard if (to != NULL) 168999c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard xmlRegStatePush(ctxt, to); 169099c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard else { 169199c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard return(-1); 169299c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard } 169399c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard } 169499c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, from, to); 169599c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard ctxt->state = to; 169699c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard xmlRegFreeAtom(atom); 169799c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard return(0); 1698567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 1699567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (to == NULL) { 1700567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard to = xmlRegNewState(ctxt); 1701567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (to != NULL) 1702567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegStatePush(ctxt, to); 1703567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else { 1704a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 17054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 170610bda629bf8fe279f02493f0921110c552be3171Daniel Veillard } 170710bda629bf8fe279f02493f0921110c552be3171Daniel Veillard end = to; 170810bda629bf8fe279f02493f0921110c552be3171Daniel Veillard if ((atom->quant == XML_REGEXP_QUANT_MULT) || 170910bda629bf8fe279f02493f0921110c552be3171Daniel Veillard (atom->quant == XML_REGEXP_QUANT_PLUS)) { 171010bda629bf8fe279f02493f0921110c552be3171Daniel Veillard /* 171110bda629bf8fe279f02493f0921110c552be3171Daniel Veillard * Do not pollute the target state by adding transitions from 171210bda629bf8fe279f02493f0921110c552be3171Daniel Veillard * it as it is likely to be the shared target of multiple branches. 171310bda629bf8fe279f02493f0921110c552be3171Daniel Veillard * So isolate with an epsilon transition. 171410bda629bf8fe279f02493f0921110c552be3171Daniel Veillard */ 171510bda629bf8fe279f02493f0921110c552be3171Daniel Veillard xmlRegStatePtr tmp; 171610bda629bf8fe279f02493f0921110c552be3171Daniel Veillard 171710bda629bf8fe279f02493f0921110c552be3171Daniel Veillard tmp = xmlRegNewState(ctxt); 171810bda629bf8fe279f02493f0921110c552be3171Daniel Veillard if (tmp != NULL) 171910bda629bf8fe279f02493f0921110c552be3171Daniel Veillard xmlRegStatePush(ctxt, tmp); 172010bda629bf8fe279f02493f0921110c552be3171Daniel Veillard else { 172110bda629bf8fe279f02493f0921110c552be3171Daniel Veillard return(-1); 172210bda629bf8fe279f02493f0921110c552be3171Daniel Veillard } 172310bda629bf8fe279f02493f0921110c552be3171Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, tmp, to); 172410bda629bf8fe279f02493f0921110c552be3171Daniel Veillard to = tmp; 17254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 1726567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (xmlRegAtomPush(ctxt, atom) < 0) { 1727567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(-1); 1728567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 1729567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegStateAddTrans(ctxt, from, atom, to, -1, -1); 173010bda629bf8fe279f02493f0921110c552be3171Daniel Veillard ctxt->state = end; 17314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (atom->quant) { 17324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_OPT: 17334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 17344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, from, to); 17354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 17364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_MULT: 17374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 17384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, from, to); 17395de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1); 17404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 17414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_PLUS: 17424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 17435de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1); 17444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 17455657837103e9938b42135cb993f197d1235221e0William M. Brack case XML_REGEXP_QUANT_RANGE: 1746c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard#if DV_test 17475657837103e9938b42135cb993f197d1235221e0William M. Brack if (atom->min == 0) { 17485657837103e9938b42135cb993f197d1235221e0William M. Brack xmlFAGenerateEpsilonTransition(ctxt, from, to); 17495657837103e9938b42135cb993f197d1235221e0William M. Brack } 1750c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard#endif 17515657837103e9938b42135cb993f197d1235221e0William M. Brack break; 17524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard default: 17534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 17544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 1755a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(0); 17564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 17574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 17584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 17594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAReduceEpsilonTransitions: 1760441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 17614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @fromnr: the from state 17624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @tonr: the to state 1763ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * @counter: should that transition be associated to a counted 17644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 17654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 17664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 17674255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int fromnr, 17684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int tonr, int counter) { 17694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int transnr; 17704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr from; 17714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr to; 17724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 17734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 17744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("xmlFAReduceEpsilonTransitions(%d, %d)\n", fromnr, tonr); 17754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 17764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard from = ctxt->states[fromnr]; 17774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (from == NULL) 17784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 17794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to = ctxt->states[tonr]; 17804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) 17814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 17824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((to->mark == XML_REGEXP_MARK_START) || 17834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (to->mark == XML_REGEXP_MARK_VISITED)) 17844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 17854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 17864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to->mark = XML_REGEXP_MARK_VISITED; 17874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to->type == XML_REGEXP_FINAL_STATE) { 17884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 17894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("State %d is final, so %d becomes final\n", tonr, fromnr); 17904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 17914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard from->type = XML_REGEXP_FINAL_STATE; 17924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 17934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (transnr = 0;transnr < to->nbTrans;transnr++) { 1794db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (to->trans[transnr].to < 0) 1795db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard continue; 17964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to->trans[transnr].atom == NULL) { 17974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 17984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Don't remove counted transitions 17994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Don't loop either 18004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 1801b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (to->trans[transnr].to != fromnr) { 1802b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (to->trans[transnr].count >= 0) { 1803b509f1543df71549969eeac076349e05d2f78044Daniel Veillard int newto = to->trans[transnr].to; 1804b509f1543df71549969eeac076349e05d2f78044Daniel Veillard 1805b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlRegStateAddTrans(ctxt, from, NULL, 1806b509f1543df71549969eeac076349e05d2f78044Daniel Veillard ctxt->states[newto], 18075de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard -1, to->trans[transnr].count); 1808b509f1543df71549969eeac076349e05d2f78044Daniel Veillard } else { 18094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 1810b509f1543df71549969eeac076349e05d2f78044Daniel Veillard printf("Found epsilon trans %d from %d to %d\n", 1811b509f1543df71549969eeac076349e05d2f78044Daniel Veillard transnr, tonr, to->trans[transnr].to); 18124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 1813b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (to->trans[transnr].counter >= 0) { 1814b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlFAReduceEpsilonTransitions(ctxt, fromnr, 1815b509f1543df71549969eeac076349e05d2f78044Daniel Veillard to->trans[transnr].to, 1816b509f1543df71549969eeac076349e05d2f78044Daniel Veillard to->trans[transnr].counter); 1817b509f1543df71549969eeac076349e05d2f78044Daniel Veillard } else { 1818b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlFAReduceEpsilonTransitions(ctxt, fromnr, 1819b509f1543df71549969eeac076349e05d2f78044Daniel Veillard to->trans[transnr].to, 1820b509f1543df71549969eeac076349e05d2f78044Daniel Veillard counter); 1821b509f1543df71549969eeac076349e05d2f78044Daniel Veillard } 1822b509f1543df71549969eeac076349e05d2f78044Daniel Veillard } 18234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 18244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 18254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int newto = to->trans[transnr].to; 18264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1827b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (to->trans[transnr].counter >= 0) { 1828b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom, 1829b509f1543df71549969eeac076349e05d2f78044Daniel Veillard ctxt->states[newto], 18305de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard to->trans[transnr].counter, -1); 1831b509f1543df71549969eeac076349e05d2f78044Daniel Veillard } else { 1832b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom, 18335de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard ctxt->states[newto], counter, -1); 1834b509f1543df71549969eeac076349e05d2f78044Daniel Veillard } 18354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 18364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 18374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to->mark = XML_REGEXP_MARK_NORMAL; 18384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 18394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 18404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 1841db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * xmlFAEliminateSimpleEpsilonTransitions: 1842db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * @ctxt: a regexp parser context 1843db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * 1844db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * Eliminating general epsilon transitions can get costly in the general 1845db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * algorithm due to the large amount of generated new transitions and 1846db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * associated comparisons. However for simple epsilon transition used just 1847db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * to separate building blocks when generating the automata this can be 1848db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * reduced to state elimination: 1849db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * - if there exists an epsilon from X to Y 1850db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * - if there is no other transition from X 1851db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * then X and Y are semantically equivalent and X can be eliminated 1852db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * If X is the start state then make Y the start state, else replace the 1853db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * target of all transitions to X by transitions to Y. 1854db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard */ 1855db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillardstatic void 1856db68b74dc7ec531361a736de7769a3e8ce881f79Daniel VeillardxmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) { 1857db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int statenr, i, j, newto; 1858db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlRegStatePtr state, tmp; 1859db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard 1860db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 1861db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard state = ctxt->states[statenr]; 1862db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (state == NULL) 1863db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard continue; 1864db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (state->nbTrans != 1) 1865db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard continue; 18660e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard if (state->type == XML_REGEXP_UNREACH_STATE) 18670e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard continue; 1868db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard /* is the only transition out a basic transition */ 1869db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if ((state->trans[0].atom == NULL) && 1870db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard (state->trans[0].to >= 0) && 1871db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard (state->trans[0].to != statenr) && 1872db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard (state->trans[0].counter < 0) && 1873db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard (state->trans[0].count < 0)) { 1874db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard newto = state->trans[0].to; 1875db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard 1876db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (state->type == XML_REGEXP_START_STATE) { 1877db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 1878db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard printf("Found simple epsilon trans from start %d to %d\n", 1879db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard statenr, newto); 1880db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard#endif 1881db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } else { 1882db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 1883db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard printf("Found simple epsilon trans from %d to %d\n", 1884db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard statenr, newto); 1885db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard#endif 1886db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard for (i = 0;i < state->nbTransTo;i++) { 1887db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard tmp = ctxt->states[state->transTo[i]]; 1888db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard for (j = 0;j < tmp->nbTrans;j++) { 1889db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (tmp->trans[j].to == statenr) { 1890db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 1891db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard printf("Changed transition %d on %d to go to %d\n", 1892db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard j, tmp->no, newto); 1893db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard#endif 18940e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard tmp->trans[j].to = -1; 18950e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard xmlRegStateAddTrans(ctxt, tmp, tmp->trans[j].atom, 18960e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard ctxt->states[newto], 18970e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard tmp->trans[j].counter, 18980e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard tmp->trans[j].count); 1899db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1900db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1901db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1902db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (state->type == XML_REGEXP_FINAL_STATE) 1903db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard ctxt->states[newto]->type = XML_REGEXP_FINAL_STATE; 1904db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard /* eliminate the transition completely */ 1905db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard state->nbTrans = 0; 1906db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard 19070e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard state->type = XML_REGEXP_UNREACH_STATE; 1908db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard 1909db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1910db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard 1911db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1912db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1913db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard} 1914db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard/** 19154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAEliminateEpsilonTransitions: 1916441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 19174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 19184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 19194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 19204255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAEliminateEpsilonTransitions(xmlRegParserCtxtPtr ctxt) { 19214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int statenr, transnr; 19224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state; 1923db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int has_epsilon; 19244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1925a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (ctxt->states == NULL) return; 1926a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard 19270e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard /* 19280e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard * Eliminate simple epsilon transition and the associated unreachable 19290e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard * states. 19300e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard */ 1931db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlFAEliminateSimpleEpsilonTransitions(ctxt); 19320e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 19330e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard state = ctxt->states[statenr]; 19340e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard if ((state != NULL) && (state->type == XML_REGEXP_UNREACH_STATE)) { 19350e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard#ifdef DEBUG_REGEXP_GRAPH 19360e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard printf("Removed unreachable state %d\n", statenr); 19370e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard#endif 19380e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard xmlRegFreeState(state); 19390e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard ctxt->states[statenr] = NULL; 19400e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard } 19410e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard } 1942db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard 1943db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard has_epsilon = 0; 1944a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard 19454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 1946fcd18ff8f753dd7308b619476266f1a2ddcc8859Daniel Veillard * Build the completed transitions bypassing the epsilons 19474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Use a marking algorithm to avoid loops 1948fcd18ff8f753dd7308b619476266f1a2ddcc8859Daniel Veillard * Mark sink states too. 1949fcd18ff8f753dd7308b619476266f1a2ddcc8859Daniel Veillard * Process from the latests states backward to the start when 1950fcd18ff8f753dd7308b619476266f1a2ddcc8859Daniel Veillard * there is long cascading epsilon chains this minimize the 1951fcd18ff8f753dd7308b619476266f1a2ddcc8859Daniel Veillard * recursions and transition compares when adding the new ones 19524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 1953fcd18ff8f753dd7308b619476266f1a2ddcc8859Daniel Veillard for (statenr = ctxt->nbStates - 1;statenr >= 0;statenr--) { 19544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state = ctxt->states[statenr]; 19554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state == NULL) 19564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 1957cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((state->nbTrans == 0) && 1958cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (state->type != XML_REGEXP_FINAL_STATE)) { 1959cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard state->type = XML_REGEXP_SINK_STATE; 1960cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 19614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (transnr = 0;transnr < state->nbTrans;transnr++) { 19624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((state->trans[transnr].atom == NULL) && 19634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (state->trans[transnr].to >= 0)) { 19644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state->trans[transnr].to == statenr) { 19654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans[transnr].to = -1; 19664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 19674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Removed loopback epsilon trans %d on %d\n", 19684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard transnr, statenr); 19694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 19704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (state->trans[transnr].count < 0) { 19714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int newto = state->trans[transnr].to; 19724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 19734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 19744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Found epsilon trans %d from %d to %d\n", 19754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard transnr, statenr, newto); 19764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 1977db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard has_epsilon = 1; 19780e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard state->trans[transnr].to = -2; 19790e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard state->mark = XML_REGEXP_MARK_START; 19804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAReduceEpsilonTransitions(ctxt, statenr, 19814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard newto, state->trans[transnr].counter); 19824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->mark = XML_REGEXP_MARK_NORMAL; 19834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 19844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 19854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Found counted transition %d on %d\n", 19864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard transnr, statenr); 19874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 19884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 19894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 19904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 19914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 19924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 19934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Eliminate the epsilon transitions 19944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 1995db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (has_epsilon) { 1996db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 1997db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard state = ctxt->states[statenr]; 1998db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (state == NULL) 1999db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard continue; 2000db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard for (transnr = 0;transnr < state->nbTrans;transnr++) { 2001db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlRegTransPtr trans = &(state->trans[transnr]); 2002db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if ((trans->atom == NULL) && 2003db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard (trans->count < 0) && 2004db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard (trans->to >= 0)) { 2005db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard trans->to = -1; 2006db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 20074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 20084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 20094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 201023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 201123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 201223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Use this pass to detect unreachable states too 201323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 201423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 201523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard state = ctxt->states[statenr]; 201623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (state != NULL) 2017779af00750fa86045e94422287d67a2cf5723f65William M. Brack state->reached = XML_REGEXP_MARK_NORMAL; 201823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 201923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard state = ctxt->states[0]; 202023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (state != NULL) 2021779af00750fa86045e94422287d67a2cf5723f65William M. Brack state->reached = XML_REGEXP_MARK_START; 202223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard while (state != NULL) { 202323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegStatePtr target = NULL; 2024779af00750fa86045e94422287d67a2cf5723f65William M. Brack state->reached = XML_REGEXP_MARK_VISITED; 202523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 2026ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Mark all states reachable from the current reachable state 202723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 202823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (transnr = 0;transnr < state->nbTrans;transnr++) { 202923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if ((state->trans[transnr].to >= 0) && 203023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ((state->trans[transnr].atom != NULL) || 203123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard (state->trans[transnr].count >= 0))) { 203223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int newto = state->trans[transnr].to; 203323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 203423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (ctxt->states[newto] == NULL) 203523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard continue; 2036779af00750fa86045e94422287d67a2cf5723f65William M. Brack if (ctxt->states[newto]->reached == XML_REGEXP_MARK_NORMAL) { 2037779af00750fa86045e94422287d67a2cf5723f65William M. Brack ctxt->states[newto]->reached = XML_REGEXP_MARK_START; 203823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard target = ctxt->states[newto]; 203923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 204023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 204123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 2042cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard 204323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 204423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * find the next accessible state not explored 204523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 204623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (target == NULL) { 204723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (statenr = 1;statenr < ctxt->nbStates;statenr++) { 204823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard state = ctxt->states[statenr]; 2049779af00750fa86045e94422287d67a2cf5723f65William M. Brack if ((state != NULL) && (state->reached == 2050779af00750fa86045e94422287d67a2cf5723f65William M. Brack XML_REGEXP_MARK_START)) { 205123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard target = state; 205223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard break; 205323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 205423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 205523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 205623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard state = target; 205723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 205823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 205923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard state = ctxt->states[statenr]; 2060779af00750fa86045e94422287d67a2cf5723f65William M. Brack if ((state != NULL) && (state->reached == XML_REGEXP_MARK_NORMAL)) { 206123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 206223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("Removed unreachable state %d\n", statenr); 206323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 206423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegFreeState(state); 206523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ctxt->states[statenr] = NULL; 206623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 206723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 206823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 20694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 20704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2071567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillardstatic int 2072567a45b5e931388acf850d56f937f1f66ff0f860Daniel VeillardxmlFACompareRanges(xmlRegRangePtr range1, xmlRegRangePtr range2) { 2073567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int ret = 0; 2074567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2075567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range1->type == XML_REGEXP_RANGES) || 2076567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_RANGES) || 2077567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_SUBREG) || 2078567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range1->type == XML_REGEXP_SUBREG) || 2079567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range1->type == XML_REGEXP_STRING) || 2080567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_STRING)) 2081567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(-1); 2082567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2083567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* put them in order */ 2084567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (range1->type > range2->type) { 2085567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegRangePtr tmp; 2086567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2087567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard tmp = range1; 2088567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard range1 = range2; 2089567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard range2 = tmp; 2090567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2091567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range1->type == XML_REGEXP_ANYCHAR) || 2092567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_ANYCHAR)) { 2093567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2094567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else if ((range1->type == XML_REGEXP_EPSILON) || 2095567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_EPSILON)) { 2096567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(0); 2097567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else if (range1->type == range2->type) { 20989332b48f16123cac16a207425b3a0206e5da35c1Daniel Veillard if (range1->type != XML_REGEXP_CHARVAL) 20999332b48f16123cac16a207425b3a0206e5da35c1Daniel Veillard ret = 1; 21009332b48f16123cac16a207425b3a0206e5da35c1Daniel Veillard else if ((range1->end < range2->start) || 21019332b48f16123cac16a207425b3a0206e5da35c1Daniel Veillard (range2->end < range1->start)) 2102567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 21039332b48f16123cac16a207425b3a0206e5da35c1Daniel Veillard else 21049332b48f16123cac16a207425b3a0206e5da35c1Daniel Veillard ret = 1; 2105567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else if (range1->type == XML_REGEXP_CHARVAL) { 2106567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int codepoint; 2107567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int neg = 0; 2108567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2109567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* 2110567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * just check all codepoints in the range for acceptance, 2111567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * this is usually way cheaper since done only once at 2112567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * compilation than testing over and over at runtime or 2113567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * pushing too many states when evaluating. 2114567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard */ 2115567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (((range1->neg == 0) && (range2->neg != 0)) || 2116567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ((range1->neg != 0) && (range2->neg == 0))) 2117567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard neg = 1; 2118567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2119567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard for (codepoint = range1->start;codepoint <= range1->end ;codepoint++) { 2120567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = xmlRegCheckCharacterRange(range2->type, codepoint, 2121567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 0, range2->start, range2->end, 2122567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard range2->blockName); 2123567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (ret < 0) 2124567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(-1); 2125567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (((neg == 1) && (ret == 0)) || 2126567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ((neg == 0) && (ret == 1))) 2127567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(1); 2128567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2129567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(0); 2130567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else if ((range1->type == XML_REGEXP_BLOCK_NAME) || 2131567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_BLOCK_NAME)) { 2132567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (range1->type == range2->type) { 2133567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = xmlStrEqual(range1->blockName, range2->blockName); 2134567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else { 2135567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* 2136567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * comparing a block range with anything else is way 2137567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * too costly, and maintining the table is like too much 2138567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * memory too, so let's force the automata to save state 2139567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * here. 2140567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard */ 2141567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(1); 2142567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2143567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else if ((range1->type < XML_REGEXP_LETTER) || 2144567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type < XML_REGEXP_LETTER)) { 2145567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range1->type == XML_REGEXP_ANYSPACE) && 2146567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NOTSPACE)) 2147567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2148567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else if ((range1->type == XML_REGEXP_INITNAME) && 2149567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NOTINITNAME)) 2150567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2151567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else if ((range1->type == XML_REGEXP_NAMECHAR) && 2152567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NOTNAMECHAR)) 2153567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2154567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else if ((range1->type == XML_REGEXP_DECIMAL) && 2155567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NOTDECIMAL)) 2156567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2157567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else if ((range1->type == XML_REGEXP_REALCHAR) && 2158567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NOTREALCHAR)) 2159567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2160567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else { 2161567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* same thing to limit complexity */ 2162567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(1); 2163567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2164567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else { 2165567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2166567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* range1->type < range2->type here */ 2167567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard switch (range1->type) { 2168567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_LETTER: 2169567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* all disjoint except in the subgroups */ 2170567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_LETTER_UPPERCASE) || 2171567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_LETTER_LOWERCASE) || 2172567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_LETTER_TITLECASE) || 2173567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_LETTER_MODIFIER) || 2174567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_LETTER_OTHERS)) 2175567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2176567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2177567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_MARK: 2178567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_MARK_NONSPACING) || 2179567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_MARK_SPACECOMBINING) || 2180567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_MARK_ENCLOSING)) 2181567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2182567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2183567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_NUMBER: 2184567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_NUMBER_DECIMAL) || 2185567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NUMBER_LETTER) || 2186567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NUMBER_OTHERS)) 2187567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2188567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2189567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_PUNCT: 2190567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_PUNCT_CONNECTOR) || 2191567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_PUNCT_DASH) || 2192567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_PUNCT_OPEN) || 2193567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_PUNCT_CLOSE) || 2194567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_PUNCT_INITQUOTE) || 2195567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_PUNCT_FINQUOTE) || 2196567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_PUNCT_OTHERS)) 2197567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2198567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2199567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_SEPAR: 2200567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_SEPAR_SPACE) || 2201567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_SEPAR_LINE) || 2202567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_SEPAR_PARA)) 2203567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2204567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2205567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_SYMBOL: 2206567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_SYMBOL_MATH) || 2207567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_SYMBOL_CURRENCY) || 2208567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_SYMBOL_MODIFIER) || 2209567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_SYMBOL_OTHERS)) 2210567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2211567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2212567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_OTHER: 2213567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_OTHER_CONTROL) || 2214567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_OTHER_FORMAT) || 2215567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_OTHER_PRIVATE)) 2216567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2217567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2218567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard default: 2219567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type >= XML_REGEXP_LETTER) && 2220567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type < XML_REGEXP_BLOCK_NAME)) 2221567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2222567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else { 2223567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* safety net ! */ 2224567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(1); 2225567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2226567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2227567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2228567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (((range1->neg == 0) && (range2->neg != 0)) || 2229567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ((range1->neg != 0) && (range2->neg == 0))) 2230567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = !ret; 2231594e5dfb48ee6fbac1b64155839063648022fc57Daniel Veillard return(ret); 2232567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard} 2233567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2234e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard/** 2235fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * xmlFACompareAtomTypes: 2236fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * @type1: an atom type 2237fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * @type2: an atom type 2238fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * 2239fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * Compares two atoms type to check whether they intersect in some ways, 2240fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * this is used by xmlFACompareAtoms only 2241fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * 2242fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * Returns 1 if they may intersect and 0 otherwise 2243fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard */ 2244fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillardstatic int 2245fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel VeillardxmlFACompareAtomTypes(xmlRegAtomType type1, xmlRegAtomType type2) { 2246fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type1 == XML_REGEXP_EPSILON) || 2247fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type1 == XML_REGEXP_CHARVAL) || 2248fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type1 == XML_REGEXP_RANGES) || 2249fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type1 == XML_REGEXP_SUBREG) || 2250fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type1 == XML_REGEXP_STRING) || 2251fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type1 == XML_REGEXP_ANYCHAR)) 2252fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2253fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type2 == XML_REGEXP_EPSILON) || 2254fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 == XML_REGEXP_CHARVAL) || 2255fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 == XML_REGEXP_RANGES) || 2256fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 == XML_REGEXP_SUBREG) || 2257fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 == XML_REGEXP_STRING) || 2258fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 == XML_REGEXP_ANYCHAR)) 2259fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2260fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2261fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type1 == type2) return(1); 2262fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2263fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* simplify subsequent compares by making sure type1 < type2 */ 2264fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type1 > type2) { 2265fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard xmlRegAtomType tmp = type1; 2266fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard type1 = type2; 2267fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard type2 = tmp; 2268fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard } 2269fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard switch (type1) { 2270fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_ANYSPACE: /* \s */ 2271fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* can't be a letter, number, mark, pontuation, symbol */ 2272fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type2 == XML_REGEXP_NOTSPACE) || 2273fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_LETTER) && 2274fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_LETTER_OTHERS)) || 2275fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_NUMBER) && 2276fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_NUMBER_OTHERS)) || 2277fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_MARK) && 2278fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 2279fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_PUNCT) && 2280fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 2281fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SYMBOL) && 2282fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SYMBOL_OTHERS)) 2283fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ) return(0); 2284fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2285fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NOTSPACE: /* \S */ 2286fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2287fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_INITNAME: /* \l */ 2288fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* can't be a number, mark, separator, pontuation, symbol or other */ 2289fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type2 == XML_REGEXP_NOTINITNAME) || 2290fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_NUMBER) && 2291fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_NUMBER_OTHERS)) || 2292fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_MARK) && 2293fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 2294fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SEPAR) && 2295fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SEPAR_PARA)) || 2296fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_PUNCT) && 2297fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 2298fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SYMBOL) && 2299fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SYMBOL_OTHERS)) || 2300fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_OTHER) && 2301fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_OTHER_NA)) 2302fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ) return(0); 2303fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2304fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NOTINITNAME: /* \L */ 2305fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2306fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NAMECHAR: /* \c */ 2307fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* can't be a mark, separator, pontuation, symbol or other */ 2308fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type2 == XML_REGEXP_NOTNAMECHAR) || 2309fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_MARK) && 2310fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 2311fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_PUNCT) && 2312fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 2313fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SEPAR) && 2314fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SEPAR_PARA)) || 2315fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SYMBOL) && 2316fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SYMBOL_OTHERS)) || 2317fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_OTHER) && 2318fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_OTHER_NA)) 2319fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ) return(0); 2320fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2321fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NOTNAMECHAR: /* \C */ 2322fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2323fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_DECIMAL: /* \d */ 2324fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* can't be a letter, mark, separator, pontuation, symbol or other */ 2325fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type2 == XML_REGEXP_NOTDECIMAL) || 2326fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 == XML_REGEXP_REALCHAR) || 2327fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_LETTER) && 2328fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_LETTER_OTHERS)) || 2329fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_MARK) && 2330fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 2331fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_PUNCT) && 2332fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 2333fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SEPAR) && 2334fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SEPAR_PARA)) || 2335fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SYMBOL) && 2336fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SYMBOL_OTHERS)) || 2337fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_OTHER) && 2338fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_OTHER_NA)) 2339fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard )return(0); 2340fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2341fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NOTDECIMAL: /* \D */ 2342fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2343fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_REALCHAR: /* \w */ 2344fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* can't be a mark, separator, pontuation, symbol or other */ 2345fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type2 == XML_REGEXP_NOTDECIMAL) || 2346fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_MARK) && 2347fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 2348fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_PUNCT) && 2349fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 2350fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SEPAR) && 2351fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SEPAR_PARA)) || 2352fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SYMBOL) && 2353fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SYMBOL_OTHERS)) || 2354fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_OTHER) && 2355fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_OTHER_NA)) 2356fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard )return(0); 2357fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2358fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NOTREALCHAR: /* \W */ 2359fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2360fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* 2361fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * at that point we know both type 1 and type2 are from 2362fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * character categories are ordered and are different, 2363fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * it becomes simple because this is a partition 2364fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard */ 2365fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_LETTER: 2366fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_LETTER_OTHERS) 2367fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2368fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2369fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_LETTER_UPPERCASE: 2370fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_LETTER_LOWERCASE: 2371fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_LETTER_TITLECASE: 2372fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_LETTER_MODIFIER: 2373fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_LETTER_OTHERS: 2374fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2375fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_MARK: 2376fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_MARK_ENCLOSING) 2377fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2378fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2379fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_MARK_NONSPACING: 2380fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_MARK_SPACECOMBINING: 2381fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_MARK_ENCLOSING: 2382fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2383fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NUMBER: 2384fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_NUMBER_OTHERS) 2385fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2386fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2387fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NUMBER_DECIMAL: 2388fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NUMBER_LETTER: 2389fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NUMBER_OTHERS: 2390fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2391fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT: 2392fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_PUNCT_OTHERS) 2393fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2394fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2395fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_CONNECTOR: 2396fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_DASH: 2397fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_OPEN: 2398fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_CLOSE: 2399fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_INITQUOTE: 2400fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_FINQUOTE: 2401fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_OTHERS: 2402fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2403fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SEPAR: 2404fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_SEPAR_PARA) 2405fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2406fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2407fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SEPAR_SPACE: 2408fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SEPAR_LINE: 2409fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SEPAR_PARA: 2410fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2411fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SYMBOL: 2412fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_SYMBOL_OTHERS) 2413fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2414fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2415fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SYMBOL_MATH: 2416fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SYMBOL_CURRENCY: 2417fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SYMBOL_MODIFIER: 2418fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SYMBOL_OTHERS: 2419fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2420fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_OTHER: 2421fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_OTHER_NA) 2422fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2423fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2424fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_OTHER_CONTROL: 2425fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_OTHER_FORMAT: 2426fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_OTHER_PRIVATE: 2427fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_OTHER_NA: 2428fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2429fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard default: 2430fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2431fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard } 2432fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2433fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard} 2434fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2435fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard/** 2436fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * xmlFAEqualAtoms: 2437fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * @atom1: an atom 2438fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * @atom2: an atom 24391ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * @deep: if not set only compare string pointers 2440fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * 2441fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * Compares two atoms to check whether they are the same exactly 2442fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * this is used to remove equivalent transitions 2443fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * 2444fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * Returns 1 if same and 0 otherwise 2445fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard */ 2446fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillardstatic int 24471ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel VeillardxmlFAEqualAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) { 2448fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard int ret = 0; 2449fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2450fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (atom1 == atom2) 2451fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2452fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((atom1 == NULL) || (atom2 == NULL)) 2453fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2454fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2455fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (atom1->type != atom2->type) 2456fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2457fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard switch (atom1->type) { 2458fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_EPSILON: 2459fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = 0; 2460fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2461fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_STRING: 24621ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (!deep) 24631ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard ret = (atom1->valuep == atom2->valuep); 24641ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard else 24651ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard ret = xmlStrEqual((xmlChar *)atom1->valuep, 24661ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard (xmlChar *)atom2->valuep); 2467fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2468fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_CHARVAL: 2469fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = (atom1->codepoint == atom2->codepoint); 2470fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2471fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_RANGES: 2472fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* too hard to do in the general case */ 2473fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = 0; 2474fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard default: 2475fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2476fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard } 2477fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(ret); 2478fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard} 2479fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2480fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard/** 2481e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * xmlFACompareAtoms: 2482e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * @atom1: an atom 2483e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * @atom2: an atom 24841ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * @deep: if not set only compare string pointers 2485e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 2486567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * Compares two atoms to check whether they intersect in some ways, 2487fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * this is used by xmlFAComputesDeterminism and xmlFARecurseDeterminism only 2488e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 2489e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * Returns 1 if yes and 0 otherwise 2490e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2491e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillardstatic int 24921ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel VeillardxmlFACompareAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) { 2493fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard int ret = 1; 24949efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 2495e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (atom1 == atom2) 2496e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(1); 2497e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if ((atom1 == NULL) || (atom2 == NULL)) 2498e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(0); 2499e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 2500fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((atom1->type == XML_REGEXP_ANYCHAR) || 2501fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (atom2->type == XML_REGEXP_ANYCHAR)) 2502fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2503fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2504fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (atom1->type > atom2->type) { 2505567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegAtomPtr tmp; 2506567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard tmp = atom1; 2507567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard atom1 = atom2; 2508567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard atom2 = tmp; 2509fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard } 2510fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (atom1->type != atom2->type) { 2511fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = xmlFACompareAtomTypes(atom1->type, atom2->type); 2512fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* if they can't intersect at the type level break now */ 2513fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (ret == 0) 2514fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2515567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2516e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard switch (atom1->type) { 2517e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard case XML_REGEXP_STRING: 25181ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (!deep) 25191ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard ret = (atom1->valuep != atom2->valuep); 25201ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard else 25211ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard ret = xmlRegStrEqualWildcard((xmlChar *)atom1->valuep, 25221ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard (xmlChar *)atom2->valuep); 25239efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard break; 2524e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard case XML_REGEXP_EPSILON: 2525567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard goto not_determinist; 2526e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard case XML_REGEXP_CHARVAL: 2527567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (atom2->type == XML_REGEXP_CHARVAL) { 2528fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = (atom1->codepoint == atom2->codepoint); 2529567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else { 2530fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = xmlRegCheckCharacter(atom2, atom1->codepoint); 2531fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (ret < 0) 2532fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = 1; 2533fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard } 2534fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2535fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_RANGES: 2536fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (atom2->type == XML_REGEXP_RANGES) { 2537567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int i, j, res; 2538567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegRangePtr r1, r2; 2539567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2540567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* 2541567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * need to check that none of the ranges eventually matches 2542567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard */ 2543567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard for (i = 0;i < atom1->nbRanges;i++) { 2544567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard for (j = 0;j < atom2->nbRanges;j++) { 2545567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard r1 = atom1->ranges[i]; 2546567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard r2 = atom2->ranges[j]; 2547567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard res = xmlFACompareRanges(r1, r2); 2548567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (res == 1) { 2549567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2550567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard goto done; 2551567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2552567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2553567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2554567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2555567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2556567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2557e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard default: 2558567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard goto not_determinist; 2559e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2560567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillarddone: 25616e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard if (atom1->neg != atom2->neg) { 25629efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard ret = !ret; 25636e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard } 2564567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (ret == 0) 2565567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(0); 2566567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillardnot_determinist: 2567567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(1); 2568e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard} 2569e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 2570e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard/** 2571e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * xmlFARecurseDeterminism: 2572e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * @ctxt: a regexp parser context 2573e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 2574e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * Check whether the associated regexp is determinist, 2575e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * should be called after xmlFAEliminateEpsilonTransitions() 2576e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 2577e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2578e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillardstatic int 2579e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel VeillardxmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state, 2580e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int to, xmlRegAtomPtr atom) { 2581e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int ret = 1; 2582567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int res; 25835de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard int transnr, nbTrans; 2584e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard xmlRegTransPtr t1; 25851ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard int deep = 1; 2586e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 2587e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (state == NULL) 2588e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(ret); 25891ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard 25901ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (ctxt->flags & AM_AUTOMATA_RNG) 25911ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard deep = 0; 25921ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard 25935de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard /* 25945de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard * don't recurse on transitions potentially added in the course of 25955de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard * the elimination. 25965de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard */ 25975de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard nbTrans = state->nbTrans; 25985de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard for (transnr = 0;transnr < nbTrans;transnr++) { 2599e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard t1 = &(state->trans[transnr]); 2600e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard /* 2601e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * check transitions conflicting with the one looked at 2602e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2603e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (t1->atom == NULL) { 26040e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard if (t1->to < 0) 2605e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 2606567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard res = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to], 2607e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard to, atom); 2608567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (res == 0) { 2609567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2610aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard /* t1->nd = 1; */ 2611567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2612e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 2613e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2614e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (t1->to != to) 2615e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 26161ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (xmlFACompareAtoms(t1->atom, atom, deep)) { 2617567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2618567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* mark the transition as non-deterministic */ 2619567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard t1->nd = 1; 2620567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2621e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2622e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(ret); 2623e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard} 2624e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 2625e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard/** 2626e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * xmlFAComputesDeterminism: 2627e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * @ctxt: a regexp parser context 2628e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 2629e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * Check whether the associated regexp is determinist, 2630e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * should be called after xmlFAEliminateEpsilonTransitions() 2631e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 2632e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2633e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillardstatic int 2634e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel VeillardxmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) { 2635e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int statenr, transnr; 2636e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard xmlRegStatePtr state; 2637567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegTransPtr t1, t2, last; 2638e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int i; 2639e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int ret = 1; 26401ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard int deep = 1; 2641e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 26424402ab420f68d9384bd6c2066c1676848d98d27cDaniel Veillard#ifdef DEBUG_REGEXP_GRAPH 26434402ab420f68d9384bd6c2066c1676848d98d27cDaniel Veillard printf("xmlFAComputesDeterminism\n"); 26444402ab420f68d9384bd6c2066c1676848d98d27cDaniel Veillard xmlRegPrintCtxt(stdout, ctxt); 26454402ab420f68d9384bd6c2066c1676848d98d27cDaniel Veillard#endif 2646e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (ctxt->determinist != -1) 2647e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(ctxt->determinist); 2648e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 26491ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (ctxt->flags & AM_AUTOMATA_RNG) 26501ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard deep = 0; 26511ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard 2652e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard /* 2653567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * First cleanup the automata removing cancelled transitions 2654e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2655e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 2656e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard state = ctxt->states[statenr]; 2657e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (state == NULL) 2658e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 26594f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard if (state->nbTrans < 2) 26604f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard continue; 2661e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard for (transnr = 0;transnr < state->nbTrans;transnr++) { 2662e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard t1 = &(state->trans[transnr]); 2663e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard /* 2664e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * Determinism checks in case of counted or all transitions 2665e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * will have to be handled separately 2666e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2667567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (t1->atom == NULL) { 2668aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard /* t1->nd = 1; */ 2669e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 2670567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2671e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (t1->to == -1) /* eliminated */ 2672e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 2673e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard for (i = 0;i < transnr;i++) { 2674e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard t2 = &(state->trans[i]); 2675e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (t2->to == -1) /* eliminated */ 2676e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 2677e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (t2->atom != NULL) { 2678e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (t1->to == t2->to) { 26791ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard /* 26801ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * Here we use deep because we want to keep the 26811ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * transitions which indicate a conflict 26821ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard */ 26831ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (xmlFAEqualAtoms(t1->atom, t2->atom, deep) && 268411e28e4dfb84804474a3d7a4bfb08bae8f00bc0aDaniel Veillard (t1->counter == t2->counter) && 268511e28e4dfb84804474a3d7a4bfb08bae8f00bc0aDaniel Veillard (t1->count == t2->count)) 2686ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack t2->to = -1; /* eliminated */ 2687567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2688567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2689567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2690567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2691567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2692567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2693567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* 2694567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * Check for all states that there aren't 2 transitions 2695567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * with the same atom and a different target. 2696567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard */ 2697567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 2698567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard state = ctxt->states[statenr]; 2699567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (state == NULL) 2700567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard continue; 2701567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (state->nbTrans < 2) 2702567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard continue; 2703567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard last = NULL; 2704567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard for (transnr = 0;transnr < state->nbTrans;transnr++) { 2705567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard t1 = &(state->trans[transnr]); 2706567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* 2707567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * Determinism checks in case of counted or all transitions 2708567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * will have to be handled separately 2709567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard */ 2710567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (t1->atom == NULL) { 2711567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard continue; 2712567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2713567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (t1->to == -1) /* eliminated */ 2714567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard continue; 2715567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard for (i = 0;i < transnr;i++) { 2716567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard t2 = &(state->trans[i]); 2717567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (t2->to == -1) /* eliminated */ 2718567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard continue; 2719567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (t2->atom != NULL) { 27201ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard /* 27211ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * But here we don't use deep because we want to 27221ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * find transitions which indicate a conflict 27231ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard */ 27241ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (xmlFACompareAtoms(t1->atom, t2->atom, 1)) { 2725567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2726567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* mark the transitions as non-deterministic ones */ 2727567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard t1->nd = 1; 2728567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard t2->nd = 1; 2729567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard last = t1; 2730e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2731e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } else if (t1->to != -1) { 2732e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard /* 2733e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * do the closure in case of remaining specific 2734e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * epsilon transitions like choices or all 2735e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2736e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard ret = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to], 2737e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard t2->to, t2->atom); 2738567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* don't shortcut the computation so all non deterministic 2739567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard transition get marked down 2740e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (ret == 0) 2741aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard return(0); 2742aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard */ 2743567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (ret == 0) { 2744567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard t1->nd = 1; 2745aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard /* t2->nd = 1; */ 2746567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard last = t1; 2747567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2748e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2749e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2750567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* don't shortcut the computation so all non deterministic 2751567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard transition get marked down 2752e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (ret == 0) 2753567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; */ 2754e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2755567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2756567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* 2757567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * mark specifically the last non-deterministic transition 2758567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * from a state since there is no need to set-up rollback 2759567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * from it 2760567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard */ 2761567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (last != NULL) { 2762567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard last->nd = 2; 2763567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2764567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2765567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* don't shortcut the computation so all non deterministic 2766567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard transition get marked down 2767e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (ret == 0) 2768567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; */ 2769e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2770567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2771e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard ctxt->determinist = ret; 2772e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(ret); 2773e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard} 2774e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 27754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 27764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 27774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Routines to check input against transition atoms * 27784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 27794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 27804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 27814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 27824255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, int neg, 27834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int start, int end, const xmlChar *blockName) { 27844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ret = 0; 27854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 27864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (type) { 27874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_STRING: 27884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SUBREG: 27894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_RANGES: 27904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_EPSILON: 27914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 27924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_ANYCHAR: 27934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ((codepoint != '\n') && (codepoint != '\r')); 27944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 27954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_CHARVAL: 27964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ((codepoint >= start) && (codepoint <= end)); 27974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 27984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTSPACE: 27994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard neg = !neg; 28004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_ANYSPACE: 28014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ((codepoint == '\n') || (codepoint == '\r') || 28024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (codepoint == '\t') || (codepoint == ' ')); 28034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTINITNAME: 28054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard neg = !neg; 28064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_INITNAME: 2807871611bb0325095b30559ff1edc1fdaa2ad5fd2fWilliam M. Brack ret = (IS_LETTER(codepoint) || 28084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (codepoint == '_') || (codepoint == ':')); 28094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTNAMECHAR: 28114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard neg = !neg; 28124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NAMECHAR: 2813871611bb0325095b30559ff1edc1fdaa2ad5fd2fWilliam M. Brack ret = (IS_LETTER(codepoint) || IS_DIGIT(codepoint) || 28144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (codepoint == '.') || (codepoint == '-') || 28154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (codepoint == '_') || (codepoint == ':') || 2816871611bb0325095b30559ff1edc1fdaa2ad5fd2fWilliam M. Brack IS_COMBINING(codepoint) || IS_EXTENDER(codepoint)); 28174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTDECIMAL: 28194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard neg = !neg; 28204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_DECIMAL: 28214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatNd(codepoint); 28224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_REALCHAR: 28244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard neg = !neg; 28254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTREALCHAR: 28264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatP(codepoint); 28274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 0) 28284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatZ(codepoint); 28294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 0) 28304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatC(codepoint); 28314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER: 28334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatL(codepoint); 28344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_UPPERCASE: 28364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatLu(codepoint); 28374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_LOWERCASE: 28394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatLl(codepoint); 28404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_TITLECASE: 28424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatLt(codepoint); 28434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_MODIFIER: 28454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatLm(codepoint); 28464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_OTHERS: 28484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatLo(codepoint); 28494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK: 28514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatM(codepoint); 28524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_NONSPACING: 28544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatMn(codepoint); 28554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_SPACECOMBINING: 28574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatMc(codepoint); 28584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_ENCLOSING: 28604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatMe(codepoint); 28614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER: 28634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatN(codepoint); 28644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_DECIMAL: 28664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatNd(codepoint); 28674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_LETTER: 28694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatNl(codepoint); 28704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_OTHERS: 28724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatNo(codepoint); 28734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT: 28754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatP(codepoint); 28764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_CONNECTOR: 28784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPc(codepoint); 28794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_DASH: 28814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPd(codepoint); 28824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_OPEN: 28844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPs(codepoint); 28854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_CLOSE: 28874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPe(codepoint); 28884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_INITQUOTE: 28904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPi(codepoint); 28914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_FINQUOTE: 28934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPf(codepoint); 28944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_OTHERS: 28964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPo(codepoint); 28974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR: 28994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatZ(codepoint); 29004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_SPACE: 29024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatZs(codepoint); 29034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_LINE: 29054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatZl(codepoint); 29064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_PARA: 29084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatZp(codepoint); 29094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL: 29114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatS(codepoint); 29124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_MATH: 29144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatSm(codepoint); 29154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_CURRENCY: 29174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatSc(codepoint); 29184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_MODIFIER: 29204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatSk(codepoint); 29214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_OTHERS: 29234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatSo(codepoint); 29244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER: 29264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatC(codepoint); 29274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_CONTROL: 29294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatCc(codepoint); 29304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_FORMAT: 29324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatCf(codepoint); 29334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_PRIVATE: 29354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatCo(codepoint); 29364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_NA: 29384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* ret = xmlUCSIsCatCn(codepoint); */ 29394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* Seems it doesn't exist anymore in recent Unicode releases */ 29404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 29414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_BLOCK_NAME: 29434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsBlock(codepoint, (const char *) blockName); 29444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 29464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (neg) 29474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(!ret); 29484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 29494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 29504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 29514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 29524255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint) { 29534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i, ret = 0; 29544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegRangePtr range; 29554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2956871611bb0325095b30559ff1edc1fdaa2ad5fd2fWilliam M. Brack if ((atom == NULL) || (!IS_CHAR(codepoint))) 29574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 29584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 29594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (atom->type) { 29604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SUBREG: 29614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_EPSILON: 29624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 29634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_CHARVAL: 29644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(codepoint == atom->codepoint); 29654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_RANGES: { 29664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int accept = 0; 2967f2a1283564df8ded1942b231c60c3a7ae4ff748aDaniel Veillard 29684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < atom->nbRanges;i++) { 29694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard range = atom->ranges[i]; 2970f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard if (range->neg == 2) { 29714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacterRange(range->type, codepoint, 29724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 0, range->start, range->end, 29734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard range->blockName); 29744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret != 0) 29754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); /* excluded char */ 2976f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard } else if (range->neg) { 2977f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard ret = xmlRegCheckCharacterRange(range->type, codepoint, 2978f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard 0, range->start, range->end, 2979f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard range->blockName); 2980f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard if (ret == 0) 2981f2a1283564df8ded1942b231c60c3a7ae4ff748aDaniel Veillard accept = 1; 2982f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard else 2983f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard return(0); 29844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 29854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacterRange(range->type, codepoint, 29864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 0, range->start, range->end, 29874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard range->blockName); 29884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret != 0) 29894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard accept = 1; /* might still be excluded */ 29904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 29914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 29924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(accept); 29934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 29944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_STRING: 29954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("TODO: XML_REGEXP_STRING\n"); 29964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 29974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_ANYCHAR: 29984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_ANYSPACE: 29994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTSPACE: 30004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_INITNAME: 30014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTINITNAME: 30024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NAMECHAR: 30034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTNAMECHAR: 30044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_DECIMAL: 30054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTDECIMAL: 30064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_REALCHAR: 30074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTREALCHAR: 30084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER: 30094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_UPPERCASE: 30104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_LOWERCASE: 30114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_TITLECASE: 30124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_MODIFIER: 30134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_OTHERS: 30144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK: 30154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_NONSPACING: 30164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_SPACECOMBINING: 30174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_ENCLOSING: 30184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER: 30194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_DECIMAL: 30204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_LETTER: 30214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_OTHERS: 30224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT: 30234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_CONNECTOR: 30244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_DASH: 30254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_OPEN: 30264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_CLOSE: 30274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_INITQUOTE: 30284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_FINQUOTE: 30294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_OTHERS: 30304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR: 30314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_SPACE: 30324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_LINE: 30334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_PARA: 30344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL: 30354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_MATH: 30364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_CURRENCY: 30374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_MODIFIER: 30384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_OTHERS: 30394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER: 30404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_CONTROL: 30414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_FORMAT: 30424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_PRIVATE: 30434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_NA: 30444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_BLOCK_NAME: 30454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacterRange(atom->type, codepoint, 0, 0, 0, 30464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (const xmlChar *)atom->valuep); 30474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->neg) 30484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = !ret; 30494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 30504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 30514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 30524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 30534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 30544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 30554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 3056ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Saving and restoring state of an execution context * 30574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 30584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 30594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 30604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 30614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 30624255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegDebugExec(xmlRegExecCtxtPtr exec) { 30634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("state: %d:%d:idx %d", exec->state->no, exec->transno, exec->index); 30644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStack != NULL) { 30654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 30664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf(": "); 30674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;(i < 3) && (i < exec->inputStackNr);i++) 30680e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard printf("%s ", (const char *) 30690e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard exec->inputStack[exec->inputStackNr - (i + 1)].value); 30704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 30714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf(": %s", &(exec->inputString[exec->index])); 30724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 30734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("\n"); 30744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 30754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 30764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 30774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 30784255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegExecSave(xmlRegExecCtxtPtr exec) { 30794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 30804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("saving "); 30814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno++; 30824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegDebugExec(exec); 30834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno--; 30844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 308594cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard#ifdef MAX_PUSH 308694cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard if (exec->nbPush > MAX_PUSH) { 308794cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard return; 308894cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard } 308994cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard exec->nbPush++; 309094cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard#endif 30914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 30924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->maxRollbacks == 0) { 30934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks = 4; 30944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks = (xmlRegExecRollback *) xmlMalloc(exec->maxRollbacks * 30954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegExecRollback)); 30964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks == NULL) { 3097ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "saving regexp"); 30984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks = 0; 30994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 31004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(exec->rollbacks, 0, 31024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks * sizeof(xmlRegExecRollback)); 31034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (exec->nbRollbacks >= exec->maxRollbacks) { 31044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegExecRollback *tmp; 31054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int len = exec->maxRollbacks; 31064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 31074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks *= 2; 31084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegExecRollback *) xmlRealloc(exec->rollbacks, 31094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks * sizeof(xmlRegExecRollback)); 31104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 3111ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "saving regexp"); 31124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks /= 2; 31134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 31144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks = tmp; 31164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = &exec->rollbacks[len]; 31174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(tmp, 0, (exec->maxRollbacks - len) * sizeof(xmlRegExecRollback)); 31184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks[exec->nbRollbacks].state = exec->state; 31204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks[exec->nbRollbacks].index = exec->index; 31214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks[exec->nbRollbacks].nextbranch = exec->transno + 1; 31224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->comp->nbCounters > 0) { 31234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks[exec->nbRollbacks].counts == NULL) { 31244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks[exec->nbRollbacks].counts = (int *) 31254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlMalloc(exec->comp->nbCounters * sizeof(int)); 31264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks[exec->nbRollbacks].counts == NULL) { 3127ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "saving regexp"); 31284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -5; 31294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 31304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memcpy(exec->rollbacks[exec->nbRollbacks].counts, exec->counts, 31334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->comp->nbCounters * sizeof(int)); 31344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->nbRollbacks++; 31364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 31374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 31384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 31394255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegExecRollBack(xmlRegExecCtxtPtr exec) { 31404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->nbRollbacks <= 0) { 31414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -1; 31424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 31434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("rollback failed on empty stack\n"); 31444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 31454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 31464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->nbRollbacks--; 31484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = exec->rollbacks[exec->nbRollbacks].state; 31494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index = exec->rollbacks[exec->nbRollbacks].index; 31504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = exec->rollbacks[exec->nbRollbacks].nextbranch; 31514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->comp->nbCounters > 0) { 31524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks[exec->nbRollbacks].counts == NULL) { 31534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(stderr, "exec save: allocation failed"); 31544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -6; 31554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 31564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memcpy(exec->counts, exec->rollbacks[exec->nbRollbacks].counts, 31584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->comp->nbCounters * sizeof(int)); 31594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 31614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 31624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("restored "); 31634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegDebugExec(exec); 31644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 31654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 31664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 31674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 31684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 3169ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Verifier, running an input against a compiled regexp * 31704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 31714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 31724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 31734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 31744255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) { 31754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegExecCtxt execval; 31764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegExecCtxtPtr exec = &execval; 3177567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int ret, codepoint = 0, len, deter; 31784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 31794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputString = content; 31804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index = 0; 318194cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard exec->nbPush = 0; 31824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->determinist = 1; 31834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks = 0; 31844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->nbRollbacks = 0; 31854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks = NULL; 31864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = 0; 31874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->comp = comp; 31884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = comp->states[0]; 31894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = 0; 31904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 0; 3191f2a1283564df8ded1942b231c60c3a7ae4ff748aDaniel Veillard exec->inputStack = NULL; 3192f2a1283564df8ded1942b231c60c3a7ae4ff748aDaniel Veillard exec->inputStackMax = 0; 31934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (comp->nbCounters > 0) { 31944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int)); 3195ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard if (exec->counts == NULL) { 3196ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "running regexp"); 31974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 3198ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard } 31994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(exec->counts, 0, comp->nbCounters * sizeof(int)); 32004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else 32014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->counts = NULL; 32024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((exec->status == 0) && 32034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ((exec->inputString[exec->index] != 0) || 3204ad55998f74ab7f89cc5ed454589fb8f528873a02Daniel Veillard ((exec->state != NULL) && 3205ad55998f74ab7f89cc5ed454589fb8f528873a02Daniel Veillard (exec->state->type != XML_REGEXP_FINAL_STATE)))) { 32064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegTransPtr trans; 32074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 32084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 32094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 32100e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * If end of input on non-terminal state, rollback, however we may 32114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * still have epsilon like transition for counted transitions 32120e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * on counters, in that case don't break too early. Additionally, 32130e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * if we are working on a range like "AB{0,2}", where B is not present, 32140e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * we don't want to break. 32154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 321611ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard len = 1; 32170e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL)) { 3218ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack /* 3219ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * if there is a transition, we must check if 3220ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * atom allows minOccurs of 0 3221ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack */ 3222ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack if (exec->transno < exec->state->nbTrans) { 32230e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack trans = &exec->state->trans[exec->transno]; 32240e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack if (trans->to >=0) { 32250e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack atom = trans->atom; 32260e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack if (!((atom->min == 0) && (atom->max > 0))) 32270e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack goto rollback; 32280e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack } 32290e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack } else 32300e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack goto rollback; 32310e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack } 32324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 32334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 0; 32344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (;exec->transno < exec->state->nbTrans;exec->transno++) { 32354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard trans = &exec->state->trans[exec->transno]; 32364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->to < 0) 32374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 32384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom = trans->atom; 32394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 3240567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard deter = 1; 32414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->count >= 0) { 32424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int count; 32434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegCounterPtr counter; 32444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 324511ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (exec->counts == NULL) { 324611ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard exec->status = -1; 324711ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard goto error; 324811ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard } 32494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 32504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * A counted transition. 32514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 32524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 32534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard count = exec->counts[trans->count]; 32544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard counter = &exec->comp->counters[trans->count]; 32554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 32564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("testing count %d: val %d, min %d, max %d\n", 32574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard trans->count, count, counter->min, counter->max); 32584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 32594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ((count >= counter->min) && (count <= counter->max)); 3260567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((ret) && (counter->min != counter->max)) 3261567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard deter = 0; 32624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (atom == NULL) { 32634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(stderr, "epsilon transition left at runtime\n"); 32644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -2; 32654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 32664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (exec->inputString[exec->index] != 0) { 32674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len); 32684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacter(atom, codepoint); 32690e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack if ((ret == 1) && (atom->min >= 0) && (atom->max > 0)) { 32704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr to = comp->states[trans->to]; 32714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 32724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 32734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * this is a multiple input sequence 3274fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard * If there is a counter associated increment it now. 3275fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard * before potentially saving and rollback 3276c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard * do not increment if the counter is already over the 3277c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard * maximum limit in which case get to next transition 32784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 3279fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard if (trans->counter >= 0) { 3280c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard xmlRegCounterPtr counter; 3281c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard 3282c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard if ((exec->counts == NULL) || 3283c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard (exec->comp == NULL) || 3284c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard (exec->comp->counters == NULL)) { 328511ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard exec->status = -1; 328611ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard goto error; 328711ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard } 3288c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard counter = &exec->comp->counters[trans->counter]; 3289c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard if (exec->counts[trans->counter] >= counter->max) 3290c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard continue; /* for loop on transitions */ 3291c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard 3292fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard#ifdef DEBUG_REGEXP_EXEC 3293fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard printf("Increasing count %d\n", trans->counter); 3294fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard#endif 3295fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard exec->counts[trans->counter]++; 3296fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard } 32974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->state->nbTrans > exec->transno + 1) { 32984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 32994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 33004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 1; 33014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard do { 33024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 33034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Try to progress as much as possible on the input 33044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 33054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount == atom->max) { 33064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 33074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 33084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index += len; 33094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 33104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * End of input: stop here 33114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 33124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputString[exec->index] == 0) { 33134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index -= len; 33144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 33154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 33164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount >= atom->min) { 33174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int transno = exec->transno; 33184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state = exec->state; 33194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 33204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 33214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The transition is acceptable save it 33224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 33234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = -1; /* trick */ 33244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = to; 33254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 33264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = transno; 33274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = state; 33284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 33294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), 33304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard len); 33314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacter(atom, codepoint); 33324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount++; 33334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } while (ret == 1); 33344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount < atom->min) 33354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 33364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 33374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 33384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * If the last check failed but one transition was found 33394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * possible, rollback 33404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 33414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret < 0) 33424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 33434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 0) { 33444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto rollback; 33454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 3346fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard if (trans->counter >= 0) { 334711ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (exec->counts == NULL) { 334811ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard exec->status = -1; 334911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard goto error; 335011ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard } 3351fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard#ifdef DEBUG_REGEXP_EXEC 3352fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard printf("Decreasing count %d\n", trans->counter); 3353fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard#endif 3354fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard exec->counts[trans->counter]--; 3355fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard } 33560e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack } else if ((ret == 0) && (atom->min == 0) && (atom->max > 0)) { 33570e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack /* 33580e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * we don't match on the codepoint, but minOccurs of 0 33590e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * says that's ok. Setting len to 0 inhibits stepping 33600e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * over the codepoint. 33610e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack */ 33620e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack exec->transcount = 1; 33630e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack len = 0; 33640e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack ret = 1; 33654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 33660e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack } else if ((atom->min == 0) && (atom->max > 0)) { 33670e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack /* another spot to match when minOccurs is 0 */ 33680e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack exec->transcount = 1; 33690e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack len = 0; 33700e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack ret = 1; 33714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 33724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 1) { 3373567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((trans->nd == 1) || 3374567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ((trans->count >= 0) && (deter == 0) && 3375567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (exec->state->nbTrans > exec->transno + 1))) { 3376aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 3377aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard if (trans->nd == 1) 3378aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard printf("Saving on nd transition atom %d for %c at %d\n", 3379aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard trans->atom->no, codepoint, exec->index); 3380aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard else 3381aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard printf("Saving on counted transition count %d for %c at %d\n", 3382aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard trans->count, codepoint, exec->index); 3383aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard#endif 33844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 33854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 33864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->counter >= 0) { 3387c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard xmlRegCounterPtr counter; 3388c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard 3389c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard /* make sure we don't go over the counter maximum value */ 3390c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard if ((exec->counts == NULL) || 3391c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard (exec->comp == NULL) || 3392c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard (exec->comp->counters == NULL)) { 3393c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard exec->status = -1; 339411ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard goto error; 339511ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard } 3396c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard counter = &exec->comp->counters[trans->counter]; 3397c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard if (exec->counts[trans->counter] >= counter->max) 3398c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard continue; /* for loop on transitions */ 33994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 34004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Increasing count %d\n", trans->counter); 34014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 34024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->counts[trans->counter]++; 34034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 340410752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard if ((trans->count >= 0) && 340510752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard (trans->count < REGEXP_ALL_COUNTER)) { 340611ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (exec->counts == NULL) { 340711ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard exec->status = -1; 340811ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard goto error; 340911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard } 341010752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard#ifdef DEBUG_REGEXP_EXEC 341110752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard printf("resetting count %d on transition\n", 341210752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard trans->count); 341310752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard#endif 341410752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard exec->counts[trans->count] = 0; 341510752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard } 34164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 34174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("entering state %d\n", trans->to); 34184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 34194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = comp->states[trans->to]; 34204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = 0; 34214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->atom != NULL) { 34224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index += len; 34234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 34244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto progress; 34254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ret < 0) { 34264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -4; 34274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 34284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 34294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 34304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((exec->transno != 0) || (exec->state->nbTrans == 0)) { 34314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardrollback: 34324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 34334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Failed to find a way out 34344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 34354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->determinist = 0; 3436aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 3437aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard printf("rollback from state %d on %d:%c\n", exec->state->no, 3438aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard codepoint,codepoint); 3439aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard#endif 34404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecRollBack(exec); 34414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 34424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardprogress: 34434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 34444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 344511ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillarderror: 34464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks != NULL) { 34474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->counts != NULL) { 34484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 34494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 34504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < exec->maxRollbacks;i++) 34514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks[i].counts != NULL) 34524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->rollbacks[i].counts); 34534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 34544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->rollbacks); 34554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 34564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->counts != NULL) 34574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->counts); 34584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->status == 0) 34594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 346094cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard if (exec->status == -1) { 346194cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard if (exec->nbPush > MAX_PUSH) 346294cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard return(-1); 34634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 346494cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard } 34654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(exec->status); 34664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 34674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 34684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 34694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 3470ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Progressive interface to the verifier one atom at a time * 34714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 34724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 34737bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#ifdef DEBUG_ERR 34747bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillardstatic void testerr(xmlRegExecCtxtPtr exec); 34757bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#endif 34764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 34774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 347801c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlRegNewExecCtxt: 34794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @comp: a precompiled regular expression 34804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @callback: a callback function used for handling progresses in the 34814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * automata matching phase 34824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @data: the context data associated to the callback in this context 34834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 34844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Build a context used for progressive evaluation of a regexp. 348501c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * 348601c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * Returns the new context 34874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 34884255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegExecCtxtPtr 34894255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewExecCtxt(xmlRegexpPtr comp, xmlRegExecCallbacks callback, void *data) { 34904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegExecCtxtPtr exec; 34914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 34924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (comp == NULL) 34934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 3494a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if ((comp->compact == NULL) && (comp->states == NULL)) 3495a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 34964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec = (xmlRegExecCtxtPtr) xmlMalloc(sizeof(xmlRegExecCtxt)); 34974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec == NULL) { 3498ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "creating execution context"); 34994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 35004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 35014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(exec, 0, sizeof(xmlRegExecCtxt)); 35024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputString = NULL; 35034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index = 0; 35044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->determinist = 1; 35054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks = 0; 35064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->nbRollbacks = 0; 35074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks = NULL; 35084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = 0; 35094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->comp = comp; 351023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (comp->compact == NULL) 351123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard exec->state = comp->states[0]; 35124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = 0; 35134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 0; 35144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->callback = callback; 35154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->data = data; 35164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (comp->nbCounters > 0) { 35177bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard /* 35187bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * For error handling, exec->counts is allocated twice the size 35197bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * the second half is used to store the data in case of rollback 35207bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard */ 35217bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int) 35227bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * 2); 35234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->counts == NULL) { 3524ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "creating execution context"); 35254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec); 35264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 35274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 35287bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard memset(exec->counts, 0, comp->nbCounters * sizeof(int) * 2); 35297bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->errCounts = &exec->counts[comp->nbCounters]; 35307bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } else { 35314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->counts = NULL; 35327bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->errCounts = NULL; 35337bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 35344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackMax = 0; 35354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackNr = 0; 35364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStack = NULL; 35377bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->errStateNo = -1; 35387bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->errString = NULL; 353994cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard exec->nbPush = 0; 35404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(exec); 35414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 35424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 35434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 35444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeExecCtxt: 35454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @exec: a regular expression evaulation context 35464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 35474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free the structures associated to a regular expression evaulation context. 35484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 35494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid 35504255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeExecCtxt(xmlRegExecCtxtPtr exec) { 35514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec == NULL) 35524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 35534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 35544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks != NULL) { 35554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->counts != NULL) { 35564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 35574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 35584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < exec->maxRollbacks;i++) 35594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks[i].counts != NULL) 35604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->rollbacks[i].counts); 35614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 35624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->rollbacks); 35634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 35644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->counts != NULL) 35654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->counts); 35664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStack != NULL) { 35674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 35684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 35693237023d6a8036dff817c3d46485ce6495d8ae21Daniel Veillard for (i = 0;i < exec->inputStackNr;i++) { 35703237023d6a8036dff817c3d46485ce6495d8ae21Daniel Veillard if (exec->inputStack[i].value != NULL) 35713237023d6a8036dff817c3d46485ce6495d8ae21Daniel Veillard xmlFree(exec->inputStack[i].value); 35723237023d6a8036dff817c3d46485ce6495d8ae21Daniel Veillard } 35734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->inputStack); 35744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 35757bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard if (exec->errString != NULL) 35767bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlFree(exec->errString); 35774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec); 35784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 35794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 35804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 35814255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegExecSaveInputString(xmlRegExecCtxtPtr exec, const xmlChar *value, 35824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard void *data) { 35834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 35844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("saving value: %d:%s\n", exec->inputStackNr, value); 35854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 35864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStackMax == 0) { 35874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackMax = 4; 35884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStack = (xmlRegInputTokenPtr) 35894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlMalloc(exec->inputStackMax * sizeof(xmlRegInputToken)); 35904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStack == NULL) { 3591ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "pushing input string"); 35924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackMax = 0; 35934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 35944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 35954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (exec->inputStackNr + 1 >= exec->inputStackMax) { 35964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegInputTokenPtr tmp; 35974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 35984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackMax *= 2; 35994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegInputTokenPtr) xmlRealloc(exec->inputStack, 36004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackMax * sizeof(xmlRegInputToken)); 36014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 3602ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "pushing input string"); 36034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackMax /= 2; 36044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 36054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 36064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStack = tmp; 36074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 36084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStack[exec->inputStackNr].value = xmlStrdup(value); 36094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStack[exec->inputStackNr].data = data; 36104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackNr++; 36114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStack[exec->inputStackNr].value = NULL; 36124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStack[exec->inputStackNr].data = NULL; 36134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 36144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3615c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard/** 3616c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * xmlRegStrEqualWildcard: 3617c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * @expStr: the string to be evaluated 3618c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * @valStr: the validation string 3619c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * 3620c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * Checks if both strings are equal or have the same content. "*" 3621c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * can be used as a wildcard in @valStr; "|" is used as a seperator of 3622c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * substrings in both @expStr and @valStr. 3623c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * 3624c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * Returns 1 if the comparison is satisfied and the number of substrings 3625c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * is equal, 0 otherwise. 3626c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard */ 3627c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard 3628c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillardstatic int 3629c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel VeillardxmlRegStrEqualWildcard(const xmlChar *expStr, const xmlChar *valStr) { 3630c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (expStr == valStr) return(1); 3631c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (expStr == NULL) return(0); 3632c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (valStr == NULL) return(0); 3633c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard do { 3634c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard /* 3635c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * Eval if we have a wildcard for the current item. 3636c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard */ 3637c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (*expStr != *valStr) { 36384f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard /* if one of them starts with a wildcard make valStr be it */ 36394f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard if (*valStr == '*') { 36404f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard const xmlChar *tmp; 36414f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard 36424f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard tmp = valStr; 36434f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard valStr = expStr; 36444f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard expStr = tmp; 36454f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard } 3646c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if ((*valStr != 0) && (*expStr != 0) && (*expStr++ == '*')) { 3647c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard do { 3648c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (*valStr == XML_REG_STRING_SEPARATOR) 3649c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard break; 3650c0e833f0024d46f50772620f24e6cf9d93748017Kasimier T. Buchcik valStr++; 3651c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard } while (*valStr != 0); 3652c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard continue; 3653c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard } else 3654c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard return(0); 3655c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard } 3656c0e833f0024d46f50772620f24e6cf9d93748017Kasimier T. Buchcik expStr++; 3657c0e833f0024d46f50772620f24e6cf9d93748017Kasimier T. Buchcik valStr++; 3658c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard } while (*valStr != 0); 3659c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (*expStr != 0) 3660c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard return (0); 3661c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard else 3662c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard return (1); 3663c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard} 36644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 36654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 366623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * xmlRegCompactPushString: 366723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * @exec: a regexp execution context 366823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * @comp: the precompiled exec with a compact table 366923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * @value: a string token input 367023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * @data: data associated to the token to reuse in callbacks 367123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * 367223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Push one input token in the execution context 367323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * 367423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Returns: 1 if the regexp reached a final state, 0 if non-final, and 367523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * a negative value in case of error. 367623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 367723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillardstatic int 367823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel VeillardxmlRegCompactPushString(xmlRegExecCtxtPtr exec, 367923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegexpPtr comp, 368023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard const xmlChar *value, 368123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard void *data) { 368223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int state = exec->index; 368323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int i, target; 368423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 368523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if ((comp == NULL) || (comp->compact == NULL) || (comp->stringMap == NULL)) 368623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(-1); 368723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 368823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (value == NULL) { 368923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 369023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * are we at a final state ? 369123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 369223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (comp->compact[state * (comp->nbstrings + 1)] == 369323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard XML_REGEXP_FINAL_STATE) 369423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(1); 369523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(0); 369623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 369723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 369823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_PUSH 369923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("value pushed: %s\n", value); 370023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 370123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 370223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 3703ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Examine all outside transitions from current state 370423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 370523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < comp->nbstrings;i++) { 370623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard target = comp->compact[state * (comp->nbstrings + 1) + i + 1]; 370723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if ((target > 0) && (target <= comp->nbstates)) { 3708c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard target--; /* to avoid 0 */ 3709c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (xmlRegStrEqualWildcard(comp->stringMap[i], value)) { 3710c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard exec->index = target; 3711118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if ((exec->callback != NULL) && (comp->transdata != NULL)) { 3712118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard exec->callback(exec->data, value, 3713118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard comp->transdata[state * comp->nbstrings + i], data); 3714118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard } 371523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_PUSH 371623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("entering state %d\n", target); 371723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 371823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (comp->compact[target * (comp->nbstrings + 1)] == 3719cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_SINK_STATE) 3720cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard goto error; 3721cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard 3722cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if (comp->compact[target * (comp->nbstrings + 1)] == 372323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard XML_REGEXP_FINAL_STATE) 372423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(1); 372523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(0); 372623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 372723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 372823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 372923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 373023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Failed to find an exit transition out from current state for the 373123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * current token 373223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 373323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_PUSH 373423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("failed to find a transition for %s on state %d\n", value, state); 373523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 3736cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillarderror: 37377bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard if (exec->errString != NULL) 37387bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlFree(exec->errString); 37397bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->errString = xmlStrdup(value); 37407bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->errStateNo = state; 374123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard exec->status = -1; 37427bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#ifdef DEBUG_ERR 37437bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard testerr(exec); 37447bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#endif 374523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(-1); 374623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard} 374723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 374823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard/** 37496e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * xmlRegExecPushStringInternal: 3750ea7751d53bf497e873dca39b2c305e300e2574f9Daniel Veillard * @exec: a regexp execution context or NULL to indicate the end 37514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @value: a string token input 37524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @data: data associated to the token to reuse in callbacks 37536e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * @compound: value was assembled from 2 strings 37544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 37554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Push one input token in the execution context 37564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 37574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns: 1 if the regexp reached a final state, 0 if non-final, and 37584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * a negative value in case of error. 37594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 37606e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillardstatic int 37616e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel VeillardxmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value, 37626e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard void *data, int compound) { 37634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegTransPtr trans; 37644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 37654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ret; 37664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int final = 0; 37679070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard int progress = 1; 37684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 37694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec == NULL) 37704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 377123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (exec->comp == NULL) 377223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(-1); 37734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->status != 0) 37744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(exec->status); 37754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 377623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (exec->comp->compact != NULL) 377723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(xmlRegCompactPushString(exec, exec->comp, value, data)); 377823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 37794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (value == NULL) { 37804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->state->type == XML_REGEXP_FINAL_STATE) 37814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 37824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard final = 1; 37834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 37844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 37854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 37864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("value pushed: %s\n", value); 37874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 37884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 37894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * If we have an active rollback stack push the new value there 37904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * and get back to where we were left 37914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 37924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((value != NULL) && (exec->inputStackNr > 0)) { 37934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSaveInputString(exec, value, data); 37944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value = exec->inputStack[exec->index].value; 37954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard data = exec->inputStack[exec->index].data; 37964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 37974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("value loaded: %s\n", value); 37984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 37994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 38004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 38014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((exec->status == 0) && 38024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ((value != NULL) || 38034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ((final == 1) && 38044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (exec->state->type != XML_REGEXP_FINAL_STATE)))) { 38054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 38064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 38074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * End of input on non-terminal state, rollback, however we may 38084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * still have epsilon like transition for counted transitions 38094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * on counters, in that case don't break too early. 38104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 3811b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if ((value == NULL) && (exec->counts == NULL)) 38124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto rollback; 38134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 38144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 0; 38154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (;exec->transno < exec->state->nbTrans;exec->transno++) { 38164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard trans = &exec->state->trans[exec->transno]; 38174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->to < 0) 38184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 38194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom = trans->atom; 38204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 3821441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if (trans->count == REGEXP_ALL_LAX_COUNTER) { 3822441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard int i; 3823441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard int count; 3824441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard xmlRegTransPtr t; 3825441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard xmlRegCounterPtr counter; 3826441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard 3827441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard ret = 0; 3828441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard 3829441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard#ifdef DEBUG_PUSH 3830441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard printf("testing all lax %d\n", trans->count); 3831441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard#endif 3832441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard /* 3833441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * Check all counted transitions from the current state 3834441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard */ 3835441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if ((value == NULL) && (final)) { 3836441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard ret = 1; 3837441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } else if (value != NULL) { 3838441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard for (i = 0;i < exec->state->nbTrans;i++) { 3839441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard t = &exec->state->trans[i]; 3840441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if ((t->counter < 0) || (t == trans)) 3841441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard continue; 3842441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard counter = &exec->comp->counters[t->counter]; 3843441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard count = exec->counts[t->counter]; 3844441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if ((count < counter->max) && 3845441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard (t->atom != NULL) && 3846441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard (xmlStrEqual(value, t->atom->valuep))) { 3847441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard ret = 0; 3848441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard break; 3849441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } 3850441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if ((count >= counter->min) && 3851441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard (count < counter->max) && 385211ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard (t->atom != NULL) && 3853441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard (xmlStrEqual(value, t->atom->valuep))) { 3854441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard ret = 1; 3855441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard break; 3856441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } 3857441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } 3858441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } 3859441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } else if (trans->count == REGEXP_ALL_COUNTER) { 38608a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard int i; 38618a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard int count; 38628a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard xmlRegTransPtr t; 38638a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard xmlRegCounterPtr counter; 38648a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard 38658a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard ret = 1; 38668a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard 38678a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard#ifdef DEBUG_PUSH 38688a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard printf("testing all %d\n", trans->count); 38698a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard#endif 38708a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard /* 38718a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard * Check all counted transitions from the current state 38728a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard */ 38738a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard for (i = 0;i < exec->state->nbTrans;i++) { 38748a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard t = &exec->state->trans[i]; 38758a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard if ((t->counter < 0) || (t == trans)) 38768a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard continue; 38778a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard counter = &exec->comp->counters[t->counter]; 38788a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard count = exec->counts[t->counter]; 38798a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard if ((count < counter->min) || (count > counter->max)) { 38808a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard ret = 0; 38818a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard break; 38828a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard } 38838a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard } 38848a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard } else if (trans->count >= 0) { 38854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int count; 38864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegCounterPtr counter; 38874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 38884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 38894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * A counted transition. 38904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 38914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 38924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard count = exec->counts[trans->count]; 38934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard counter = &exec->comp->counters[trans->count]; 38944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 38954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("testing count %d: val %d, min %d, max %d\n", 38964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard trans->count, count, counter->min, counter->max); 38974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 38984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ((count >= counter->min) && (count <= counter->max)); 38994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (atom == NULL) { 39004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(stderr, "epsilon transition left at runtime\n"); 39014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -2; 39024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 39034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (value != NULL) { 3904c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard ret = xmlRegStrEqualWildcard(atom->valuep, value); 39056e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard if (atom->neg) { 39069efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard ret = !ret; 39076e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard if (!compound) 39086e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard ret = 0; 39096e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard } 3910441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if ((ret == 1) && (trans->counter >= 0)) { 3911441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard xmlRegCounterPtr counter; 3912441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard int count; 3913441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard 3914441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard count = exec->counts[trans->counter]; 3915441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard counter = &exec->comp->counters[trans->counter]; 3916441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if (count >= counter->max) 3917441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard ret = 0; 3918441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } 3919441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard 39204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) { 39214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr to = exec->comp->states[trans->to]; 39224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 39234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 39244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * this is a multiple input sequence 39254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 39264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->state->nbTrans > exec->transno + 1) { 39274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStackNr <= 0) { 39284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSaveInputString(exec, value, data); 39294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 39314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 1; 39334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard do { 39344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 39354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Try to progress as much as possible on the input 39364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 39374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount == atom->max) { 39384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 39394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index++; 39414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value = exec->inputStack[exec->index].value; 39424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard data = exec->inputStack[exec->index].data; 39434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 39444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("value loaded: %s\n", value); 39454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 39464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 39474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 39484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * End of input: stop here 39494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 39504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (value == NULL) { 39514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index --; 39524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 39534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount >= atom->min) { 39554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int transno = exec->transno; 39564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state = exec->state; 39574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 39584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 39594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The transition is acceptable save it 39604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 39614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = -1; /* trick */ 39624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = to; 39634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStackNr <= 0) { 39644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSaveInputString(exec, value, data); 39654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 39674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = transno; 39684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = state; 39694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlStrEqual(value, atom->valuep); 39714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount++; 39724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } while (ret == 1); 39734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount < atom->min) 39744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 39754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 39764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 39774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * If the last check failed but one transition was found 39784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * possible, rollback 39794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 39804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret < 0) 39814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 39824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 0) { 39834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto rollback; 39844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 1) { 39889887395b556af391306245b52487c215337c4054William M. Brack if ((exec->callback != NULL) && (atom != NULL) && 39899887395b556af391306245b52487c215337c4054William M. Brack (data != NULL)) { 39904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->callback(exec->data, atom->valuep, 39914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->data, data); 39924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->state->nbTrans > exec->transno + 1) { 39944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStackNr <= 0) { 39954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSaveInputString(exec, value, data); 39964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 39984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->counter >= 0) { 40004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 40014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Increasing count %d\n", trans->counter); 40024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 40034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->counts[trans->counter]++; 40044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 400510752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard if ((trans->count >= 0) && 400610752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard (trans->count < REGEXP_ALL_COUNTER)) { 400710752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard#ifdef DEBUG_REGEXP_EXEC 400810752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard printf("resetting count %d on transition\n", 400910752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard trans->count); 401010752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard#endif 401110752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard exec->counts[trans->count] = 0; 401210752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard } 40134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 40144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("entering state %d\n", trans->to); 40154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 4016cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((exec->comp->states[trans->to] != NULL) && 4017cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (exec->comp->states[trans->to]->type == 4018cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_SINK_STATE)) { 4019cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard /* 4020cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * entering a sink state, save the current state as error 4021cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * state. 4022cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard */ 4023cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if (exec->errString != NULL) 4024cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard xmlFree(exec->errString); 4025cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard exec->errString = xmlStrdup(value); 4026cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard exec->errState = exec->state; 4027cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard memcpy(exec->errCounts, exec->counts, 4028cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard exec->comp->nbCounters * sizeof(int)); 4029cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 40304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = exec->comp->states[trans->to]; 40314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = 0; 40324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->atom != NULL) { 40334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStack != NULL) { 40344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index++; 40354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->index < exec->inputStackNr) { 40364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value = exec->inputStack[exec->index].value; 40374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard data = exec->inputStack[exec->index].data; 40384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 40394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("value loaded: %s\n", value); 40404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 40414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 40424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value = NULL; 40434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard data = NULL; 40444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 40454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("end of input\n"); 40464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 40474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 40494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value = NULL; 40504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard data = NULL; 40514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 40524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("end of input\n"); 40534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 40544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto progress; 40574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ret < 0) { 40584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -4; 40594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 40604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((exec->transno != 0) || (exec->state->nbTrans == 0)) { 40634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardrollback: 40649070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard /* 4065cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * if we didn't yet rollback on the current input 4066cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * store the current state as the error state. 40679070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard */ 4068cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((progress) && (exec->state != NULL) && 4069cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (exec->state->type != XML_REGEXP_SINK_STATE)) { 40709070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard progress = 0; 40719070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard if (exec->errString != NULL) 40729070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard xmlFree(exec->errString); 40739070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard exec->errString = xmlStrdup(value); 40749070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard exec->errState = exec->state; 40759070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard memcpy(exec->errCounts, exec->counts, 40769070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard exec->comp->nbCounters * sizeof(int)); 40779070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard } 40789070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard 40794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 40804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Failed to find a way out 40814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 40824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->determinist = 0; 40834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecRollBack(exec); 40844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->status == 0) { 40854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value = exec->inputStack[exec->index].value; 40864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard data = exec->inputStack[exec->index].data; 40874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 40884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("value loaded: %s\n", value); 40894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 40904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40929070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard continue; 40934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardprogress: 40949070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard progress = 1; 40954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 40964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->status == 0) { 40984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(exec->state->type == XML_REGEXP_FINAL_STATE); 40994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 41007bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#ifdef DEBUG_ERR 41019070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard if (exec->status < 0) { 41027bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard testerr(exec); 41037bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 41049070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard#endif 41054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(exec->status); 41064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 41074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 410852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard/** 41096e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * xmlRegExecPushString: 41106e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * @exec: a regexp execution context or NULL to indicate the end 41116e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * @value: a string token input 41126e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * @data: data associated to the token to reuse in callbacks 41136e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * 41146e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * Push one input token in the execution context 41156e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * 41166e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * Returns: 1 if the regexp reached a final state, 0 if non-final, and 41176e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * a negative value in case of error. 41186e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard */ 41196e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillardint 41206e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel VeillardxmlRegExecPushString(xmlRegExecCtxtPtr exec, const xmlChar *value, 41216e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard void *data) { 41226e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard return(xmlRegExecPushStringInternal(exec, value, data, 0)); 41236e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard} 41246e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard 41256e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard/** 412652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * xmlRegExecPushString2: 412752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @exec: a regexp execution context or NULL to indicate the end 412852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @value: the first string token input 412952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @value2: the second string token input 413052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @data: data associated to the token to reuse in callbacks 413152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * 413252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * Push one input token in the execution context 413352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * 413452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * Returns: 1 if the regexp reached a final state, 0 if non-final, and 413552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * a negative value in case of error. 413652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard */ 413752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillardint 413852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel VeillardxmlRegExecPushString2(xmlRegExecCtxtPtr exec, const xmlChar *value, 413952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard const xmlChar *value2, void *data) { 414052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard xmlChar buf[150]; 414152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard int lenn, lenp, ret; 414252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard xmlChar *str; 414352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 414452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (exec == NULL) 414552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(-1); 414652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (exec->comp == NULL) 414752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(-1); 414852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (exec->status != 0) 414952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(exec->status); 415052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 415152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (value2 == NULL) 415252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(xmlRegExecPushString(exec, value, data)); 415352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 415452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard lenn = strlen((char *) value2); 415552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard lenp = strlen((char *) value); 415652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 415752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (150 < lenn + lenp + 2) { 41583c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 415952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (str == NULL) { 416052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard exec->status = -1; 416152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(-1); 416252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard } 416352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard } else { 416452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard str = buf; 416552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard } 416652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard memcpy(&str[0], value, lenp); 4167c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard str[lenp] = XML_REG_STRING_SEPARATOR; 416852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard memcpy(&str[lenp + 1], value2, lenn); 416952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard str[lenn + lenp + 1] = 0; 417052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 417152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (exec->comp->compact != NULL) 417252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard ret = xmlRegCompactPushString(exec, exec->comp, str, data); 417352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard else 41746e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard ret = xmlRegExecPushStringInternal(exec, str, data, 1); 417552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 417652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (str != buf) 41770b1ff14bd0c7c50f8cdce96478615570e1435c4fDaniel Veillard xmlFree(str); 417852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(ret); 417952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard} 418052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 41817bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard/** 418277005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard * xmlRegExecGetValues: 4183fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @exec: a regexp execution context 4184fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @err: error extraction or normal one 41857bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * @nbval: pointer to the number of accepted values IN/OUT 4186cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * @nbneg: return number of negative transitions 41877bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * @values: pointer to the array of acceptable values 4188fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @terminal: return value if this was a terminal state 41897bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * 4190fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * Extract informations from the regexp execution, internal routine to 4191fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * implement xmlRegExecNextValues() and xmlRegExecErrInfo() 41927bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * 41937bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * Returns: 0 in case of success or -1 in case of error. 41947bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard */ 4195fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillardstatic int 4196fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel VeillardxmlRegExecGetValues(xmlRegExecCtxtPtr exec, int err, 4197cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard int *nbval, int *nbneg, 4198cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard xmlChar **values, int *terminal) { 41997bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int maxval; 4200cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard int nb = 0; 42017bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard 4202cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((exec == NULL) || (nbval == NULL) || (nbneg == NULL) || 4203cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (values == NULL) || (*nbval <= 0)) 42047bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard return(-1); 4205fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard 42067bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard maxval = *nbval; 42077bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard *nbval = 0; 4208cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard *nbneg = 0; 42097bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard if ((exec->comp != NULL) && (exec->comp->compact != NULL)) { 42107bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlRegexpPtr comp; 42117bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int target, i, state; 42127bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard 42137bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard comp = exec->comp; 4214fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard 4215fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (err) { 4216fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (exec->errStateNo == -1) return(-1); 4217fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard state = exec->errStateNo; 4218fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } else { 4219fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard state = exec->index; 4220fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } 4221fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (terminal != NULL) { 4222fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (comp->compact[state * (comp->nbstrings + 1)] == 4223fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard XML_REGEXP_FINAL_STATE) 4224fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard *terminal = 1; 4225fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard else 4226fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard *terminal = 0; 4227fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } 4228cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard for (i = 0;(i < comp->nbstrings) && (nb < maxval);i++) { 42297bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard target = comp->compact[state * (comp->nbstrings + 1) + i + 1]; 4230cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((target > 0) && (target <= comp->nbstates) && 4231cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (comp->compact[(target - 1) * (comp->nbstrings + 1)] != 4232cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_SINK_STATE)) { 4233cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard values[nb++] = comp->stringMap[i]; 42347bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard (*nbval)++; 42357bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 42367bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 4237cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard for (i = 0;(i < comp->nbstrings) && (nb < maxval);i++) { 4238cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard target = comp->compact[state * (comp->nbstrings + 1) + i + 1]; 4239cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((target > 0) && (target <= comp->nbstates) && 4240cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (comp->compact[(target - 1) * (comp->nbstrings + 1)] == 4241cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_SINK_STATE)) { 4242cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard values[nb++] = comp->stringMap[i]; 4243cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (*nbneg)++; 4244cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 4245cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 42467bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } else { 42477bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int transno; 42487bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlRegTransPtr trans; 42497bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlRegAtomPtr atom; 4250fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard xmlRegStatePtr state; 4251fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard 4252fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (terminal != NULL) { 4253fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (exec->state->type == XML_REGEXP_FINAL_STATE) 4254fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard *terminal = 1; 4255fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard else 4256fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard *terminal = 0; 4257fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } 42587bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard 4259fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (err) { 4260fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (exec->errState == NULL) return(-1); 4261fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard state = exec->errState; 4262fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } else { 4263fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (exec->state == NULL) return(-1); 4264fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard state = exec->state; 4265fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } 42667bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard for (transno = 0; 4267cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (transno < state->nbTrans) && (nb < maxval); 42687bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard transno++) { 4269fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard trans = &state->trans[transno]; 42707bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard if (trans->to < 0) 42717bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard continue; 42727bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard atom = trans->atom; 42737bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard if ((atom == NULL) || (atom->valuep == NULL)) 42747bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard continue; 42757bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard if (trans->count == REGEXP_ALL_LAX_COUNTER) { 4276cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard /* this should not be reached but ... */ 42777bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard TODO; 42787bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } else if (trans->count == REGEXP_ALL_COUNTER) { 4279cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard /* this should not be reached but ... */ 42807bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard TODO; 42817bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } else if (trans->counter >= 0) { 428211ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard xmlRegCounterPtr counter = NULL; 42837bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int count; 42847bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard 4285fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (err) 4286fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard count = exec->errCounts[trans->counter]; 4287fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard else 4288fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard count = exec->counts[trans->counter]; 428911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (exec->comp != NULL) 429011ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard counter = &exec->comp->counters[trans->counter]; 429111ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if ((counter == NULL) || (count < counter->max)) { 429277005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard if (atom->neg) 429377005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard values[nb++] = (xmlChar *) atom->valuep2; 429477005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard else 429577005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard values[nb++] = (xmlChar *) atom->valuep; 42967bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard (*nbval)++; 42977bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 42987bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } else { 4299cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((exec->comp->states[trans->to] != NULL) && 4300cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (exec->comp->states[trans->to]->type != 4301cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_SINK_STATE)) { 430277005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard if (atom->neg) 430377005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard values[nb++] = (xmlChar *) atom->valuep2; 430477005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard else 430577005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard values[nb++] = (xmlChar *) atom->valuep; 4306cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (*nbval)++; 4307cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 4308cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 4309cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 4310cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard for (transno = 0; 4311cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (transno < state->nbTrans) && (nb < maxval); 4312cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard transno++) { 4313cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard trans = &state->trans[transno]; 4314cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if (trans->to < 0) 4315cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard continue; 4316cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard atom = trans->atom; 4317cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((atom == NULL) || (atom->valuep == NULL)) 4318cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard continue; 4319cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if (trans->count == REGEXP_ALL_LAX_COUNTER) { 4320cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard continue; 4321cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } else if (trans->count == REGEXP_ALL_COUNTER) { 4322cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard continue; 4323cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } else if (trans->counter >= 0) { 4324cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard continue; 4325cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } else { 4326cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((exec->comp->states[trans->to] != NULL) && 4327cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (exec->comp->states[trans->to]->type == 4328cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_SINK_STATE)) { 432977005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard if (atom->neg) 433077005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard values[nb++] = (xmlChar *) atom->valuep2; 433177005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard else 433277005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard values[nb++] = (xmlChar *) atom->valuep; 4333cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (*nbneg)++; 4334cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 43357bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 43367bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 43377bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 43387bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard return(0); 43397bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard} 43407bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard 4341fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard/** 4342fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * xmlRegExecNextValues: 4343fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @exec: a regexp execution context 4344fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @nbval: pointer to the number of accepted values IN/OUT 4345cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * @nbneg: return number of negative transitions 4346fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @values: pointer to the array of acceptable values 4347fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @terminal: return value if this was a terminal state 4348fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * 4349fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * Extract informations from the regexp execution, 4350fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * the parameter @values must point to an array of @nbval string pointers 4351fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * on return nbval will contain the number of possible strings in that 4352fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * state and the @values array will be updated with them. The string values 4353fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * returned will be freed with the @exec context and don't need to be 4354fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * deallocated. 4355fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * 4356fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * Returns: 0 in case of success or -1 in case of error. 4357fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard */ 4358fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillardint 4359cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel VeillardxmlRegExecNextValues(xmlRegExecCtxtPtr exec, int *nbval, int *nbneg, 4360cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard xmlChar **values, int *terminal) { 4361cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard return(xmlRegExecGetValues(exec, 0, nbval, nbneg, values, terminal)); 4362fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard} 4363fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard 4364fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard/** 4365fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * xmlRegExecErrInfo: 4366fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @exec: a regexp execution context generating an error 4367fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @string: return value for the error string 4368fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @nbval: pointer to the number of accepted values IN/OUT 4369cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * @nbneg: return number of negative transitions 4370fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @values: pointer to the array of acceptable values 4371fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @terminal: return value if this was a terminal state 4372fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * 4373fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * Extract error informations from the regexp execution, the parameter 4374fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @string will be updated with the value pushed and not accepted, 4375fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * the parameter @values must point to an array of @nbval string pointers 4376fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * on return nbval will contain the number of possible strings in that 4377fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * state and the @values array will be updated with them. The string values 4378fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * returned will be freed with the @exec context and don't need to be 4379fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * deallocated. 4380fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * 4381fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * Returns: 0 in case of success or -1 in case of error. 4382fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard */ 4383fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillardint 4384fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel VeillardxmlRegExecErrInfo(xmlRegExecCtxtPtr exec, const xmlChar **string, 4385cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard int *nbval, int *nbneg, xmlChar **values, int *terminal) { 4386fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (exec == NULL) 4387fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard return(-1); 4388fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (string != NULL) { 4389fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (exec->status != 0) 4390fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard *string = exec->errString; 4391fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard else 4392fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard *string = NULL; 4393fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } 4394cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard return(xmlRegExecGetValues(exec, 1, nbval, nbneg, values, terminal)); 4395fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard} 4396fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard 43977bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#ifdef DEBUG_ERR 43987bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillardstatic void testerr(xmlRegExecCtxtPtr exec) { 43997bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard const xmlChar *string; 4400cee2b3a5f124e19db46109132c22e1b8faec1c87Daniel Veillard xmlChar *values[5]; 44017bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int nb = 5; 4402cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard int nbneg; 4403fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard int terminal; 4404cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard xmlRegExecErrInfo(exec, &string, &nb, &nbneg, &values[0], &terminal); 44057bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard} 44067bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#endif 44077bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard 44084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#if 0 44094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 44104255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegExecPushChar(xmlRegExecCtxtPtr exec, int UCS) { 44114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegTransPtr trans; 44124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 44134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ret; 44144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int codepoint, len; 44154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec == NULL) 44174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 44184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->status != 0) 44194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(exec->status); 44204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((exec->status == 0) && 44224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ((exec->inputString[exec->index] != 0) || 44234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (exec->state->type != XML_REGEXP_FINAL_STATE))) { 44244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 44264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * End of input on non-terminal state, rollback, however we may 44274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * still have epsilon like transition for counted transitions 44284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * on counters, in that case don't break too early. 44294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 44304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL)) 44314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto rollback; 44324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 0; 44344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (;exec->transno < exec->state->nbTrans;exec->transno++) { 44354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard trans = &exec->state->trans[exec->transno]; 44364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->to < 0) 44374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 44384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom = trans->atom; 44394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 44404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->count >= 0) { 44414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int count; 44424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegCounterPtr counter; 44434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 44454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * A counted transition. 44464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 44474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard count = exec->counts[trans->count]; 44494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard counter = &exec->comp->counters[trans->count]; 44504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 44514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("testing count %d: val %d, min %d, max %d\n", 44524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard trans->count, count, counter->min, counter->max); 44534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 44544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ((count >= counter->min) && (count <= counter->max)); 44554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (atom == NULL) { 44564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(stderr, "epsilon transition left at runtime\n"); 44574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -2; 44584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 44594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (exec->inputString[exec->index] != 0) { 44604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len); 44614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacter(atom, codepoint); 44624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) { 44634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr to = exec->comp->states[trans->to]; 44644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 44664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * this is a multiple input sequence 44674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 44684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->state->nbTrans > exec->transno + 1) { 44694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 44704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 44714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 1; 44724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard do { 44734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 44744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Try to progress as much as possible on the input 44754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 44764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount == atom->max) { 44774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 44784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 44794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index += len; 44804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 44814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * End of input: stop here 44824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 44834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputString[exec->index] == 0) { 44844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index -= len; 44854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 44864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 44874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount >= atom->min) { 44884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int transno = exec->transno; 44894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state = exec->state; 44904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 44924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The transition is acceptable save it 44934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 44944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = -1; /* trick */ 44954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = to; 44964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 44974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = transno; 44984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = state; 44994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), 45014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard len); 45024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacter(atom, codepoint); 45034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount++; 45044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } while (ret == 1); 45054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount < atom->min) 45064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 45074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 45084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 45094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * If the last check failed but one transition was found 45104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * possible, rollback 45114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 45124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret < 0) 45134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 45144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 0) { 45154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto rollback; 45164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 1) { 45204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->state->nbTrans > exec->transno + 1) { 45214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 45224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 452354eb0243c442292953b4a3df39568735039ebc82Daniel Veillard /* 452454eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * restart count for expressions like this ((abc){2})* 452554eb0243c442292953b4a3df39568735039ebc82Daniel Veillard */ 452654eb0243c442292953b4a3df39568735039ebc82Daniel Veillard if (trans->count >= 0) { 452754eb0243c442292953b4a3df39568735039ebc82Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 452854eb0243c442292953b4a3df39568735039ebc82Daniel Veillard printf("Reset count %d\n", trans->count); 452954eb0243c442292953b4a3df39568735039ebc82Daniel Veillard#endif 453054eb0243c442292953b4a3df39568735039ebc82Daniel Veillard exec->counts[trans->count] = 0; 453154eb0243c442292953b4a3df39568735039ebc82Daniel Veillard } 45324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->counter >= 0) { 45334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 45344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Increasing count %d\n", trans->counter); 45354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 45364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->counts[trans->counter]++; 45374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 45394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("entering state %d\n", trans->to); 45404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 45414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = exec->comp->states[trans->to]; 45424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = 0; 45434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->atom != NULL) { 45444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index += len; 45454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto progress; 45474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ret < 0) { 45484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -4; 45494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 45504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((exec->transno != 0) || (exec->state->nbTrans == 0)) { 45534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardrollback: 45544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 45554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Failed to find a way out 45564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 45574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->determinist = 0; 45584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecRollBack(exec); 45594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardprogress: 45614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 45624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 45644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 45654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 45664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 4567ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Parser for the Schemas Datatype Regular Expressions * 45684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#regexs * 45694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 45704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 45714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 45724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 45734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAIsChar: 4574441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 45754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 45764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [10] Char ::= [^.\?*+()|#x5B#x5D] 45774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 45784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 45794255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAIsChar(xmlRegParserCtxtPtr ctxt) { 45804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int cur; 45814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int len; 45824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 45834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR_SCHAR(ctxt->cur, len); 45844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((cur == '.') || (cur == '\\') || (cur == '?') || 45854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == '*') || (cur == '+') || (cur == '(') || 45864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == ')') || (cur == '|') || (cur == 0x5B) || 45874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == 0x5D) || (cur == 0)) 45884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 45894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(cur); 45904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 45914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 45924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 45934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharProp: 4594441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 45954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 45964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [27] charProp ::= IsCategory | IsBlock 45974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [28] IsCategory ::= Letters | Marks | Numbers | Punctuation | 45984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Separators | Symbols | Others 45994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [29] Letters ::= 'L' [ultmo]? 46004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [30] Marks ::= 'M' [nce]? 46014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [31] Numbers ::= 'N' [dlo]? 46024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [32] Punctuation ::= 'P' [cdseifo]? 46034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [33] Separators ::= 'Z' [slp]? 46044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [34] Symbols ::= 'S' [mcko]? 46054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [35] Others ::= 'C' [cfon]? 46064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [36] IsBlock ::= 'Is' [a-zA-Z0-9#x2D]+ 46074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 46084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 46094255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) { 46104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int cur; 4611779af00750fa86045e94422287d67a2cf5723f65William M. Brack xmlRegAtomType type = (xmlRegAtomType) 0; 46124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *blockName = NULL; 46134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 46144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 46154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'L') { 46164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 46184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'u') { 46194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_LETTER_UPPERCASE; 46214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'l') { 46224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_LETTER_LOWERCASE; 46244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 't') { 46254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_LETTER_TITLECASE; 46274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'm') { 46284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_LETTER_MODIFIER; 46304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'o') { 46314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_LETTER_OTHERS; 46334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 46344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_LETTER; 46354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 46364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'M') { 46374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 46394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'n') { 46404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* nonspacing */ 46424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_MARK_NONSPACING; 46434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'c') { 46444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* spacing combining */ 46464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_MARK_SPACECOMBINING; 46474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'e') { 46484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* enclosing */ 46504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_MARK_ENCLOSING; 46514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 46524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* all marks */ 46534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_MARK; 46544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 46554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'N') { 46564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 46584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'd') { 46594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* digital */ 46614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NUMBER_DECIMAL; 46624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'l') { 46634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* letter */ 46654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NUMBER_LETTER; 46664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'o') { 46674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* other */ 46694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NUMBER_OTHERS; 46704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 46714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* all numbers */ 46724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NUMBER; 46734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 46744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'P') { 46754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 46774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'c') { 46784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* connector */ 46804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_CONNECTOR; 46814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'd') { 46824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* dash */ 46844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_DASH; 46854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 's') { 46864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* open */ 46884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_OPEN; 46894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'e') { 46904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* close */ 46924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_CLOSE; 46934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'i') { 46944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* initial quote */ 46964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_INITQUOTE; 46974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'f') { 46984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* final quote */ 47004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_FINQUOTE; 47014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'o') { 47024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* other */ 47044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_OTHERS; 47054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 47064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* all punctuation */ 47074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT; 47084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 47094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'Z') { 47104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 47124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 's') { 47134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* space */ 47154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SEPAR_SPACE; 47164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'l') { 47174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* line */ 47194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SEPAR_LINE; 47204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'p') { 47214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* paragraph */ 47234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SEPAR_PARA; 47244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 47254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* all separators */ 47264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SEPAR; 47274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 47284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'S') { 47294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 47314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'm') { 47324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SYMBOL_MATH; 47344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* math */ 47354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'c') { 47364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SYMBOL_CURRENCY; 47384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* currency */ 47394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'k') { 47404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SYMBOL_MODIFIER; 47424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* modifiers */ 47434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'o') { 47444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SYMBOL_OTHERS; 47464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* other */ 47474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 47484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* all symbols */ 47494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SYMBOL; 47504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 47514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'C') { 47524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 47544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'c') { 47554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* control */ 47574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_OTHER_CONTROL; 47584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'f') { 47594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* format */ 47614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_OTHER_FORMAT; 47624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'o') { 47634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* private use */ 47654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_OTHER_PRIVATE; 47664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'n') { 47674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* not assigned */ 47694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_OTHER_NA; 47704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 47714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* all others */ 47724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_OTHER; 47734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 47744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'I') { 47754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard const xmlChar *start; 47764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 47784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur != 's') { 47794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("IsXXXX expected"); 47804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 47814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 47824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard start = ctxt->cur; 47844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 47854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (((cur >= 'a') && (cur <= 'z')) || 47864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ((cur >= 'A') && (cur <= 'Z')) || 47874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ((cur >= '0') && (cur <= '9')) || 47884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == 0x2D)) { 47894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 47914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while (((cur >= 'a') && (cur <= 'z')) || 47924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ((cur >= 'A') && (cur <= 'Z')) || 47934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ((cur >= '0') && (cur <= '9')) || 47944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == 0x2D)) { 47954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 47974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 47984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 47994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_BLOCK_NAME; 48004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard blockName = xmlStrndup(start, ctxt->cur - start); 48014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 48024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Unknown char property"); 48034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) { 48064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, type); 48074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom != NULL) 48084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->valuep = blockName; 48094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->atom->type == XML_REGEXP_RANGES) { 48104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 48114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type, 0, 0, blockName); 48124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 48144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 48154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 48164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharClassEsc: 4817441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 48184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 48194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [23] charClassEsc ::= ( SingleCharEsc | MultiCharEsc | catEsc | complEsc ) 48204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [24] SingleCharEsc ::= '\' [nrt\|.?*+(){}#x2D#x5B#x5D#x5E] 48214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [25] catEsc ::= '\p{' charProp '}' 48224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [26] complEsc ::= '\P{' charProp '}' 48234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [37] MultiCharEsc ::= '.' | ('\' [sSiIcCdDwW]) 48244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 48254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 48264255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharClassEsc(xmlRegParserCtxtPtr ctxt) { 48274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int cur; 48284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 48294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == '.') { 48304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) { 48314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_ANYCHAR); 48324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->atom->type == XML_REGEXP_RANGES) { 48334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 48344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_ANYCHAR, 0, 0, NULL); 48354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != '\\') { 48404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Escaped sequence: expecting \\"); 48414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 48454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'p') { 48464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != '{') { 48484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Expecting '{'"); 48494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharProp(ctxt); 48534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != '}') { 48544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Expecting '}'"); 48554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'P') { 48594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != '{') { 48614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Expecting '{'"); 48624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharProp(ctxt); 48664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->neg = 1; 48674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != '}') { 48684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Expecting '}'"); 48694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if ((cur == 'n') || (cur == 'r') || (cur == 't') || (cur == '\\') || 48734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == '|') || (cur == '.') || (cur == '?') || (cur == '*') || 48744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == '+') || (cur == '(') || (cur == ')') || (cur == '{') || 48754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == '}') || (cur == 0x2D) || (cur == 0x5B) || (cur == 0x5D) || 48764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == 0x5E)) { 48774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) { 48784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL); 487999c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard if (ctxt->atom != NULL) { 488099c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard switch (cur) { 488199c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard case 'n': 488299c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard ctxt->atom->codepoint = '\n'; 488399c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard break; 488499c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard case 'r': 488599c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard ctxt->atom->codepoint = '\r'; 488699c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard break; 488799c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard case 't': 488899c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard ctxt->atom->codepoint = '\t'; 488999c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard break; 489099c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard default: 489199c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard ctxt->atom->codepoint = cur; 489299c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard } 489399c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard } 48944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->atom->type == XML_REGEXP_RANGES) { 48959543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard switch (cur) { 48969543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard case 'n': 48979543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard cur = '\n'; 48989543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard break; 48999543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard case 'r': 49009543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard cur = '\r'; 49019543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard break; 49029543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard case 't': 49039543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard cur = '\t'; 49049543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard break; 49059543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard } 49064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 49074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_CHARVAL, cur, cur, NULL); 49084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 49094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 49104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if ((cur == 's') || (cur == 'S') || (cur == 'i') || (cur == 'I') || 49114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == 'c') || (cur == 'C') || (cur == 'd') || (cur == 'D') || 49124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == 'w') || (cur == 'W')) { 4913b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlRegAtomType type = XML_REGEXP_ANYSPACE; 49144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 49154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (cur) { 49164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 's': 49174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_ANYSPACE; 49184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 49194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'S': 49204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NOTSPACE; 49214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 49224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'i': 49234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_INITNAME; 49244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 49254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'I': 49264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NOTINITNAME; 49274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 49284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'c': 49294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NAMECHAR; 49304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 49314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'C': 49324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NOTNAMECHAR; 49334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 49344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'd': 49354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_DECIMAL; 49364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 49374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'D': 49384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NOTDECIMAL; 49394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 49404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'w': 49414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_REALCHAR; 49424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 49434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'W': 49444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NOTREALCHAR; 49454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 49464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 49474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 49484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) { 49494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, type); 49504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->atom->type == XML_REGEXP_RANGES) { 49514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 49524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type, 0, 0, NULL); 49534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 4954cb4284e29641aa7dd990d42aba772b7f5c1ab50dDaniel Veillard } else { 4955cb4284e29641aa7dd990d42aba772b7f5c1ab50dDaniel Veillard ERROR("Wrong escape sequence, misuse of character '\\'"); 49564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 49574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 49584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 49594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 49604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharRange: 4961441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 49624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 49634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [17] charRange ::= seRange | XmlCharRef | XmlCharIncDash 49644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [18] seRange ::= charOrEsc '-' charOrEsc 49654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [20] charOrEsc ::= XmlChar | SingleCharEsc 49664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [21] XmlChar ::= [^\#x2D#x5B#x5D] 49674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [22] XmlCharIncDash ::= [^\#x5B#x5D] 49684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 49694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 49704255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharRange(xmlRegParserCtxtPtr ctxt) { 4971dc99df936c74b6ced82904086544fec365d1f219William M. Brack int cur, len; 49724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int start = -1; 49734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int end = -1; 49744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 4975777737ea020106db4d376f2d8b3992198892f29aDaniel Veillard if (CUR == '\0') { 4976777737ea020106db4d376f2d8b3992198892f29aDaniel Veillard ERROR("Expecting ']'"); 4977777737ea020106db4d376f2d8b3992198892f29aDaniel Veillard return; 4978777737ea020106db4d376f2d8b3992198892f29aDaniel Veillard } 4979777737ea020106db4d376f2d8b3992198892f29aDaniel Veillard 49804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 49814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == '\\') { 49824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 49834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 49844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (cur) { 49854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'n': start = 0xA; break; 49864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'r': start = 0xD; break; 49874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 't': start = 0x9; break; 49884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case '\\': case '|': case '.': case '-': case '^': case '?': 49894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case '*': case '+': case '{': case '}': case '(': case ')': 49904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case '[': case ']': 49914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard start = cur; break; 49924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard default: 49934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Invalid escape value"); 49944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 49954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 49964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard end = start; 4997dc99df936c74b6ced82904086544fec365d1f219William M. Brack len = 1; 49984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if ((cur != 0x5B) && (cur != 0x5D)) { 4999dc99df936c74b6ced82904086544fec365d1f219William M. Brack end = start = CUR_SCHAR(ctxt->cur, len); 50004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 50014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Expecting a char range"); 50024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 50034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5004a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack /* 5005a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack * Since we are "inside" a range, we can assume ctxt->cur is past 5006a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack * the start of ctxt->string, and PREV should be safe 5007a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack */ 5008a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack if ((start == '-') && (NXT(1) != ']') && (PREV != '[') && (PREV != '^')) { 5009a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack NEXTL(len); 50104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 50114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5012a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack NEXTL(len); 50134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 501410f1ef4ce875d6affb467f33ab653cd8072e5888William M. Brack if ((cur != '-') || (NXT(1) == ']')) { 50154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 50164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_CHARVAL, start, end, NULL); 50174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 50184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 50194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 50204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 50214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == '\\') { 50224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 50234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 50244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (cur) { 50254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'n': end = 0xA; break; 50264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'r': end = 0xD; break; 50274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 't': end = 0x9; break; 50284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case '\\': case '|': case '.': case '-': case '^': case '?': 50294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case '*': case '+': case '{': case '}': case '(': case ')': 50304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case '[': case ']': 50314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard end = cur; break; 50324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard default: 50334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Invalid escape value"); 50344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 50354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5036dc99df936c74b6ced82904086544fec365d1f219William M. Brack len = 1; 50374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if ((cur != 0x5B) && (cur != 0x5D)) { 5038dc99df936c74b6ced82904086544fec365d1f219William M. Brack end = CUR_SCHAR(ctxt->cur, len); 50394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 50404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Expecting the end of a char range"); 50414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 50424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5043dc99df936c74b6ced82904086544fec365d1f219William M. Brack NEXTL(len); 50444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* TODO check that the values are acceptable character ranges for XML */ 50454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (end < start) { 50464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("End of range is before start of range"); 50474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 50484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 50494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_CHARVAL, start, end, NULL); 50504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 50514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 50524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 50534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 50544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 50554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParsePosCharGroup: 5056441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 50574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 50584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [14] posCharGroup ::= ( charRange | charClassEsc )+ 50594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 50604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 50614255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParsePosCharGroup(xmlRegParserCtxtPtr ctxt) { 50624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard do { 5063041b687e93cc4d5806b902ed3b445a47669dc2adDaniel Veillard if (CUR == '\\') { 50644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharClassEsc(ctxt); 50654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 50664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharRange(ctxt); 50674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 50684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } while ((CUR != ']') && (CUR != '^') && (CUR != '-') && 5069777737ea020106db4d376f2d8b3992198892f29aDaniel Veillard (CUR != 0) && (ctxt->error == 0)); 50704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 50714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 50724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 50734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharGroup: 5074441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 50754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 50764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [13] charGroup ::= posCharGroup | negCharGroup | charClassSub 50774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [15] negCharGroup ::= '^' posCharGroup 50784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [16] charClassSub ::= ( posCharGroup | negCharGroup ) '-' charClassExpr 50794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [12] charClassExpr ::= '[' charGroup ']' 50804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 50814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 50824255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharGroup(xmlRegParserCtxtPtr ctxt) { 50834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int n = ctxt->neg; 50844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((CUR != ']') && (ctxt->error == 0)) { 50854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == '^') { 50864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int neg = ctxt->neg; 50874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 50884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 50894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->neg = !ctxt->neg; 50904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParsePosCharGroup(ctxt); 50914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->neg = neg; 509210f1ef4ce875d6affb467f33ab653cd8072e5888William M. Brack } else if ((CUR == '-') && (NXT(1) == '[')) { 5093f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard int neg = ctxt->neg; 5094f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard ctxt->neg = 2; 509510f1ef4ce875d6affb467f33ab653cd8072e5888William M. Brack NEXT; /* eat the '-' */ 509610f1ef4ce875d6affb467f33ab653cd8072e5888William M. Brack NEXT; /* eat the '[' */ 50974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharGroup(ctxt); 50984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == ']') { 50994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 51004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 51014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("charClassExpr: ']' expected"); 51024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 51034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5104f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard ctxt->neg = neg; 51054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 51064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (CUR != ']') { 51074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParsePosCharGroup(ctxt); 51084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->neg = n; 51114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 51124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 51134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 51144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharClass: 5115441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 51164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 51174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [11] charClass ::= charClassEsc | charClassExpr 51184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [12] charClassExpr ::= '[' charGroup ']' 51194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 51204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 51214255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharClass(xmlRegParserCtxtPtr ctxt) { 51224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == '[') { 51234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 51244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_RANGES); 51254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) 51264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 51274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharGroup(ctxt); 51284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == ']') { 51294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 51304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 51314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("xmlFAParseCharClass: ']' expected"); 51324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 51344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharClassEsc(ctxt); 51354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 51374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 51384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 51394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseQuantExact: 5140441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 51414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 51424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [8] QuantExact ::= [0-9]+ 5143a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard * 5144a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard * Returns 0 if success or -1 in case of error 51454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 51464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 51474255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseQuantExact(xmlRegParserCtxtPtr ctxt) { 51484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ret = 0; 51494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ok = 0; 51504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 51514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 51524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ret * 10 + (CUR - '0'); 51534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ok = 1; 51544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 51554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ok != 1) { 51574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 51584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 51604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 51614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 51624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 51634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseQuantifier: 5164441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 51654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 51664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [4] quantifier ::= [?*+] | ( '{' quantity '}' ) 51674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [5] quantity ::= quantRange | quantMin | QuantExact 51684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [6] quantRange ::= QuantExact ',' QuantExact 51694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [7] quantMin ::= QuantExact ',' 51704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [8] QuantExact ::= [0-9]+ 51714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 51724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 51734255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseQuantifier(xmlRegParserCtxtPtr ctxt) { 51744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int cur; 51754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 51764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 51774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((cur == '?') || (cur == '*') || (cur == '+')) { 51784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom != NULL) { 51794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == '?') 51804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->quant = XML_REGEXP_QUANT_OPT; 51814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else if (cur == '*') 51824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->quant = XML_REGEXP_QUANT_MULT; 51834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else if (cur == '+') 51844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->quant = XML_REGEXP_QUANT_PLUS; 51854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 51874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 51884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == '{') { 51904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int min = 0, max = 0; 51914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 51924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 51934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = xmlFAParseQuantExact(ctxt); 51944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur >= 0) 51954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard min = cur; 51964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == ',') { 51974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 5198ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard if (CUR == '}') 5199ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard max = INT_MAX; 5200ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard else { 5201ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard cur = xmlFAParseQuantExact(ctxt); 5202ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard if (cur >= 0) 5203ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard max = cur; 5204ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard else { 5205ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard ERROR("Improper quantifier"); 5206ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard } 5207ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard } 52084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 52094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == '}') { 52104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 52114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 52124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Unterminated quantifier"); 52134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 52144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (max == 0) 52154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard max = min; 52164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom != NULL) { 52174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->quant = XML_REGEXP_QUANT_RANGE; 52184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->min = min; 52194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->max = max; 52204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 52214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 52224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 52234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 52244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 52254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 52264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 52274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseAtom: 5228441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 52294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 52304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [9] atom ::= Char | charClass | ( '(' regExp ')' ) 52314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 52324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 52334255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseAtom(xmlRegParserCtxtPtr ctxt) { 52344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int codepoint, len; 52354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 52364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard codepoint = xmlFAIsChar(ctxt); 52374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (codepoint > 0) { 52384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL); 52394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) 52404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 52414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard codepoint = CUR_SCHAR(ctxt->cur, len); 52424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->codepoint = codepoint; 52434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXTL(len); 52444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 52454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (CUR == '|') { 52464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 52474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (CUR == 0) { 52484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 52494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (CUR == ')') { 52504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 52514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (CUR == '(') { 525276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegStatePtr start, oldend, start0; 52534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 52544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 525576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* 525676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * this extra Epsilon transition is needed if we count with 0 allowed 525776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * unfortunately this can't be known at that point 525876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard */ 525976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, NULL); 526076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard start0 = ctxt->state; 52614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, NULL); 52624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard start = ctxt->state; 52634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard oldend = ctxt->end; 52644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = NULL; 52654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = NULL; 52664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseRegExp(ctxt, 0); 52674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == ')') { 52684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 52694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 52704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("xmlFAParseAtom: expecting ')'"); 52714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 52724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_SUBREG); 52734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) 52744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 52754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->start = start; 527676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ctxt->atom->start0 = start0; 52774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->stop = ctxt->state; 52784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = oldend; 52794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 52804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if ((CUR == '[') || (CUR == '\\') || (CUR == '.')) { 52814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharClass(ctxt); 52824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 52834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 52844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 52854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 52864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 52874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 52884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParsePiece: 5289441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 52904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 52914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [3] piece ::= atom quantifier? 52924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 52934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 52944255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParsePiece(xmlRegParserCtxtPtr ctxt) { 52954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ret; 52964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 52974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = NULL; 52984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlFAParseAtom(ctxt); 52994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 0) 53004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 53014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) { 53024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("internal: no atom generated"); 53034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 53044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseQuantifier(ctxt); 53054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 53064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 53074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 53084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 53094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseBranch: 5310441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 531154eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * @to: optional target to the end of the branch 531254eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * 531354eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * @to is used to optimize by removing duplicate path in automata 531454eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * in expressions like (a|b)(c|d) 53154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 53164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [2] branch ::= piece* 53174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 5318a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillardstatic int 531954eb0243c442292953b4a3df39568735039ebc82Daniel VeillardxmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) { 53204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr previous; 53214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ret; 53224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 53234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard previous = ctxt->state; 53244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlFAParsePiece(ctxt); 53254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret != 0) { 532654eb0243c442292953b4a3df39568735039ebc82Daniel Veillard if (xmlFAGenerateTransitions(ctxt, previous, 532754eb0243c442292953b4a3df39568735039ebc82Daniel Veillard (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0) 53282cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard return(-1); 53292cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard previous = ctxt->state; 53304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = NULL; 53314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 53324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((ret != 0) && (ctxt->error == 0)) { 53334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlFAParsePiece(ctxt); 53344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret != 0) { 533554eb0243c442292953b4a3df39568735039ebc82Daniel Veillard if (xmlFAGenerateTransitions(ctxt, previous, 533654eb0243c442292953b4a3df39568735039ebc82Daniel Veillard (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0) 5337a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 53384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard previous = ctxt->state; 53394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = NULL; 53404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 53414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5342a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(0); 53434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 53444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 53454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 53464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseRegExp: 5347441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 5348ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * @top: is this the top-level expression ? 53494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 53504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [1] regExp ::= branch ( '|' branch )* 53514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 53524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 53534255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) { 5354c7e3cc49bade82dba0cda4ae7c07ffcd1e32fe25Daniel Veillard xmlRegStatePtr start, end; 53554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 53562cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard /* if not top start should have been generated by an epsilon trans */ 53574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard start = ctxt->state; 53582cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard ctxt->end = NULL; 535954eb0243c442292953b4a3df39568735039ebc82Daniel Veillard xmlFAParseBranch(ctxt, NULL); 53602cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard if (top) { 53612cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 53622cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard printf("State %d is final\n", ctxt->state->no); 53632cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard#endif 53642cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard ctxt->state->type = XML_REGEXP_FINAL_STATE; 53652cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard } 53664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != '|') { 53674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = ctxt->state; 53684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 53694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 53704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard end = ctxt->state; 53714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((CUR == '|') && (ctxt->error == 0)) { 53724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 53734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->state = start; 53742cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard ctxt->end = NULL; 537554eb0243c442292953b4a3df39568735039ebc82Daniel Veillard xmlFAParseBranch(ctxt, end); 53762cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard } 53772cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard if (!top) { 53782cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard ctxt->state = end; 53794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = end; 53804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 53814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 53824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 53834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 53844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 53854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The basic API * 53864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 53874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 53884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 53894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 53904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegexpPrint: 53914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @output: the file for the output debug 53924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @regexp: the compiled regexp 53934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 53944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Print the content of the compiled regular expression 53954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 53964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid 53974255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpPrint(FILE *output, xmlRegexpPtr regexp) { 53984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 53994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 5400a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (output == NULL) 5401a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard return; 54024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " regexp: "); 54034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (regexp == NULL) { 54044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NULL\n"); 54054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 54064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 54074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "'%s' ", regexp->string); 54084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "\n"); 54094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d atoms:\n", regexp->nbAtoms); 54104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < regexp->nbAtoms; i++) { 54114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " %02d ", i); 54124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintAtom(output, regexp->atoms[i]); 54134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 54144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d states:", regexp->nbStates); 54154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "\n"); 54164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < regexp->nbStates; i++) { 54174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintState(output, regexp->states[i]); 54184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 54194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d counters:\n", regexp->nbCounters); 54204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < regexp->nbCounters; i++) { 54214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " %d: min %d max %d\n", i, regexp->counters[i].min, 54224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard regexp->counters[i].max); 54234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 54244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 54254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 54274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegexpCompile: 54284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @regexp: a regular expression string 54294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 54304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Parses a regular expression conforming to XML Schemas Part 2 Datatype 5431ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Appendix F and builds an automata suitable for testing strings against 54324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * that regular expression 54334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 54344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the compiled expression or NULL in case of error 54354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 54364255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpPtr 54374255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpCompile(const xmlChar *regexp) { 54384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegexpPtr ret; 54394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegParserCtxtPtr ctxt; 54404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt = xmlRegNewParserCtxt(regexp); 54424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt == NULL) 54434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 54444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* initialize the parser */ 54464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = NULL; 54474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->start = ctxt->state = xmlRegNewState(ctxt); 54484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePush(ctxt, ctxt->start); 54494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* parse the expression building an automata */ 54514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseRegExp(ctxt, 1); 54524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != 0) { 54534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("xmlFAParseRegExp: extra characters"); 54544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5455cb4284e29641aa7dd990d42aba772b7f5c1ab50dDaniel Veillard if (ctxt->error != 0) { 5456cb4284e29641aa7dd990d42aba772b7f5c1ab50dDaniel Veillard xmlRegFreeParserCtxt(ctxt); 5457cb4284e29641aa7dd990d42aba772b7f5c1ab50dDaniel Veillard return(NULL); 5458cb4284e29641aa7dd990d42aba772b7f5c1ab50dDaniel Veillard } 54594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = ctxt->state; 54604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->start->type = XML_REGEXP_START_STATE; 54614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end->type = XML_REGEXP_FINAL_STATE; 54624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* remove the Epsilon except for counted transitions */ 54644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAEliminateEpsilonTransitions(ctxt); 54654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->error != 0) { 54684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeParserCtxt(ctxt); 54694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 54704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 54714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegEpxFromParse(ctxt); 54724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeParserCtxt(ctxt); 54734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 54744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 54754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 54774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegexpExec: 54784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @comp: the compiled regular expression 54794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @content: the value to check against the regular expression 54804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 5481ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Check if the regular expression generates the value 54824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 5483ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Returns 1 if it matches, 0 if not and a negative value in case of error 54844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 54854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardint 54864255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpExec(xmlRegexpPtr comp, const xmlChar *content) { 54874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((comp == NULL) || (content == NULL)) 54884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 54894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(xmlFARegExec(comp, content)); 54904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 54914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 549323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * xmlRegexpIsDeterminist: 549423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * @comp: the compiled regular expression 549523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * 549623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Check if the regular expression is determinist 549723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * 5498ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Returns 1 if it yes, 0 if not and a negative value in case of error 549923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 550023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillardint 550123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel VeillardxmlRegexpIsDeterminist(xmlRegexpPtr comp) { 550223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlAutomataPtr am; 550323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int ret; 550423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 550523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (comp == NULL) 550623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(-1); 550723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (comp->determinist != -1) 550823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(comp->determinist); 550923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 551023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am = xmlNewAutomata(); 5511bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard if (am->states != NULL) { 5512bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard int i; 5513bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard 5514bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard for (i = 0;i < am->nbStates;i++) 5515bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard xmlRegFreeState(am->states[i]); 5516bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard xmlFree(am->states); 5517bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard } 551823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->nbAtoms = comp->nbAtoms; 551923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->atoms = comp->atoms; 552023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->nbStates = comp->nbStates; 552123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->states = comp->states; 552223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->determinist = -1; 55231ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard am->flags = comp->flags; 552423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret = xmlFAComputesDeterminism(am); 552523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->atoms = NULL; 552623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->states = NULL; 552723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFreeAutomata(am); 55281ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard comp->determinist = ret; 552923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(ret); 553023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard} 553123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 553223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard/** 55334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeRegexp: 55344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @regexp: the regexp 55354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 55364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp 55374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 55384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid 55394255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeRegexp(xmlRegexpPtr regexp) { 55404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 55414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (regexp == NULL) 55424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 55434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 55444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (regexp->string != NULL) 55454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(regexp->string); 55464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (regexp->states != NULL) { 55474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < regexp->nbStates;i++) 55484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeState(regexp->states[i]); 55494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(regexp->states); 55504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 55514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (regexp->atoms != NULL) { 55524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < regexp->nbAtoms;i++) 55534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeAtom(regexp->atoms[i]); 55544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(regexp->atoms); 55554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 55564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (regexp->counters != NULL) 55574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(regexp->counters); 555823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (regexp->compact != NULL) 555923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(regexp->compact); 5560118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if (regexp->transdata != NULL) 5561118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard xmlFree(regexp->transdata); 556223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (regexp->stringMap != NULL) { 556323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0; i < regexp->nbstrings;i++) 556423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(regexp->stringMap[i]); 556523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(regexp->stringMap); 556623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 556723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 55684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(regexp); 55694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 55704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 55714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef LIBXML_AUTOMATA_ENABLED 55724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 55734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 55744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The Automata interface * 55754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * * 55764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 55774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 55784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 55794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlNewAutomata: 55804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 55814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Create a new automata 55824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 55834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new object or NULL in case of failure 55844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 55854255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataPtr 55864255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlNewAutomata(void) { 55874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlAutomataPtr ctxt; 55884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 55894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt = xmlRegNewParserCtxt(NULL); 55904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt == NULL) 55914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 55924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 55934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* initialize the parser */ 55944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = NULL; 55954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->start = ctxt->state = xmlRegNewState(ctxt); 5596a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (ctxt->start == NULL) { 5597a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFreeAutomata(ctxt); 5598a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 5599a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 5600d0271473abc7ca82a22e9a953ec525a6f4b504d5Daniel Veillard ctxt->start->type = XML_REGEXP_START_STATE; 5601a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (xmlRegStatePush(ctxt, ctxt->start) < 0) { 5602a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlRegFreeState(ctxt->start); 5603a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFreeAutomata(ctxt); 5604a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 5605a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 56061ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard ctxt->flags = 0; 56074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ctxt); 56094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 56104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 56124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFreeAutomata: 56134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 56144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 56154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free an automata 56164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 56174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid 56184255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFreeAutomata(xmlAutomataPtr am) { 56194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (am == NULL) 56204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 56214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeParserCtxt(am); 56224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 56234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 5625293416828e1467f877d9dd928f174dcf81b103bcDaniel Veillard * xmlAutomataSetFlags: 56261ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * @am: an automata 56271ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * @flags: a set of internal flags 56281ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * 56291ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * Set some flags on the automata 56301ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard */ 56311ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillardvoid 56321ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel VeillardxmlAutomataSetFlags(xmlAutomataPtr am, int flags) { 56331ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (am == NULL) 56341ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard return; 56351ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard am->flags |= flags; 56361ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard} 56371ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard 56381ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard/** 56394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataGetInitState: 56404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 56414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 5642a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * Initial state lookup 5643a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * 56444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the initial state of the automata 56454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 56464255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr 56474255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataGetInitState(xmlAutomataPtr am) { 56484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (am == NULL) 56494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 56504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(am->start); 56514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 56524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 56544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataSetFinalState: 56554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 56564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @state: a state in this automata 56574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 56584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Makes that state a final state 56594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 56604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns 0 or -1 in case of error 56614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 56624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardint 56634255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataSetFinalState(xmlAutomataPtr am, xmlAutomataStatePtr state) { 56644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((am == NULL) || (state == NULL)) 56654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 56664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->type = XML_REGEXP_FINAL_STATE; 56674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 56684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 56694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 56714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataNewTransition: 56724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 56734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @from: the starting point of the transition 56744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @to: the target point of the transition or NULL 56754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @token: the input string associated to that transition 56764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @data: data passed to the callback function if the transition is activated 56774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 5678ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 56794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * and then adds a transition from the @from state to the target state 56804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * activated by the value of @token 56814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 56824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the target state or NULL in case of error 56834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 56844255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr 56854255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataNewTransition(xmlAutomataPtr am, xmlAutomataStatePtr from, 56864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlAutomataStatePtr to, const xmlChar *token, 56874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard void *data) { 56884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 56894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((am == NULL) || (from == NULL) || (token == NULL)) 56914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 56924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 5693a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (atom == NULL) 5694a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 56954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->data = data; 56964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom == NULL) 56974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 56984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->valuep = xmlStrdup(token); 56994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 5700a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (xmlFAGenerateTransitions(am, from, to, atom) < 0) { 5701a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlRegFreeAtom(atom); 5702a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 5703a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 57044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) 570552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(am->state); 570652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(to); 570752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard} 570852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 570952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard/** 571052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * xmlAutomataNewTransition2: 571152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @am: an automata 571252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @from: the starting point of the transition 571352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @to: the target point of the transition or NULL 571452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @token: the first input string associated to that transition 571552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @token2: the second input string associated to that transition 571652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @data: data passed to the callback function if the transition is activated 571752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * 5718ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 571952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * and then adds a transition from the @from state to the target state 572052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * activated by the value of @token 572152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * 572252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * Returns the target state or NULL in case of error 572352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard */ 572452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel VeillardxmlAutomataStatePtr 572552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel VeillardxmlAutomataNewTransition2(xmlAutomataPtr am, xmlAutomataStatePtr from, 572652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard xmlAutomataStatePtr to, const xmlChar *token, 572752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard const xmlChar *token2, void *data) { 572852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard xmlRegAtomPtr atom; 572952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 573052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if ((am == NULL) || (from == NULL) || (token == NULL)) 573152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(NULL); 573252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 573352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (atom == NULL) 573452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(NULL); 573511ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard atom->data = data; 573652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if ((token2 == NULL) || (*token2 == 0)) { 573752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard atom->valuep = xmlStrdup(token); 573852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard } else { 573952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard int lenn, lenp; 574052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard xmlChar *str; 574152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 574252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard lenn = strlen((char *) token2); 574352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard lenp = strlen((char *) token); 574452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 57453c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 574652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (str == NULL) { 574752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard xmlRegFreeAtom(atom); 574852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(NULL); 574952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard } 575052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard memcpy(&str[0], token, lenp); 575152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard str[lenp] = '|'; 575252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard memcpy(&str[lenp + 1], token2, lenn); 575352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard str[lenn + lenp + 1] = 0; 575452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 575552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard atom->valuep = str; 575652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard } 575752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 5758a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (xmlFAGenerateTransitions(am, from, to, atom) < 0) { 5759a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlRegFreeAtom(atom); 5760a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 5761a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 576252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (to == NULL) 57634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(am->state); 57649efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard return(to); 57659efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard} 57669efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 57679efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard/** 57689efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * xmlAutomataNewNegTrans: 57699efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * @am: an automata 57709efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * @from: the starting point of the transition 57719efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * @to: the target point of the transition or NULL 57729efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * @token: the first input string associated to that transition 57739efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * @token2: the second input string associated to that transition 57749efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * @data: data passed to the callback function if the transition is activated 57759efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * 57769efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * If @to is NULL, this creates first a new target state in the automata 57779efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * and then adds a transition from the @from state to the target state 57789efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * activated by any value except (@token,@token2) 57796e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * Note that if @token2 is not NULL, then (X, NULL) won't match to follow 57806e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard # the semantic of XSD ##other 57819efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * 57829efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * Returns the target state or NULL in case of error 57839efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard */ 57849efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel VeillardxmlAutomataStatePtr 57859efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel VeillardxmlAutomataNewNegTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 57869efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard xmlAutomataStatePtr to, const xmlChar *token, 57879efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard const xmlChar *token2, void *data) { 57889efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard xmlRegAtomPtr atom; 578977005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard xmlChar err_msg[200]; 57909efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 57919efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if ((am == NULL) || (from == NULL) || (token == NULL)) 57929efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard return(NULL); 57939efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 57949efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if (atom == NULL) 57959efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard return(NULL); 57969efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard atom->data = data; 57979efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard atom->neg = 1; 57989efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if ((token2 == NULL) || (*token2 == 0)) { 57999efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard atom->valuep = xmlStrdup(token); 58009efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard } else { 58019efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard int lenn, lenp; 58029efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard xmlChar *str; 58039efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 58049efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard lenn = strlen((char *) token2); 58059efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard lenp = strlen((char *) token); 58069efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 58079efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 58089efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if (str == NULL) { 58099efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard xmlRegFreeAtom(atom); 58109efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard return(NULL); 58119efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard } 58129efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard memcpy(&str[0], token, lenp); 58139efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard str[lenp] = '|'; 58149efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard memcpy(&str[lenp + 1], token2, lenn); 58159efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard str[lenn + lenp + 1] = 0; 58169efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 58179efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard atom->valuep = str; 58189efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard } 5819db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard snprintf((char *) err_msg, 199, "not %s", (const char *) atom->valuep); 582077005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard err_msg[199] = 0; 582177005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard atom->valuep2 = xmlStrdup(err_msg); 58229efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 58239efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if (xmlFAGenerateTransitions(am, from, to, atom) < 0) { 58249efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard xmlRegFreeAtom(atom); 58259efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard return(NULL); 58269efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard } 58276e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard am->negs++; 58289efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if (to == NULL) 58299efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard return(am->state); 58304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(to); 58314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 58324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 58334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 583487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * xmlAutomataNewCountTrans2: 583587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @am: an automata 583687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @from: the starting point of the transition 583787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @to: the target point of the transition or NULL 583887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @token: the input string associated to that transition 583987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @token2: the second input string associated to that transition 584087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @min: the minimum successive occurences of token 584187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @max: the maximum successive occurences of token 584287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @data: data associated to the transition 584387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * 584487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * If @to is NULL, this creates first a new target state in the automata 584587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * and then adds a transition from the @from state to the target state 584687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * activated by a succession of input of value @token and @token2 and 584787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * whose number is between @min and @max 584887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * 584987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * Returns the target state or NULL in case of error 585087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik */ 585187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. BuchcikxmlAutomataStatePtr 585287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. BuchcikxmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, 585387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlAutomataStatePtr to, const xmlChar *token, 585487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik const xmlChar *token2, 585587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik int min, int max, void *data) { 585687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegAtomPtr atom; 585787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik int counter; 585887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 585987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if ((am == NULL) || (from == NULL) || (token == NULL)) 586087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 586187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (min < 0) 586287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 586387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if ((max < min) || (max < 1)) 586487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 586587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 586687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (atom == NULL) 586787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 586887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if ((token2 == NULL) || (*token2 == 0)) { 586987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->valuep = xmlStrdup(token); 587087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } else { 587187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik int lenn, lenp; 587287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlChar *str; 587387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 587487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik lenn = strlen((char *) token2); 587587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik lenp = strlen((char *) token); 587687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 587787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 587887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (str == NULL) { 587987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegFreeAtom(atom); 588087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 588187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } 588287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik memcpy(&str[0], token, lenp); 588387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik str[lenp] = '|'; 588487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik memcpy(&str[lenp + 1], token2, lenn); 588587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik str[lenn + lenp + 1] = 0; 588687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 588787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->valuep = str; 588887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } 588987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->data = data; 589087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (min == 0) 589187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->min = 1; 589287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik else 589387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->min = min; 589487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->max = max; 589587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 589687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik /* 589787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * associate a counter to the transition. 589887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik */ 589987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik counter = xmlRegGetCounter(am); 590087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik am->counters[counter].min = min; 590187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik am->counters[counter].max = max; 590287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 590387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik /* xmlFAGenerateTransitions(am, from, to, atom); */ 590487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (to == NULL) { 590587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik to = xmlRegNewState(am); 590687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegStatePush(am, to); 590787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } 59085de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(am, from, atom, to, counter, -1); 590987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegAtomPush(am, atom); 591087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik am->state = to; 591187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 591287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (to == NULL) 591387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik to = am->state; 591487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (to == NULL) 591587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 591687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (min == 0) 591787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlFAGenerateEpsilonTransition(am, from, to); 591887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(to); 591987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik} 592087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 592187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik/** 59224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataNewCountTrans: 59234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 59244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @from: the starting point of the transition 59254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @to: the target point of the transition or NULL 59264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @token: the input string associated to that transition 59274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @min: the minimum successive occurences of token 5928a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * @max: the maximum successive occurences of token 5929a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * @data: data associated to the transition 59304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 5931ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 59324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * and then adds a transition from the @from state to the target state 59334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * activated by a succession of input of value @token and whose number 59344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * is between @min and @max 59354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 59364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the target state or NULL in case of error 59374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 59384255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr 59394255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 59404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlAutomataStatePtr to, const xmlChar *token, 59414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int min, int max, void *data) { 59424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 59430ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard int counter; 59444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 59454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((am == NULL) || (from == NULL) || (token == NULL)) 59464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 59474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (min < 0) 59484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 59494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((max < min) || (max < 1)) 59504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 59514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 59524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom == NULL) 59534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 59544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->valuep = xmlStrdup(token); 59554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->data = data; 59564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (min == 0) 59574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->min = 1; 59584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else 59594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->min = min; 59604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->max = max; 59614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 59620ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard /* 59630ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard * associate a counter to the transition. 59640ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard */ 59650ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard counter = xmlRegGetCounter(am); 59660ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard am->counters[counter].min = min; 59670ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard am->counters[counter].max = max; 59680ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard 59690ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard /* xmlFAGenerateTransitions(am, from, to, atom); */ 59700ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard if (to == NULL) { 59710ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard to = xmlRegNewState(am); 59720ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard xmlRegStatePush(am, to); 5973a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 59745de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(am, from, atom, to, counter, -1); 59750ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard xmlRegAtomPush(am, atom); 59760ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard am->state = to; 59770ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard 59784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) 59794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to = am->state; 59804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) 59814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 59824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (min == 0) 59834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(am, from, to); 59844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(to); 59854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 59864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 59874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 598887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * xmlAutomataNewOnceTrans2: 598987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @am: an automata 599087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @from: the starting point of the transition 599187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @to: the target point of the transition or NULL 599287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @token: the input string associated to that transition 599387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @token2: the second input string associated to that transition 599487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @min: the minimum successive occurences of token 599587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @max: the maximum successive occurences of token 599687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @data: data associated to the transition 599787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * 599887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * If @to is NULL, this creates first a new target state in the automata 599987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * and then adds a transition from the @from state to the target state 600087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * activated by a succession of input of value @token and @token2 and whose 600187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * number is between @min and @max, moreover that transition can only be 600287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * crossed once. 600387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * 600487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * Returns the target state or NULL in case of error 600587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik */ 600687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. BuchcikxmlAutomataStatePtr 600787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. BuchcikxmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, 600887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlAutomataStatePtr to, const xmlChar *token, 600987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik const xmlChar *token2, 601087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik int min, int max, void *data) { 601187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegAtomPtr atom; 601287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik int counter; 601387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 601487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if ((am == NULL) || (from == NULL) || (token == NULL)) 601587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 601687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (min < 1) 601787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 601887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if ((max < min) || (max < 1)) 601987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 602087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 602187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (atom == NULL) 602287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 602387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if ((token2 == NULL) || (*token2 == 0)) { 602487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->valuep = xmlStrdup(token); 602587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } else { 602687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik int lenn, lenp; 602787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlChar *str; 602887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 602987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik lenn = strlen((char *) token2); 603087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik lenp = strlen((char *) token); 603187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 603287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 603387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (str == NULL) { 603487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegFreeAtom(atom); 603587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 603687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } 603787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik memcpy(&str[0], token, lenp); 603887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik str[lenp] = '|'; 603987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik memcpy(&str[lenp + 1], token2, lenn); 604087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik str[lenn + lenp + 1] = 0; 604187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 604287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->valuep = str; 604387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } 604487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->data = data; 604587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->quant = XML_REGEXP_QUANT_ONCEONLY; 604611ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard atom->min = min; 604787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->max = max; 604887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik /* 604987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * associate a counter to the transition. 605087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik */ 605187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik counter = xmlRegGetCounter(am); 605287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik am->counters[counter].min = 1; 605387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik am->counters[counter].max = 1; 605487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 605587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik /* xmlFAGenerateTransitions(am, from, to, atom); */ 605687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (to == NULL) { 605787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik to = xmlRegNewState(am); 605887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegStatePush(am, to); 605987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } 60605de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(am, from, atom, to, counter, -1); 606187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegAtomPush(am, atom); 606287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik am->state = to; 606387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(to); 606487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik} 606587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 606687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 606787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 606887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik/** 60697646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * xmlAutomataNewOnceTrans: 60707646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @am: an automata 60717646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @from: the starting point of the transition 60727646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @to: the target point of the transition or NULL 60737646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @token: the input string associated to that transition 60747646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @min: the minimum successive occurences of token 6075a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * @max: the maximum successive occurences of token 6076a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * @data: data associated to the transition 60777646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * 6078ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 60797646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * and then adds a transition from the @from state to the target state 60807646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * activated by a succession of input of value @token and whose number 6081ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * is between @min and @max, moreover that transition can only be crossed 60827646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * once. 60837646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * 60847646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * Returns the target state or NULL in case of error 60857646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard */ 60867646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlAutomataStatePtr 60877646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 60887646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard xmlAutomataStatePtr to, const xmlChar *token, 60897646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard int min, int max, void *data) { 60907646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard xmlRegAtomPtr atom; 60917646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard int counter; 60927646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard 60937646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if ((am == NULL) || (from == NULL) || (token == NULL)) 60947646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(NULL); 60957646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if (min < 1) 60967646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(NULL); 60977646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if ((max < min) || (max < 1)) 60987646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(NULL); 60997646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 61007646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if (atom == NULL) 61017646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(NULL); 61027646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard atom->valuep = xmlStrdup(token); 61037646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard atom->data = data; 61047646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCEONLY; 610511ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard atom->min = min; 61067646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard atom->max = max; 61077646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard /* 61087646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * associate a counter to the transition. 61097646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard */ 61107646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard counter = xmlRegGetCounter(am); 61117646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard am->counters[counter].min = 1; 61127646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard am->counters[counter].max = 1; 61137646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard 61147646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard /* xmlFAGenerateTransitions(am, from, to, atom); */ 61157646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if (to == NULL) { 61167646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard to = xmlRegNewState(am); 61177646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard xmlRegStatePush(am, to); 61187646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard } 61195de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(am, from, atom, to, counter, -1); 61207646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard xmlRegAtomPush(am, atom); 61217646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard am->state = to; 61227646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(to); 61237646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard} 61247646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard 61257646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard/** 61264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataNewState: 61274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 61284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 61294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Create a new disconnected state in the automata 61304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 61314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new state or NULL in case of error 61324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 61334255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr 61344255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataNewState(xmlAutomataPtr am) { 61354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlAutomataStatePtr to; 61364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 61374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (am == NULL) 61384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 61394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to = xmlRegNewState(am); 61404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePush(am, to); 61414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(to); 61424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 61434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 61444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 6145a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * xmlAutomataNewEpsilon: 61464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 61474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @from: the starting point of the transition 61484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @to: the target point of the transition or NULL 61494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 6150ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 6151ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * and then adds an epsilon transition from the @from state to the 61524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * target state 61534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 61544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the target state or NULL in case of error 61554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 61564255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr 61574255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataNewEpsilon(xmlAutomataPtr am, xmlAutomataStatePtr from, 61584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlAutomataStatePtr to) { 61594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((am == NULL) || (from == NULL)) 61604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 61614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(am, from, to); 61624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) 61634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(am->state); 61644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(to); 61654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 61664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 6167b509f1543df71549969eeac076349e05d2f78044Daniel Veillard/** 61687646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * xmlAutomataNewAllTrans: 61697646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @am: an automata 61707646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @from: the starting point of the transition 61717646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @to: the target point of the transition or NULL 6172a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * @lax: allow to transition if not all all transitions have been activated 61737646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * 6174ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 61757646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * and then adds a an ALL transition from the @from state to the 61767646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * target state. That transition is an epsilon transition allowed only when 61777646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * all transitions from the @from node have been activated. 61787646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * 61797646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * Returns the target state or NULL in case of error 61807646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard */ 61817646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlAutomataStatePtr 61827646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlAutomataNewAllTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 6183441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard xmlAutomataStatePtr to, int lax) { 61847646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if ((am == NULL) || (from == NULL)) 61857646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(NULL); 6186441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard xmlFAGenerateAllTransition(am, from, to, lax); 61877646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if (to == NULL) 61887646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(am->state); 61897646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(to); 61907646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard} 61917646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard 61927646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard/** 6193b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * xmlAutomataNewCounter: 6194b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @am: an automata 6195b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @min: the minimal value on the counter 6196b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @max: the maximal value on the counter 6197b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * 6198b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * Create a new counter 6199b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * 6200b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * Returns the counter number or -1 in case of error 6201b509f1543df71549969eeac076349e05d2f78044Daniel Veillard */ 6202b509f1543df71549969eeac076349e05d2f78044Daniel Veillardint 6203b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataNewCounter(xmlAutomataPtr am, int min, int max) { 6204b509f1543df71549969eeac076349e05d2f78044Daniel Veillard int ret; 6205b509f1543df71549969eeac076349e05d2f78044Daniel Veillard 6206b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (am == NULL) 6207b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(-1); 6208b509f1543df71549969eeac076349e05d2f78044Daniel Veillard 6209b509f1543df71549969eeac076349e05d2f78044Daniel Veillard ret = xmlRegGetCounter(am); 6210b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (ret < 0) 6211b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(-1); 6212b509f1543df71549969eeac076349e05d2f78044Daniel Veillard am->counters[ret].min = min; 6213b509f1543df71549969eeac076349e05d2f78044Daniel Veillard am->counters[ret].max = max; 6214b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(ret); 6215b509f1543df71549969eeac076349e05d2f78044Daniel Veillard} 6216b509f1543df71549969eeac076349e05d2f78044Daniel Veillard 6217b509f1543df71549969eeac076349e05d2f78044Daniel Veillard/** 6218b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * xmlAutomataNewCountedTrans: 6219b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @am: an automata 6220b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @from: the starting point of the transition 6221b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @to: the target point of the transition or NULL 6222b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @counter: the counter associated to that transition 6223b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * 6224ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 6225b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * and then adds an epsilon transition from the @from state to the target state 6226b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * which will increment the counter provided 6227b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * 6228b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * Returns the target state or NULL in case of error 6229b509f1543df71549969eeac076349e05d2f78044Daniel Veillard */ 6230b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataStatePtr 6231b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataNewCountedTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 6232b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlAutomataStatePtr to, int counter) { 6233b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if ((am == NULL) || (from == NULL) || (counter < 0)) 6234b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(NULL); 6235b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlFAGenerateCountedEpsilonTransition(am, from, to, counter); 6236b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (to == NULL) 6237b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(am->state); 6238b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(to); 6239b509f1543df71549969eeac076349e05d2f78044Daniel Veillard} 6240b509f1543df71549969eeac076349e05d2f78044Daniel Veillard 6241b509f1543df71549969eeac076349e05d2f78044Daniel Veillard/** 6242b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * xmlAutomataNewCounterTrans: 6243b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @am: an automata 6244b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @from: the starting point of the transition 6245b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @to: the target point of the transition or NULL 6246b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @counter: the counter associated to that transition 6247b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * 6248ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 6249b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * and then adds an epsilon transition from the @from state to the target state 6250b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * which will be allowed only if the counter is within the right range. 6251b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * 6252b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * Returns the target state or NULL in case of error 6253b509f1543df71549969eeac076349e05d2f78044Daniel Veillard */ 6254b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataStatePtr 6255b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataNewCounterTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 6256b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlAutomataStatePtr to, int counter) { 6257b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if ((am == NULL) || (from == NULL) || (counter < 0)) 6258b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(NULL); 6259b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlFAGenerateCountedTransition(am, from, to, counter); 6260b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (to == NULL) 6261b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(am->state); 6262b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(to); 6263b509f1543df71549969eeac076349e05d2f78044Daniel Veillard} 62644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 62654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 62664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataCompile: 62674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 62684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 62694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Compile the automata into a Reg Exp ready for being executed. 62704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The automata should be free after this point. 62714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 62724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the compiled regexp or NULL in case of error 62734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 62744255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpPtr 62754255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataCompile(xmlAutomataPtr am) { 62764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegexpPtr ret; 62774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 6278a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if ((am == NULL) || (am->error != 0)) return(NULL); 62794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAEliminateEpsilonTransitions(am); 628023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* xmlFAComputesDeterminism(am); */ 62814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegEpxFromParse(am); 62824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 62834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 62844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 6285e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 6286e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard/** 6287e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * xmlAutomataIsDeterminist: 6288e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * @am: an automata 6289e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 6290e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * Checks if an automata is determinist. 6291e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 6292e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * Returns 1 if true, 0 if not, and -1 in case of error 6293e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 6294e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillardint 6295e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel VeillardxmlAutomataIsDeterminist(xmlAutomataPtr am) { 6296e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int ret; 6297e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 6298e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (am == NULL) 6299e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(-1); 6300e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 6301e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard ret = xmlFAComputesDeterminism(am); 6302e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(ret); 6303e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard} 63044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif /* LIBXML_AUTOMATA_ENABLED */ 630581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 630681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef LIBXML_EXPR_ENABLED 630781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/************************************************************************ 630881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 630981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Formal Expression handling code * 631081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 631181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ************************************************************************/ 631281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/************************************************************************ 631381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 631481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Expression handling context * 631581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 631681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ************************************************************************/ 631781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 631881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstruct _xmlExpCtxt { 631981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlDictPtr dict; 632081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr *table; 632181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int size; 632281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int nbElems; 632381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int nb_nodes; 6324594e5dfb48ee6fbac1b64155839063648022fc57Daniel Veillard int maxNodes; 632581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const char *expr; 632681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const char *cur; 632781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int nb_cons; 632881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int tabSize; 632981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard}; 633081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 633181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 633281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpNewCtxt: 633381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @maxNodes: the maximum number of nodes 633481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @dict: optional dictionnary to use internally 633581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 633681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Creates a new context for manipulating expressions 633781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 633881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the context or NULL in case of error 633981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 634081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpCtxtPtr 634181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpNewCtxt(int maxNodes, xmlDictPtr dict) { 634281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpCtxtPtr ret; 634381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int size = 256; 634481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 634581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (maxNodes <= 4096) 634681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard maxNodes = 4096; 634781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 634881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = (xmlExpCtxtPtr) xmlMalloc(sizeof(xmlExpCtxt)); 634981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) 635081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 635181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard memset(ret, 0, sizeof(xmlExpCtxt)); 635281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->size = size; 635381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->nbElems = 0; 6354594e5dfb48ee6fbac1b64155839063648022fc57Daniel Veillard ret->maxNodes = maxNodes; 635581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->table = xmlMalloc(size * sizeof(xmlExpNodePtr)); 635681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret->table == NULL) { 635781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlFree(ret); 635881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 635981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 636081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard memset(ret->table, 0, size * sizeof(xmlExpNodePtr)); 636181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (dict == NULL) { 636281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->dict = xmlDictCreate(); 636381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret->dict == NULL) { 636481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlFree(ret->table); 636581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlFree(ret); 636681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 636781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 636881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 636981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->dict = dict; 637081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlDictReference(ret->dict); 637181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 637281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 637381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 637481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 637581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 637681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpFreeCtxt: 637781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: an expression context 637881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 637981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Free an expression context 638081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 638181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardvoid 638281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpFreeCtxt(xmlExpCtxtPtr ctxt) { 638381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt == NULL) 638481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return; 638581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlDictFree(ctxt->dict); 638681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt->table != NULL) 638781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlFree(ctxt->table); 638881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlFree(ctxt); 638981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 639081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 639181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/************************************************************************ 639281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 639381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Structure associated to an expression node * 639481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 639581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ************************************************************************/ 6396465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#define MAX_NODES 10000 6397465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 6398465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/* #define DEBUG_DERIV */ 6399465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 6400465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/* 6401465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * TODO: 6402465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - Wildcards 6403465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - public API for creation 6404465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 6405465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Started 6406465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - regression testing 6407465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 6408465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Done 6409465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - split into module and test tool 6410465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - memleaks 6411465a000b1080427bd62d89a925409b7db78616acDaniel Veillard */ 641281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 641381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardtypedef enum { 641481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard XML_EXP_NILABLE = (1 << 0) 641581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} xmlExpNodeInfo; 641681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 641781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#define IS_NILLABLE(node) ((node)->info & XML_EXP_NILABLE) 641881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 641981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstruct _xmlExpNode { 642081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned char type;/* xmlExpNodeType */ 642181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned char info;/* OR of xmlExpNodeInfo */ 642281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned short key; /* the hash key */ 642381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned int ref; /* The number of references */ 642481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int c_max; /* the maximum length it can consume */ 642581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr exp_left; 642681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr next;/* the next node in the hash table or free list */ 642781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard union { 642881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard struct { 642981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int f_min; 643081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int f_max; 643181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } count; 643281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard struct { 643381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr f_right; 643481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } children; 643581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar *f_str; 643681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } field; 643781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard}; 643881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 643981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#define exp_min field.count.f_min 644081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#define exp_max field.count.f_max 644181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/* #define exp_left field.children.f_left */ 644281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#define exp_right field.children.f_right 644381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#define exp_str field.f_str 644481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 644581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNodePtr xmlExpNewNode(xmlExpCtxtPtr ctxt, xmlExpNodeType type); 644681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNode forbiddenExpNode = { 644781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard XML_EXP_FORBID, 0, 0, 0, 0, NULL, NULL, {{ 0, 0}} 644881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard}; 644981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpNodePtr forbiddenExp = &forbiddenExpNode; 645081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNode emptyExpNode = { 645181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard XML_EXP_EMPTY, 1, 0, 0, 0, NULL, NULL, {{ 0, 0}} 645281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard}; 645381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpNodePtr emptyExp = &emptyExpNode; 645481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 645581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/************************************************************************ 645681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 645781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * The custom hash table for unicity and canonicalization * 645881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * of sub-expressions pointers * 645981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 646081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ************************************************************************/ 646181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/* 646281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpHashNameComputeKey: 646381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Calculate the hash key for a token 646481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 646581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic unsigned short 646681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpHashNameComputeKey(const xmlChar *name) { 646781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned short value = 0L; 646881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard char ch; 646981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 647081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (name != NULL) { 647181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value += 30 * (*name); 647281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard while ((ch = *name++) != 0) { 647381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); 647481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 647581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 647681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return (value); 647781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 647881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 647981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/* 648081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpHashComputeKey: 648181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Calculate the hash key for a compound expression 648281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 648381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic unsigned short 648481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpHashComputeKey(xmlExpNodeType type, xmlExpNodePtr left, 648581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr right) { 648681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned long value; 648781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned short ret; 648881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 648981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard switch (type) { 649081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_SEQ: 649181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value = left->key; 649281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value += right->key; 649381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value *= 3; 649481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = (unsigned short) value; 649581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard break; 649681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_OR: 649781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value = left->key; 649881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value += right->key; 649981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value *= 7; 650081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = (unsigned short) value; 650181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard break; 650281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_COUNT: 650381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value = left->key; 650481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value += right->key; 650581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = (unsigned short) value; 650681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard break; 650781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard default: 650881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = 0; 650981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 651081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 651181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 651281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 651381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 651481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNodePtr 651581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpNewNode(xmlExpCtxtPtr ctxt, xmlExpNodeType type) { 651681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr ret; 651781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 651881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt->nb_nodes >= MAX_NODES) 651981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 652081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = (xmlExpNodePtr) xmlMalloc(sizeof(xmlExpNode)); 652181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) 652281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 652381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard memset(ret, 0, sizeof(xmlExpNode)); 652481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->type = type; 652581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->next = NULL; 652681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->nb_nodes++; 652781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->nb_cons++; 652881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 652981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 653081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 653181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 653281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpHashGetEntry: 653381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @table: the hash table 653481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 653581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Get the unique entry from the hash table. The entry is created if 653681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * needed. @left and @right are consumed, i.e. their ref count will 653781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * be decremented by the operation. 653881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 653981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the pointer or NULL in case of error 654081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 654181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNodePtr 654281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpHashGetEntry(xmlExpCtxtPtr ctxt, xmlExpNodeType type, 654381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr left, xmlExpNodePtr right, 654481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar *name, int min, int max) { 654581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned short kbase, key; 654681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr entry; 654781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr insert; 654881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 654981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt == NULL) 655081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 655181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 655281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 655381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Check for duplicate and insertion location. 655481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 655581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (type == XML_EXP_ATOM) { 655681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard kbase = xmlExpHashNameComputeKey(name); 655781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (type == XML_EXP_COUNT) { 655881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* COUNT reduction rule 1 */ 655981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* a{1} -> a */ 656081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (min == max) { 656181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (min == 1) { 656281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(left); 656381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 656481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (min == 0) { 656581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, left); 656681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(emptyExp); 656781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 656881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 656981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (min < 0) { 657081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, left); 657181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 657281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 657381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (max == -1) 657481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard kbase = min + 79; 657581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 657681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard kbase = max - min; 657781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard kbase += left->key; 657881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (type == XML_EXP_OR) { 657981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Forbid reduction rules */ 658081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left->type == XML_EXP_FORBID) { 658181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, left); 658281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(right); 658381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 658481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (right->type == XML_EXP_FORBID) { 658581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, right); 658681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(left); 658781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 658881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 658981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* OR reduction rule 1 */ 659081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* a | a reduced to a */ 659181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left == right) { 659281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->ref--; 659381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(left); 659481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 659581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* OR canonicalization rule 1 */ 659681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* linearize (a | b) | c into a | (b | c) */ 659781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((left->type == XML_EXP_OR) && (right->type != XML_EXP_OR)) { 659881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp = left; 659981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left = right; 660081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right = tmp; 660181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 660281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* OR reduction rule 2 */ 660381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* a | (a | b) and b | (a | b) are reduced to a | b */ 660481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (right->type == XML_EXP_OR) { 660581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((left == right->exp_left) || 660681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (left == right->exp_right)) { 660781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, left); 660881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(right); 660981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 661081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 661181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* OR canonicalization rule 2 */ 661281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* linearize (a | b) | c into a | (b | c) */ 661381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left->type == XML_EXP_OR) { 661481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 661581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 661681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* OR canonicalization rule 2 */ 661781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((left->exp_right->type != XML_EXP_OR) && 661881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (left->exp_right->key < left->exp_left->key)) { 661981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = left->exp_right; 662081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->exp_right = left->exp_left; 662181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->exp_left = tmp; 662281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 662381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->exp_right->ref++; 662481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left->exp_right, right, 662581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0); 662681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->exp_left->ref++; 662781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left->exp_left, tmp, 662881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0); 662981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 663081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, left); 663181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 663281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 663381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (right->type == XML_EXP_OR) { 663481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Ordering in the tree */ 663581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* C | (A | B) -> A | (B | C) */ 663681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left->key > right->exp_right->key) { 663781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 663881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right->exp_right->ref++; 663981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_right, 664081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left, NULL, 0, 0); 664181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right->exp_left->ref++; 664281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_left, 664381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp, NULL, 0, 0); 664481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, right); 664581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 664681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 664781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Ordering in the tree */ 664881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* B | (A | C) -> A | (B | C) */ 664981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left->key > right->exp_left->key) { 665081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 665181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right->exp_right->ref++; 665281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left, 665381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right->exp_right, NULL, 0, 0); 665481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right->exp_left->ref++; 665581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_left, 665681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp, NULL, 0, 0); 665781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, right); 665881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 665981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 666081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 666181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* we know both types are != XML_EXP_OR here */ 666281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else if (left->key > right->key) { 666381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp = left; 666481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left = right; 666581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right = tmp; 666681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 666781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard kbase = xmlExpHashComputeKey(type, left, right); 666881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (type == XML_EXP_SEQ) { 666981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Forbid reduction rules */ 667081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left->type == XML_EXP_FORBID) { 667181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, right); 667281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(left); 667381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 667481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (right->type == XML_EXP_FORBID) { 667581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, left); 667681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(right); 667781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 667881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Empty reduction rules */ 667981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (right->type == XML_EXP_EMPTY) { 668081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(left); 668181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 668281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left->type == XML_EXP_EMPTY) { 668381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(right); 668481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 668581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard kbase = xmlExpHashComputeKey(type, left, right); 668681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else 668781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 668881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 668981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard key = kbase % ctxt->size; 669081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt->table[key] != NULL) { 669181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard for (insert = ctxt->table[key]; insert != NULL; 669281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard insert = insert->next) { 669381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((insert->key == kbase) && 669481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (insert->type == type)) { 669581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (type == XML_EXP_ATOM) { 669681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (name == insert->exp_str) { 669781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard insert->ref++; 669881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(insert); 669981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 670081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (type == XML_EXP_COUNT) { 670181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((insert->exp_min == min) && (insert->exp_max == max) && 670281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (insert->exp_left == left)) { 670381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard insert->ref++; 670481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->ref--; 670581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(insert); 670681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 670781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if ((insert->exp_left == left) && 670881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (insert->exp_right == right)) { 670981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard insert->ref++; 671081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->ref--; 671181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right->ref--; 671281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(insert); 671381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 671481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 671581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 671681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 671781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 671881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry = xmlExpNewNode(ctxt, type); 671981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (entry == NULL) 672081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 672181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->key = kbase; 672281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (type == XML_EXP_ATOM) { 672381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->exp_str = name; 672481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = 1; 672581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (type == XML_EXP_COUNT) { 672681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->exp_min = min; 672781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->exp_max = max; 672881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->exp_left = left; 672981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((min == 0) || (IS_NILLABLE(left))) 673081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->info |= XML_EXP_NILABLE; 673181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (max < 0) 673281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = -1; 673381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 673481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = max * entry->exp_left->c_max; 673581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 673681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->exp_left = left; 673781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->exp_right = right; 673881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (type == XML_EXP_OR) { 673981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((IS_NILLABLE(left)) || (IS_NILLABLE(right))) 674081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->info |= XML_EXP_NILABLE; 674181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((entry->exp_left->c_max == -1) || 674281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (entry->exp_right->c_max == -1)) 674381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = -1; 674481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else if (entry->exp_left->c_max > entry->exp_right->c_max) 674581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = entry->exp_left->c_max; 674681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 674781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = entry->exp_right->c_max; 674881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 674981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((IS_NILLABLE(left)) && (IS_NILLABLE(right))) 675081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->info |= XML_EXP_NILABLE; 675181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((entry->exp_left->c_max == -1) || 675281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (entry->exp_right->c_max == -1)) 675381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = -1; 675481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 675581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = entry->exp_left->c_max + entry->exp_right->c_max; 675681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 675781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 675881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->ref = 1; 675981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt->table[key] != NULL) 676081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->next = ctxt->table[key]; 676181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 676281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->table[key] = entry; 676381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->nbElems++; 676481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 676581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(entry); 676681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 676781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 676881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 676981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpFree: 677081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expression context 677181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the expression 677281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 677381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Dereference the expression 677481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 677581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardvoid 677681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpFree(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp) { 677781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((exp == NULL) || (exp == forbiddenExp) || (exp == emptyExp)) 677881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return; 677981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->ref--; 678081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->ref == 0) { 678181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned short key; 678281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 678381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Unlink it first from the hash table */ 678481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard key = exp->key % ctxt->size; 678581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt->table[key] == exp) { 678681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->table[key] = exp->next; 678781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 678881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 678981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 679081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = ctxt->table[key]; 679181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard while (tmp != NULL) { 679281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp->next == exp) { 679381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp->next = exp->next; 679481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard break; 679581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 679681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = tmp->next; 679781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 679881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 679981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 680081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((exp->type == XML_EXP_SEQ) || (exp->type == XML_EXP_OR)) { 680181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, exp->exp_left); 680281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, exp->exp_right); 680381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (exp->type == XML_EXP_COUNT) { 680481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, exp->exp_left); 680581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 680681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlFree(exp); 680781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->nb_nodes--; 680881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 680981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 681081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 681181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 681281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpRef: 681381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the expression 681481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 681581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Increase the reference count of the expression 681681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 681781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardvoid 681881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpRef(xmlExpNodePtr exp) { 681981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp != NULL) 682081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->ref++; 682181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 682281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 6823ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard/** 6824ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * xmlExpNewAtom: 6825ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @ctxt: the expression context 6826ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @name: the atom name 6827ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @len: the atom name lenght in byte (or -1); 6828ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6829ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Get the atom associated to this name from that context 6830ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6831ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Returns the node or NULL in case of error 6832ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard */ 6833ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNodePtr 6834ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNewAtom(xmlExpCtxtPtr ctxt, const xmlChar *name, int len) { 6835ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard if ((ctxt == NULL) || (name == NULL)) 6836ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(NULL); 6837ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard name = xmlDictLookup(ctxt->dict, name, len); 6838ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard if (name == NULL) 6839ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(NULL); 6840ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_ATOM, NULL, NULL, name, 0, 0)); 6841ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard} 6842ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard 6843ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard/** 6844ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * xmlExpNewOr: 6845ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @ctxt: the expression context 6846ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @left: left expression 6847ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @right: right expression 6848ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6849ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Get the atom associated to the choice @left | @right 6850ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Note that @left and @right are consumed in the operation, to keep 6851ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * an handle on them use xmlExpRef() and use xmlExpFree() to release them, 6852ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * this is true even in case of failure (unless ctxt == NULL). 6853ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6854ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Returns the node or NULL in case of error 6855ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard */ 6856ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNodePtr 6857ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNewOr(xmlExpCtxtPtr ctxt, xmlExpNodePtr left, xmlExpNodePtr right) { 685811ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (ctxt == NULL) 685911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard return(NULL); 686011ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if ((left == NULL) || (right == NULL)) { 6861ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard xmlExpFree(ctxt, left); 6862ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard xmlExpFree(ctxt, right); 6863ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(NULL); 6864ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard } 6865ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, left, right, NULL, 0, 0)); 6866ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard} 6867ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard 6868ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard/** 6869ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * xmlExpNewSeq: 6870ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @ctxt: the expression context 6871ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @left: left expression 6872ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @right: right expression 6873ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6874ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Get the atom associated to the sequence @left , @right 6875ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Note that @left and @right are consumed in the operation, to keep 6876ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * an handle on them use xmlExpRef() and use xmlExpFree() to release them, 6877ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * this is true even in case of failure (unless ctxt == NULL). 6878ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6879ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Returns the node or NULL in case of error 6880ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard */ 6881ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNodePtr 6882ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNewSeq(xmlExpCtxtPtr ctxt, xmlExpNodePtr left, xmlExpNodePtr right) { 688311ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (ctxt == NULL) 688411ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard return(NULL); 688511ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if ((left == NULL) || (right == NULL)) { 6886ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard xmlExpFree(ctxt, left); 6887ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard xmlExpFree(ctxt, right); 6888ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(NULL); 6889ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard } 6890ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, left, right, NULL, 0, 0)); 6891ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard} 6892ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard 6893ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard/** 6894ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * xmlExpNewRange: 6895ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @ctxt: the expression context 6896ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @subset: the expression to be repeated 6897ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @min: the lower bound for the repetition 6898ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @max: the upper bound for the repetition, -1 means infinite 6899ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6900ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Get the atom associated to the range (@subset){@min, @max} 6901ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Note that @subset is consumed in the operation, to keep 6902ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * an handle on it use xmlExpRef() and use xmlExpFree() to release it, 6903ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * this is true even in case of failure (unless ctxt == NULL). 6904ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6905ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Returns the node or NULL in case of error 6906ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard */ 6907ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNodePtr 6908ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNewRange(xmlExpCtxtPtr ctxt, xmlExpNodePtr subset, int min, int max) { 690911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (ctxt == NULL) 691011ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard return(NULL); 691111ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if ((subset == NULL) || (min < 0) || (max < -1) || 6912ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard ((max >= 0) && (min > max))) { 6913ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard xmlExpFree(ctxt, subset); 6914ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(NULL); 6915ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard } 6916ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, subset, 6917ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard NULL, NULL, min, max)); 6918ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard} 6919ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard 692081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/************************************************************************ 692181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 692281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Public API for operations on expressions * 692381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 692481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ************************************************************************/ 692581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 692681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic int 692781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpGetLanguageInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 692881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar**list, int len, int nb) { 692981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int tmp, tmp2; 693081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardtail: 693181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard switch (exp->type) { 693281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_EMPTY: 693381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 693481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_ATOM: 693581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard for (tmp = 0;tmp < nb;tmp++) 693681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (list[tmp] == exp->exp_str) 693781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 693881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (nb >= len) 693981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-2); 694013cee4e37ba9f2a401f976e069539514ebfce7bcDaniel Veillard list[nb] = exp->exp_str; 694181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(1); 694281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_COUNT: 694381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp = exp->exp_left; 694481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard goto tail; 694581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_SEQ: 694681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_OR: 694781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpGetLanguageInt(ctxt, exp->exp_left, list, len, nb); 694881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp < 0) 694981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 695081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpGetLanguageInt(ctxt, exp->exp_right, list, len, 695181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard nb + tmp); 695281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 < 0) 695381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp2); 695481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp + tmp2); 695581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 695681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 695781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 695881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 695981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 696081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpGetLanguage: 696181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expression context 696281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the expression 69637802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard * @langList: where to store the tokens 696481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @len: the allocated lenght of @list 696581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 696681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Find all the strings used in @exp and store them in @list 696781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 696881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the number of unique strings found, -1 in case of errors and 696981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * -2 if there is more than @len strings 697081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 697181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardint 697281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpGetLanguage(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 69737802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard const xmlChar**langList, int len) { 69747802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard if ((ctxt == NULL) || (exp == NULL) || (langList == NULL) || (len <= 0)) 697581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 69767802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard return(xmlExpGetLanguageInt(ctxt, exp, langList, len, 0)); 697781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 697881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 697981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic int 698081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpGetStartInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 698181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar**list, int len, int nb) { 698281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int tmp, tmp2; 698381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardtail: 698481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard switch (exp->type) { 698581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_FORBID: 698681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 698781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_EMPTY: 698881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 698981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_ATOM: 699081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard for (tmp = 0;tmp < nb;tmp++) 699181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (list[tmp] == exp->exp_str) 699281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 699381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (nb >= len) 699481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-2); 699513cee4e37ba9f2a401f976e069539514ebfce7bcDaniel Veillard list[nb] = exp->exp_str; 699681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(1); 699781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_COUNT: 699881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp = exp->exp_left; 699981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard goto tail; 700081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_SEQ: 700181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpGetStartInt(ctxt, exp->exp_left, list, len, nb); 700281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp < 0) 700381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 700481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (IS_NILLABLE(exp->exp_left)) { 700581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpGetStartInt(ctxt, exp->exp_right, list, len, 700681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard nb + tmp); 700781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 < 0) 700881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp2); 700981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp += tmp2; 701081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 701181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 701281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_OR: 701381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpGetStartInt(ctxt, exp->exp_left, list, len, nb); 701481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp < 0) 701581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 701681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpGetStartInt(ctxt, exp->exp_right, list, len, 701781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard nb + tmp); 701881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 < 0) 701981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp2); 702081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp + tmp2); 702181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 702281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 702381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 702481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 702581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 702681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpGetStart: 702781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expression context 702881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the expression 70297802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard * @tokList: where to store the tokens 703081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @len: the allocated lenght of @list 703181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 703281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Find all the strings that appears at the start of the languages 703381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * accepted by @exp and store them in @list. E.g. for (a, b) | c 703481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * it will return the list [a, c] 703581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 703681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the number of unique strings found, -1 in case of errors and 703781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * -2 if there is more than @len strings 703881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 703981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardint 704081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpGetStart(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 70417802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard const xmlChar**tokList, int len) { 70427802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard if ((ctxt == NULL) || (exp == NULL) || (tokList == NULL) || (len <= 0)) 704381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 70447802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard return(xmlExpGetStartInt(ctxt, exp, tokList, len, 0)); 704581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 704681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 704781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 704881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpIsNillable: 704981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the expression 705081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 705181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Finds if the expression is nillable, i.e. if it accepts the empty sequqnce 705281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 705381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns 1 if nillable, 0 if not and -1 in case of error 705481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 705581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardint 705681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpIsNillable(xmlExpNodePtr exp) { 705781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp == NULL) 705881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 705981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(IS_NILLABLE(exp) != 0); 706081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 706181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 706281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNodePtr 706381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpStringDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, const xmlChar *str) 706481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard{ 706581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr ret; 706681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 706781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard switch (exp->type) { 706881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_EMPTY: 706981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 707081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_FORBID: 707181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 707281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_ATOM: 707381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_str == str) { 707481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 707581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv atom: equal => Empty\n"); 707681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 707781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = emptyExp; 707881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 707981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 708081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv atom: mismatch => forbid\n"); 708181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 708281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* TODO wildcards here */ 708381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = forbiddenExp; 708481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 708581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 708681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_OR: { 708781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 708881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 708981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 709081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv or: => or(derivs)\n"); 709181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 709281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpStringDeriveInt(ctxt, exp->exp_left, str); 709381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) { 709481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 709581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 709681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpStringDeriveInt(ctxt, exp->exp_right, str); 709781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) { 709881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 709981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 710081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 710181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, tmp, ret, 710281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0); 710381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 710481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 710581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_SEQ: 710681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 710781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv seq: starting with left\n"); 710881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 710981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpStringDeriveInt(ctxt, exp->exp_left, str); 711081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) { 711181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 711281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (ret == forbiddenExp) { 711381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (IS_NILLABLE(exp->exp_left)) { 711481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 711581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv seq: left failed but nillable\n"); 711681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 711781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpStringDeriveInt(ctxt, exp->exp_right, str); 711881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 711981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 712081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 712181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv seq: left match => sequence\n"); 712281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 712381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_right->ref++; 712481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, exp->exp_right, 712581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0); 712681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 712781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 712881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_COUNT: { 712981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int min, max; 713081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 713181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 713281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max == 0) 713381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 713481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpStringDeriveInt(ctxt, exp->exp_left, str); 713581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) 713681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 713781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == forbiddenExp) { 713881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 713981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv count: pattern mismatch => forbid\n"); 714081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 714181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 714281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 714381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max == 1) 714481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 714581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max < 0) /* unbounded */ 714681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 714781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 714881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = exp->exp_max - 1; 714981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_min > 0) 715081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - 1; 715181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 715281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 715381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_left->ref++; 715481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left, NULL, 715581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, min, max); 715681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == emptyExp) { 715781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 715881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv count: match to empty => new count\n"); 715981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 716081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 716181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 716281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 716381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv count: match => sequence with new count\n"); 716481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 716581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, tmp, 716681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0)); 716781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 716881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 716981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 717081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 717181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 717281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 717381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpStringDerive: 717481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expression context 717581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the expression 717681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @str: the string 717781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @len: the string len in bytes if available 717881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 717981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Do one step of Brzozowski derivation of the expression @exp with 718081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * respect to the input string 718181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 718281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the resulting expression or NULL in case of internal error 718381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 718481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpNodePtr 718581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpStringDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 718681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar *str, int len) { 718781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar *input; 718881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 718981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((exp == NULL) || (ctxt == NULL) || (str == NULL)) { 719081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 719181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 719281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 719381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * check the string is in the dictionnary, if yes use an interned 719481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * copy, otherwise we know it's not an acceptable input 719581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 719681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard input = xmlDictExists(ctxt->dict, str, len); 719781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (input == NULL) { 719881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 719981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 720081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(xmlExpStringDeriveInt(ctxt, exp, input)); 720181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 720281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 720381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic int 720481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpCheckCard(xmlExpNodePtr exp, xmlExpNodePtr sub) { 720581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int ret = 1; 720681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 720781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->c_max == -1) { 720881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->c_max != -1) 720981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = 0; 721081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if ((exp->c_max >= 0) && (exp->c_max < sub->c_max)) { 721181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = 0; 721281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 721381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#if 0 721481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((IS_NILLABLE(sub)) && (!IS_NILLABLE(exp))) 721581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = 0; 721681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 721781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 721881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 721981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 722081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNodePtr xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 722181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr sub); 722281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 722381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpDivide: 722481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expressions context 722581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the englobing expression 722681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @sub: the subexpression 722781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @mult: the multiple expression 722881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @remain: the remain from the derivation of the multiple 722981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 723081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Check if exp is a multiple of sub, i.e. if there is a finite number n 723181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * so that sub{n} subsume exp 723281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 723381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the multiple value if successful, 0 if it is not a multiple 723481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * and -1 in case of internel error. 723581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 723681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 723781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic int 723881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpDivide(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub, 723981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr *mult, xmlExpNodePtr *remain) { 724081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int i; 724181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp, tmp2; 724281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 724381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (mult != NULL) *mult = NULL; 724481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (remain != NULL) *remain = NULL; 724581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->c_max == -1) return(0); 724681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (IS_NILLABLE(exp) && (!IS_NILLABLE(sub))) return(0); 724781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 724881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard for (i = 1;i <= exp->c_max;i++) { 724981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard sub->ref++; 725081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, 725181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard sub, NULL, NULL, i, i); 725281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) { 725381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 725481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 725581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (!xmlExpCheckCard(tmp, exp)) { 725681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 725781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard continue; 725881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 725981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpExpDeriveInt(ctxt, tmp, exp); 726081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 == NULL) { 726181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 726281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 726381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 726481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((tmp2 != forbiddenExp) && (IS_NILLABLE(tmp2))) { 726581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (remain != NULL) 726681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard *remain = tmp2; 726781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 726881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp2); 726981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (mult != NULL) 727081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard *mult = tmp; 727181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 727281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 727381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 727481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Divide succeeded %d\n", i); 727581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 727681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(i); 727781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 727881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 727981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp2); 728081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 728181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 728281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Divide failed\n"); 728381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 728481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 728581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 728681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 728781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 728881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpExpDeriveInt: 728981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expressions context 729081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the englobing expression 729181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @sub: the subexpression 729281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 729381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Try to do a step of Brzozowski derivation but at a higher level 729481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * the input being a subexpression. 729581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 729681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the resulting expression or NULL in case of internal error 729781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 729881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNodePtr 729981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) { 730081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr ret, tmp, tmp2, tmp3; 730181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar **tab; 730281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int len, i; 730381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 730481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 730581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * In case of equality and if the expression can only consume a finite 730681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * amount, then the derivation is empty 730781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 730881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((exp == sub) && (exp->c_max >= 0)) { 730981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 731081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Equal(exp, sub) and finite -> Empty\n"); 731181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 731281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(emptyExp); 731381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 731481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 731581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * decompose sub sequence first 731681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 731781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->type == XML_EXP_EMPTY) { 731881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 731981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Empty(sub) -> Empty\n"); 732081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 732181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->ref++; 732281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(exp); 732381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 732481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->type == XML_EXP_SEQ) { 732581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 732681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Seq(sub) -> decompose\n"); 732781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 732881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpExpDeriveInt(ctxt, exp, sub->exp_left); 732981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) 733081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 733181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == forbiddenExp) 733281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 733381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpExpDeriveInt(ctxt, tmp, sub->exp_right); 733481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 733581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 733681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 733781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->type == XML_EXP_OR) { 733881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 733981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Or(sub) -> decompose\n"); 734081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 734181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpExpDeriveInt(ctxt, exp, sub->exp_left); 734281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == forbiddenExp) 734381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 734481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) 734581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 734681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpExpDeriveInt(ctxt, exp, sub->exp_right); 734781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((ret == NULL) || (ret == forbiddenExp)) { 734881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 734981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 735081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 735181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, tmp, ret, NULL, 0, 0)); 735281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 735381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (!xmlExpCheckCard(exp, sub)) { 735481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 735581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("CheckCard(exp, sub) failed -> Forbid\n"); 735681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 735781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 735881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 735981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard switch (exp->type) { 736081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_EMPTY: 736181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub == emptyExp) 736281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(emptyExp); 736381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 736481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Empty(exp) -> Forbid\n"); 736581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 736681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 736781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_FORBID: 736881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 736981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Forbid(exp) -> Forbid\n"); 737081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 737181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 737281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_ATOM: 737381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->type == XML_EXP_ATOM) { 737481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* TODO: handle wildcards */ 737581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_str == sub->exp_str) { 737681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 737781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Atom match -> Empty\n"); 737881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 737981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(emptyExp); 738081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 738181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 738281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Atom mismatch -> Forbid\n"); 738381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 738481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 738581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 738681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((sub->type == XML_EXP_COUNT) && 738781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (sub->exp_max == 1) && 738881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (sub->exp_left->type == XML_EXP_ATOM)) { 738981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* TODO: handle wildcards */ 739081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_str == sub->exp_left->exp_str) { 739181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 739281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Atom match -> Empty\n"); 739381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 739481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(emptyExp); 739581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 739681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 739781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Atom mismatch -> Forbid\n"); 739881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 739981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 740081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 740181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 740281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Compex exp vs Atom -> Forbid\n"); 740381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 740481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 740581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_SEQ: 740681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* try to get the sequence consumed only if possible */ 740781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (xmlExpCheckCard(exp->exp_left, sub)) { 740881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* See if the sequence can be consumed directly */ 740981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 741081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Seq trying left only\n"); 741181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 741281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub); 741381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((ret != forbiddenExp) && (ret != NULL)) { 741481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 741581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Seq trying left only worked\n"); 741681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 741781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 741881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * TODO: assumption here that we are determinist 741981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * i.e. we won't get to a nillable exp left 742081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * subset which could be matched by the right 742181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * part too. 742281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * e.g.: (a | b)+,(a | c) and 'a+,a' 742381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 742481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_right->ref++; 742581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, 742681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_right, NULL, 0, 0)); 742781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 742881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 742981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 743081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Seq: left too short\n"); 743181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 743281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 743381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Try instead to decompose */ 743481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->type == XML_EXP_COUNT) { 743581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int min, max; 743681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 743781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 743881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Seq: sub is a count\n"); 743981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 744081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub->exp_left); 744181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) 744281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 744381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret != forbiddenExp) { 744481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 744581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Seq , Count match on left\n"); 744681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 744781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->exp_max < 0) 744881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 744981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 745081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = sub->exp_max -1; 745181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->exp_min > 0) 745281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = sub->exp_min -1; 745381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 745481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 745581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_right->ref++; 745681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, 745781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_right, NULL, 0, 0); 745881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) 745981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 746081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 746181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard sub->exp_left->ref++; 746281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, 746381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard sub->exp_left, NULL, NULL, min, max); 746481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 == NULL) { 746581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 746681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 746781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 746881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpExpDeriveInt(ctxt, tmp, tmp2); 746981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 747081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp2); 747181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 747281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 747381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 747481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* we made no progress on structured operations */ 747581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard break; 747681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_OR: 747781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 747881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Or , trying both side\n"); 747981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 748081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub); 748181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) 748281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 748381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpExpDeriveInt(ctxt, exp->exp_right, sub); 748481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) { 748581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, ret); 748681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 748781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 748881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, tmp, NULL, 0, 0)); 748981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_COUNT: { 749081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int min, max; 749181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 749281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->type == XML_EXP_COUNT) { 749381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 749481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Try to see if the loop is completely subsumed 749581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 749681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub->exp_left); 749781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) 749881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 749981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == forbiddenExp) { 750081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int mult; 750181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 750281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 750381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Count, Count inner don't subsume\n"); 750481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 750581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard mult = xmlExpDivide(ctxt, sub->exp_left, exp->exp_left, 750681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, &tmp); 750781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (mult <= 0) { 750881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 750981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Count, Count not multiple => forbidden\n"); 751081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 751181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 751281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 751381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->exp_max == -1) { 751481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 751581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max == -1) { 751681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_min <= sub->exp_min * mult) 751781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 751881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 751981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - sub->exp_min * mult; 752081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 752181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 752281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Count, Count finite can't subsume infinite\n"); 752381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 752481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 752581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 752681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 752781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 752881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max == -1) { 752981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 753081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Infinite loop consume mult finite loop\n"); 753181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 753281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_min > sub->exp_min * mult) { 753381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 753481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - sub->exp_min * mult; 753581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 753681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 753781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 753881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 753981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 754081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max < sub->exp_max * mult) { 754181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 754281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("loops max mult mismatch => forbidden\n"); 754381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 754481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 754581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 754681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 754781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->exp_max * mult > exp->exp_min) 754881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 754981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 755081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - sub->exp_max * mult; 755181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = exp->exp_max - sub->exp_max * mult; 755281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 755381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 755481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (!IS_NILLABLE(tmp)) { 755581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 755681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * TODO: loop here to try to grow if working on finite 755781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * blocks. 755881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 755981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 756081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Count, Count remain not nillable => forbidden\n"); 756181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 756281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 756381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 756481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (sub->exp_max == -1) { 756581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max == -1) { 756681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_min <= sub->exp_min) { 756781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 756881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Infinite loops Okay => COUNT(0,Inf)\n"); 756981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 757081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 757181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 757281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 757381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 757481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Infinite loops min => Count(X,Inf)\n"); 757581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 757681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 757781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - sub->exp_min; 757881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 757981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (exp->exp_min > sub->exp_min) { 758081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 758181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("loops min mismatch 1 => forbidden ???\n"); 758281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 758381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 758481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 758581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 758681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 758781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 758881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 758981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 759081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max == -1) { 759181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 759281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Infinite loop consume finite loop\n"); 759381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 759481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_min > sub->exp_min) { 759581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 759681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - sub->exp_min; 759781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 759881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 759981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 760081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 760181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 760281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max < sub->exp_max) { 760381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 760481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("loops max mismatch => forbidden\n"); 760581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 760681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 760781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 760881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 760981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->exp_max > exp->exp_min) 761081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 761181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 761281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - sub->exp_max; 761381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = exp->exp_max - sub->exp_max; 761481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 761581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 761681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 761781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("loops match => SEQ(COUNT())\n"); 761881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 761981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_left->ref++; 762081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left, 762181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, NULL, min, max); 762281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 == NULL) { 762381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 762481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 762581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, tmp, tmp2, 762681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0); 762781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 762881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 762981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub); 763081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) 763181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 763281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == forbiddenExp) { 763381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 763481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("loop mismatch => forbidden\n"); 763581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 763681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 763781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 763881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_min > 0) 763981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - 1; 764081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 764181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 764281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max < 0) 764381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 764481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 764581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = exp->exp_max - 1; 764681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 764781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 764881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("loop match => SEQ(COUNT())\n"); 764981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 765081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_left->ref++; 765181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left, 765281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, NULL, min, max); 765381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 == NULL) 765481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 765581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, tmp, tmp2, 765681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0); 765781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 765881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 765981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 766081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 7661ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard#ifdef DEBUG_DERIV 7662ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard printf("Fallback to derivative\n"); 7663ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard#endif 7664ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard if (IS_NILLABLE(sub)) { 7665ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard if (!(IS_NILLABLE(exp))) 7666ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(forbiddenExp); 7667ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard else 7668ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard ret = emptyExp; 7669ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard } else 7670ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard ret = NULL; 767181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 767281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * here the structured derivation made no progress so 767381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * we use the default token based derivation to force one more step 767481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 767581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt->tabSize == 0) 767681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->tabSize = 40; 767781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 767881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tab = (const xmlChar **) xmlMalloc(ctxt->tabSize * 767981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard sizeof(const xmlChar *)); 768081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tab == NULL) { 768181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 768281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 768381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 768481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 768581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * collect all the strings accepted by the subexpression on input 768681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 768781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0); 768881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard while (len < 0) { 768981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar **temp; 769054a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards temp = (const xmlChar **) xmlRealloc((xmlChar **) tab, ctxt->tabSize * 2 * 769181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard sizeof(const xmlChar *)); 769281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (temp == NULL) { 769354a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards xmlFree((xmlChar **) tab); 769481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 769581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 769681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tab = temp; 769781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->tabSize *= 2; 769881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0); 769981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 770081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard for (i = 0;i < len;i++) { 770181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpStringDeriveInt(ctxt, exp, tab[i]); 770281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((tmp == NULL) || (tmp == forbiddenExp)) { 770381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, ret); 770454a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards xmlFree((xmlChar **) tab); 770581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 770681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 770781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpStringDeriveInt(ctxt, sub, tab[i]); 770881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((tmp2 == NULL) || (tmp2 == forbiddenExp)) { 770981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 771081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, ret); 771154a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards xmlFree((xmlChar **) tab); 771281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 771381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 771481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp3 = xmlExpExpDeriveInt(ctxt, tmp, tmp2); 771581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 771681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp2); 771781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 771881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((tmp3 == NULL) || (tmp3 == forbiddenExp)) { 771981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, ret); 772054a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards xmlFree((xmlChar **) tab); 772181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp3); 772281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 772381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 772481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) 772581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = tmp3; 772681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else { 772781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, tmp3, NULL, 0, 0); 772881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) { 772954a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards xmlFree((xmlChar **) tab); 773081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 773181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 773281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 773381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 773454a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards xmlFree((xmlChar **) tab); 773581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 773681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 773781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 773881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 77390090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * xmlExpExpDerive: 77400090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * @ctxt: the expressions context 77410090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * @exp: the englobing expression 77420090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * @sub: the subexpression 77430090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * 77440090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * Evaluates the expression resulting from @exp consuming a sub expression @sub 77450090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * Based on algebraic derivation and sometimes direct Brzozowski derivation 77460090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * it usually tatkes less than linear time and can handle expressions generating 77470090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * infinite languages. 77480090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * 77490090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * Returns the resulting expression or NULL in case of internal error, the 77500090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * result must be freed 77510090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard */ 77520090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel VeillardxmlExpNodePtr 77530090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel VeillardxmlExpExpDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) { 77540090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard if ((exp == NULL) || (ctxt == NULL) || (sub == NULL)) 77550090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard return(NULL); 77560090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard 77570090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard /* 77580090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * O(1) speedups 77590090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard */ 77600090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard if (IS_NILLABLE(sub) && (!IS_NILLABLE(exp))) { 77610090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard#ifdef DEBUG_DERIV 77620090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard printf("Sub nillable and not exp : can't subsume\n"); 77630090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard#endif 77640090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard return(forbiddenExp); 77650090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard } 77660090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard if (xmlExpCheckCard(exp, sub) == 0) { 77670090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard#ifdef DEBUG_DERIV 77680090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard printf("sub generate longuer sequances than exp : can't subsume\n"); 77690090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard#endif 77700090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard return(forbiddenExp); 77710090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard } 77720090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard return(xmlExpExpDeriveInt(ctxt, exp, sub)); 77730090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard} 77740090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard 77750090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard/** 777681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpSubsume: 777781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expressions context 777881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the englobing expression 777981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @sub: the subexpression 778081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 778181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Check whether @exp accepts all the languages accexpted by @sub 778281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * the input being a subexpression. 778381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 778481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns 1 if true 0 if false and -1 in case of failure. 778581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 778681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardint 778781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpSubsume(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) { 778881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 778981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 779081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((exp == NULL) || (ctxt == NULL) || (sub == NULL)) 779181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 779281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 779381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 779481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * TODO: speedup by checking the language of sub is a subset of the 779581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * language of exp 779681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 779781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 779881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * O(1) speedups 779981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 780081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (IS_NILLABLE(sub) && (!IS_NILLABLE(exp))) { 780181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 780281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Sub nillable and not exp : can't subsume\n"); 780381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 780481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 780581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 780681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (xmlExpCheckCard(exp, sub) == 0) { 780781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 780881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("sub generate longuer sequances than exp : can't subsume\n"); 780981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 781081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 781181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 781281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpExpDeriveInt(ctxt, exp, sub); 781381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 781481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Result derivation :\n"); 781581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard PRINT_EXP(tmp); 781681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 781781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) 781881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 781981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == forbiddenExp) 782081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 782181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == emptyExp) 782281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(1); 782381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((tmp != NULL) && (IS_NILLABLE(tmp))) { 782481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 782581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(1); 782681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 782781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 782881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 782981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 7830465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7831465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/************************************************************************ 7832465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * * 7833465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Parsing expression * 7834465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * * 7835465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ************************************************************************/ 7836465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7837465a000b1080427bd62d89a925409b7db78616acDaniel Veillardstatic xmlExpNodePtr xmlExpParseExpr(xmlExpCtxtPtr ctxt); 7838465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7839465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#undef CUR 7840465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#define CUR (*ctxt->cur) 7841465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#undef NEXT 7842465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#define NEXT ctxt->cur++; 7843465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#undef IS_BLANK 7844465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#define IS_BLANK(c) ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t')) 7845465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#define SKIP_BLANKS while (IS_BLANK(*ctxt->cur)) ctxt->cur++; 7846465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7847465a000b1080427bd62d89a925409b7db78616acDaniel Veillardstatic int 7848465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpParseNumber(xmlExpCtxtPtr ctxt) { 7849465a000b1080427bd62d89a925409b7db78616acDaniel Veillard int ret = 0; 7850465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7851465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7852465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (CUR == '*') { 7853465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7854465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(-1); 7855465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7856465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((CUR < '0') || (CUR > '9')) 7857465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(-1); 7858465a000b1080427bd62d89a925409b7db78616acDaniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 7859465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = ret * 10 + (CUR - '0'); 7860465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7861465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7862465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(ret); 7863465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 7864465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7865465a000b1080427bd62d89a925409b7db78616acDaniel Veillardstatic xmlExpNodePtr 7866465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpParseOr(xmlExpCtxtPtr ctxt) { 7867465a000b1080427bd62d89a925409b7db78616acDaniel Veillard const char *base; 7868465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpNodePtr ret; 7869465a000b1080427bd62d89a925409b7db78616acDaniel Veillard const xmlChar *val; 7870465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7871465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7872465a000b1080427bd62d89a925409b7db78616acDaniel Veillard base = ctxt->cur; 7873465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (*ctxt->cur == '(') { 7874465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7875465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpParseExpr(ctxt); 7876465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7877465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (*ctxt->cur != ')') { 7878465a000b1080427bd62d89a925409b7db78616acDaniel Veillard fprintf(stderr, "unbalanced '(' : %s\n", base); 7879465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpFree(ctxt, ret); 7880465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7881465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7882465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT; 7883465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7884465a000b1080427bd62d89a925409b7db78616acDaniel Veillard goto parse_quantifier; 7885465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7886465a000b1080427bd62d89a925409b7db78616acDaniel Veillard while ((CUR != 0) && (!(IS_BLANK(CUR))) && (CUR != '(') && 7887465a000b1080427bd62d89a925409b7db78616acDaniel Veillard (CUR != ')') && (CUR != '|') && (CUR != ',') && (CUR != '{') && 7888465a000b1080427bd62d89a925409b7db78616acDaniel Veillard (CUR != '*') && (CUR != '+') && (CUR != '?') && (CUR != '}')) 7889465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT; 7890465a000b1080427bd62d89a925409b7db78616acDaniel Veillard val = xmlDictLookup(ctxt->dict, BAD_CAST base, ctxt->cur - base); 7891465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (val == NULL) 7892465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7893465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_ATOM, NULL, NULL, val, 0, 0); 7894465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (ret == NULL) 7895465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7896465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7897465a000b1080427bd62d89a925409b7db78616acDaniel Veillardparse_quantifier: 7898465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (CUR == '{') { 7899465a000b1080427bd62d89a925409b7db78616acDaniel Veillard int min, max; 7900465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7901465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7902465a000b1080427bd62d89a925409b7db78616acDaniel Veillard min = xmlExpParseNumber(ctxt); 7903465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (min < 0) { 7904465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpFree(ctxt, ret); 7905465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7906465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7907465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7908465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (CUR == ',') { 7909465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7910465a000b1080427bd62d89a925409b7db78616acDaniel Veillard max = xmlExpParseNumber(ctxt); 7911465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7912465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else 7913465a000b1080427bd62d89a925409b7db78616acDaniel Veillard max = min; 7914465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (CUR != '}') { 7915465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpFree(ctxt, ret); 7916465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7917465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7918465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7919465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL, 7920465a000b1080427bd62d89a925409b7db78616acDaniel Veillard min, max); 7921465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7922465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if (CUR == '?') { 7923465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7924465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL, 7925465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 0, 1); 7926465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7927465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if (CUR == '+') { 7928465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7929465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL, 7930465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 1, -1); 7931465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7932465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if (CUR == '*') { 7933465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7934465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL, 7935465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 0, -1); 7936465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7937465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7938465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(ret); 7939465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 7940465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7941465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7942465a000b1080427bd62d89a925409b7db78616acDaniel Veillardstatic xmlExpNodePtr 7943465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpParseSeq(xmlExpCtxtPtr ctxt) { 7944465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpNodePtr ret, right; 7945465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7946465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpParseOr(ctxt); 7947465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7948465a000b1080427bd62d89a925409b7db78616acDaniel Veillard while (CUR == '|') { 7949465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7950465a000b1080427bd62d89a925409b7db78616acDaniel Veillard right = xmlExpParseOr(ctxt); 7951465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (right == NULL) { 7952465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpFree(ctxt, ret); 7953465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7954465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7955465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, right, NULL, 0, 0); 7956465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (ret == NULL) 7957465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7958465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7959465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(ret); 7960465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 7961465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7962465a000b1080427bd62d89a925409b7db78616acDaniel Veillardstatic xmlExpNodePtr 7963465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpParseExpr(xmlExpCtxtPtr ctxt) { 7964465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpNodePtr ret, right; 7965465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7966465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpParseSeq(ctxt); 7967465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7968465a000b1080427bd62d89a925409b7db78616acDaniel Veillard while (CUR == ',') { 7969465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7970465a000b1080427bd62d89a925409b7db78616acDaniel Veillard right = xmlExpParseSeq(ctxt); 7971465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (right == NULL) { 7972465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpFree(ctxt, ret); 7973465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7974465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7975465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, right, NULL, 0, 0); 7976465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (ret == NULL) 7977465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7978465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7979465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(ret); 7980465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 7981465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7982465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/** 7983465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * xmlExpParse: 7984465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @ctxt: the expressions context 7985465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @expr: the 0 terminated string 7986465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 7987465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Minimal parser for regexps, it understand the following constructs 7988465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - string terminals 7989465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - choice operator | 7990465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - sequence operator , 7991465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - subexpressions (...) 7992465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - usual cardinality operators + * and ? 7993465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - finite sequences { min, max } 7994465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - infinite sequences { min, * } 7995465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * There is minimal checkings made especially no checking on strings values 7996465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 7997465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Returns a new expression or NULL in case of failure 7998465a000b1080427bd62d89a925409b7db78616acDaniel Veillard */ 7999465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpNodePtr 8000465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpParse(xmlExpCtxtPtr ctxt, const char *expr) { 8001465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpNodePtr ret; 8002465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8003465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ctxt->expr = expr; 8004465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ctxt->cur = expr; 8005465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8006465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpParseExpr(ctxt); 8007465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 8008465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (*ctxt->cur != 0) { 8009465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpFree(ctxt, ret); 8010465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 8011465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 8012465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(ret); 8013465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 8014465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8015465a000b1080427bd62d89a925409b7db78616acDaniel Veillardstatic void 8016465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpDumpInt(xmlBufferPtr buf, xmlExpNodePtr expr, int glob) { 8017465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpNodePtr c; 8018465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8019465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (expr == NULL) return; 8020465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (glob) xmlBufferWriteChar(buf, "("); 8021465a000b1080427bd62d89a925409b7db78616acDaniel Veillard switch (expr->type) { 8022465a000b1080427bd62d89a925409b7db78616acDaniel Veillard case XML_EXP_EMPTY: 8023465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteChar(buf, "empty"); 8024465a000b1080427bd62d89a925409b7db78616acDaniel Veillard break; 8025465a000b1080427bd62d89a925409b7db78616acDaniel Veillard case XML_EXP_FORBID: 8026465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteChar(buf, "forbidden"); 8027465a000b1080427bd62d89a925409b7db78616acDaniel Veillard break; 8028465a000b1080427bd62d89a925409b7db78616acDaniel Veillard case XML_EXP_ATOM: 8029465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteCHAR(buf, expr->exp_str); 8030465a000b1080427bd62d89a925409b7db78616acDaniel Veillard break; 8031465a000b1080427bd62d89a925409b7db78616acDaniel Veillard case XML_EXP_SEQ: 8032465a000b1080427bd62d89a925409b7db78616acDaniel Veillard c = expr->exp_left; 8033465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 8034465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 1); 8035465a000b1080427bd62d89a925409b7db78616acDaniel Veillard else 8036465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 0); 8037465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteChar(buf, " , "); 8038465a000b1080427bd62d89a925409b7db78616acDaniel Veillard c = expr->exp_right; 8039465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 8040465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 1); 8041465a000b1080427bd62d89a925409b7db78616acDaniel Veillard else 8042465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 0); 8043465a000b1080427bd62d89a925409b7db78616acDaniel Veillard break; 8044465a000b1080427bd62d89a925409b7db78616acDaniel Veillard case XML_EXP_OR: 8045465a000b1080427bd62d89a925409b7db78616acDaniel Veillard c = expr->exp_left; 8046465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 8047465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 1); 8048465a000b1080427bd62d89a925409b7db78616acDaniel Veillard else 8049465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 0); 8050465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteChar(buf, " | "); 8051465a000b1080427bd62d89a925409b7db78616acDaniel Veillard c = expr->exp_right; 8052465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 8053465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 1); 8054465a000b1080427bd62d89a925409b7db78616acDaniel Veillard else 8055465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 0); 8056465a000b1080427bd62d89a925409b7db78616acDaniel Veillard break; 8057465a000b1080427bd62d89a925409b7db78616acDaniel Veillard case XML_EXP_COUNT: { 8058465a000b1080427bd62d89a925409b7db78616acDaniel Veillard char rep[40]; 8059465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8060465a000b1080427bd62d89a925409b7db78616acDaniel Veillard c = expr->exp_left; 8061465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 8062465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 1); 8063465a000b1080427bd62d89a925409b7db78616acDaniel Veillard else 8064465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 0); 8065465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((expr->exp_min == 0) && (expr->exp_max == 1)) { 8066465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[0] = '?'; 8067465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[1] = 0; 8068465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if ((expr->exp_min == 0) && (expr->exp_max == -1)) { 8069465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[0] = '*'; 8070465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[1] = 0; 8071465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if ((expr->exp_min == 1) && (expr->exp_max == -1)) { 8072465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[0] = '+'; 8073465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[1] = 0; 8074465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if (expr->exp_max == expr->exp_min) { 8075465a000b1080427bd62d89a925409b7db78616acDaniel Veillard snprintf(rep, 39, "{%d}", expr->exp_min); 8076465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if (expr->exp_max < 0) { 8077465a000b1080427bd62d89a925409b7db78616acDaniel Veillard snprintf(rep, 39, "{%d,inf}", expr->exp_min); 8078465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else { 8079465a000b1080427bd62d89a925409b7db78616acDaniel Veillard snprintf(rep, 39, "{%d,%d}", expr->exp_min, expr->exp_max); 8080465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 8081465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[39] = 0; 8082465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteChar(buf, rep); 8083465a000b1080427bd62d89a925409b7db78616acDaniel Veillard break; 8084465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 8085465a000b1080427bd62d89a925409b7db78616acDaniel Veillard default: 8086465a000b1080427bd62d89a925409b7db78616acDaniel Veillard fprintf(stderr, "Error in tree\n"); 8087465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 8088465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (glob) 8089465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteChar(buf, ")"); 8090465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 8091465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/** 8092465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * xmlExpDump: 8093465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @buf: a buffer to receive the output 8094465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @expr: the compiled expression 8095465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8096465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Serialize the expression as compiled to the buffer 8097465a000b1080427bd62d89a925409b7db78616acDaniel Veillard */ 8098465a000b1080427bd62d89a925409b7db78616acDaniel Veillardvoid 80995eee767ca9b30a8e8c54808c82060ceb41630d6aDaniel VeillardxmlExpDump(xmlBufferPtr buf, xmlExpNodePtr expr) { 81005eee767ca9b30a8e8c54808c82060ceb41630d6aDaniel Veillard if ((buf == NULL) || (expr == NULL)) 8101465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return; 81025eee767ca9b30a8e8c54808c82060ceb41630d6aDaniel Veillard xmlExpDumpInt(buf, expr, 0); 8103465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 8104465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8105465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/** 8106465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * xmlExpMaxToken: 8107465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @expr: a compiled expression 8108465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8109465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Indicate the maximum number of input a expression can accept 8110465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8111465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Returns the maximum length or -1 in case of error 8112465a000b1080427bd62d89a925409b7db78616acDaniel Veillard */ 8113465a000b1080427bd62d89a925409b7db78616acDaniel Veillardint 8114465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpMaxToken(xmlExpNodePtr expr) { 8115465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (expr == NULL) 8116465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(-1); 8117465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(expr->c_max); 8118465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 8119465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8120465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/** 8121465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * xmlExpCtxtNbNodes: 8122465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @ctxt: an expression context 8123465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8124465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Debugging facility provides the number of allocated nodes at a that point 8125465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8126465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Returns the number of nodes in use or -1 in case of error 8127465a000b1080427bd62d89a925409b7db78616acDaniel Veillard */ 8128465a000b1080427bd62d89a925409b7db78616acDaniel Veillardint 8129465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpCtxtNbNodes(xmlExpCtxtPtr ctxt) { 8130465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (ctxt == NULL) 8131465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(-1); 8132465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(ctxt->nb_nodes); 8133465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 8134465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8135465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/** 8136465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * xmlExpCtxtNbCons: 8137465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @ctxt: an expression context 8138465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8139465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Debugging facility provides the number of allocated nodes over lifetime 8140465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8141465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Returns the number of nodes ever allocated or -1 in case of error 8142465a000b1080427bd62d89a925409b7db78616acDaniel Veillard */ 8143465a000b1080427bd62d89a925409b7db78616acDaniel Veillardint 8144465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpCtxtNbCons(xmlExpCtxtPtr ctxt) { 8145465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (ctxt == NULL) 8146465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(-1); 8147465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(ctxt->nb_cons); 8148465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 8149465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 815081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif /* LIBXML_EXPR_ENABLED */ 81515d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_xmlregexp 81525d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h" 81534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif /* LIBXML_REGEXP_ENABLED */ 8154