14255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/* 24255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * regexp.c: generic and extensible Regular Expression engine 34255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 4f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel 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 47204f1f144ce1eded7dd25162c1c67e66a93fe450Patrick R. Gansterer#ifdef ERROR 48204f1f144ce1eded7dd25162c1c67e66a93fe450Patrick R. Gansterer#undef ERROR 49204f1f144ce1eded7dd25162c1c67e66a93fe450Patrick R. Gansterer#endif 50ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard#define ERROR(str) \ 51ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard ctxt->error = XML_REGEXP_COMPILE_ERROR; \ 52ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrCompile(ctxt, str); 534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define NEXT ctxt->cur++ 544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define CUR (*(ctxt->cur)) 554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define NXT(index) (ctxt->cur[index]) 564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l) 584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define NEXTL(l) ctxt->cur += l; 59c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard#define XML_REG_STRING_SEPARATOR '|' 60a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack/* 61a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack * Need PREV to check on a '-' within a Character Group. May only be used 62a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack * when it's guaranteed that cur is not at the beginning of ctxt->string! 63a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack */ 64a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack#define PREV (ctxt->cur[-1]) 654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 66e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard/** 67e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * TODO: 68e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 69e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * macro to flag unimplemented blocks 70e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 71f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#define TODO \ 72e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard xmlGenericError(xmlGenericErrorContext, \ 73e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard "Unimplemented block at %s:%d\n", \ 74e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard __FILE__, __LINE__); 75e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 77f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 78f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Datatypes and structures * 79f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 82fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard/* 83fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * Note: the order of the enums below is significant, do not shuffle 84fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard */ 854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef enum { 864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_EPSILON = 1, 874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_CHARVAL, 884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_RANGES, 89567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard XML_REGEXP_SUBREG, /* used for () sub regexps */ 904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_STRING, 914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_ANYCHAR, /* . */ 924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_ANYSPACE, /* \s */ 934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NOTSPACE, /* \S */ 944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_INITNAME, /* \l */ 95567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard XML_REGEXP_NOTINITNAME, /* \L */ 964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NAMECHAR, /* \c */ 974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NOTNAMECHAR, /* \C */ 984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_DECIMAL, /* \d */ 99567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard XML_REGEXP_NOTDECIMAL, /* \D */ 1004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_REALCHAR, /* \w */ 101567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard XML_REGEXP_NOTREALCHAR, /* \W */ 102567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard XML_REGEXP_LETTER = 100, 1034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_LETTER_UPPERCASE, 1044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_LETTER_LOWERCASE, 1054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_LETTER_TITLECASE, 1064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_LETTER_MODIFIER, 1074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_LETTER_OTHERS, 1084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK, 1094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK_NONSPACING, 1104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK_SPACECOMBINING, 1114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK_ENCLOSING, 1124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NUMBER, 1134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NUMBER_DECIMAL, 1144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NUMBER_LETTER, 1154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_NUMBER_OTHERS, 1164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT, 1174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_CONNECTOR, 1184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_DASH, 1194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_OPEN, 1204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_CLOSE, 1214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_INITQUOTE, 1224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_FINQUOTE, 1234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_PUNCT_OTHERS, 1244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SEPAR, 1254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SEPAR_SPACE, 1264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SEPAR_LINE, 1274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SEPAR_PARA, 1284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SYMBOL, 1294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SYMBOL_MATH, 1304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SYMBOL_CURRENCY, 1314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SYMBOL_MODIFIER, 1324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_SYMBOL_OTHERS, 1334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_OTHER, 1344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_OTHER_CONTROL, 1354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_OTHER_FORMAT, 1364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_OTHER_PRIVATE, 1374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_OTHER_NA, 1384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_BLOCK_NAME 1394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} xmlRegAtomType; 1404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef enum { 1424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_QUANT_EPSILON = 1, 1434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_QUANT_ONCE, 1444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_QUANT_OPT, 1454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_QUANT_MULT, 1464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_QUANT_PLUS, 1477646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard XML_REGEXP_QUANT_ONCEONLY, 1487646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard XML_REGEXP_QUANT_ALL, 1494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_QUANT_RANGE 1504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} xmlRegQuantType; 1514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef enum { 1534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_START_STATE = 1, 1544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_FINAL_STATE, 155cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_TRANS_STATE, 1560e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard XML_REGEXP_SINK_STATE, 1570e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard XML_REGEXP_UNREACH_STATE 1584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} xmlRegStateType; 1594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef enum { 1614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK_NORMAL = 0, 1624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK_START, 1634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_MARK_VISITED 1644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} xmlRegMarkedType; 1654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegRange xmlRegRange; 1674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegRange *xmlRegRangePtr; 1684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegRange { 170f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard int neg; /* 0 normal, 1 not, 2 exclude */ 1714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomType type; 1724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int start; 1734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int end; 1744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *blockName; 1754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 1764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegAtom xmlRegAtom; 1784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegAtom *xmlRegAtomPtr; 1794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlAutomataState xmlRegState; 1814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegState *xmlRegStatePtr; 1824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegAtom { 1844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int no; 1854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomType type; 1864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegQuantType quant; 1874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int min; 1884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int max; 1894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard void *valuep; 191a646cfdb14097f72d3b0ce9b0f43126934d8efd3Daniel Veillard void *valuep2; 1924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int neg; 1934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int codepoint; 1944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr start; 19576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegStatePtr start0; 1964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr stop; 1974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int maxRanges; 1984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbRanges; 1994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegRangePtr *ranges; 2004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard void *data; 2014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 2024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegCounter xmlRegCounter; 2044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegCounter *xmlRegCounterPtr; 2054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegCounter { 2074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int min; 2084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int max; 2094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 2104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegTrans xmlRegTrans; 2124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegTrans *xmlRegTransPtr; 2134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegTrans { 2154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 2164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int to; 2174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int counter; 2184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int count; 219567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int nd; 2204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 2214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlAutomataState { 2234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStateType type; 2244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegMarkedType mark; 225466fcdaa33258cf3633887222146b891d202cc6cDaniel Veillard xmlRegMarkedType markd; 22623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegMarkedType reached; 2274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int no; 2284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int maxTrans; 2294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbTrans; 2304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegTrans *trans; 231db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard /* knowing states ponting to us can speed things up */ 232db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int maxTransTo; 233db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int nbTransTo; 234db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int *transTo; 2354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 2364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlAutomata xmlRegParserCtxt; 2384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegParserCtxt *xmlRegParserCtxtPtr; 2394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2401ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard#define AM_AUTOMATA_RNG 1 2411ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard 2424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlAutomata { 2434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *string; 2444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *cur; 2454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int error; 2474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int neg; 2484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr start; 2504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr end; 2514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state; 2524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 2544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int maxAtoms; 2564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbAtoms; 2574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr *atoms; 2584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int maxStates; 2604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbStates; 2614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr *states; 2624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int maxCounters; 2644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbCounters; 2654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegCounter *counters; 266e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 267e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int determinist; 2686e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard int negs; 2691ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard int flags; 2704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 2714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegexp { 2734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *string; 2744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbStates; 2754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr *states; 2764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbAtoms; 2774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr *atoms; 2784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbCounters; 2794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegCounter *counters; 280e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int determinist; 2811ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard int flags; 28223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 28323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * That's the compact form for determinists automatas 28423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 28523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int nbstates; 28623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int *compact; 287118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard void **transdata; 28823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int nbstrings; 28923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlChar **stringMap; 2904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 2914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegExecRollback xmlRegExecRollback; 2934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegExecRollback *xmlRegExecRollbackPtr; 2944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegExecRollback { 2964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state;/* the current state */ 2974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int index; /* the index in the input stack */ 2984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nextbranch; /* the next transition to explore in that state */ 299ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack int *counts; /* save the automata state if it has some */ 3004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 3014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlRegInputToken xmlRegInputToken; 3034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlRegInputToken *xmlRegInputTokenPtr; 3044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegInputToken { 3064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *value; 3074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard void *data; 3084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 3094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlRegExecCtxt { 3114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int status; /* execution status != 0 indicate an error */ 312ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack int determinist; /* did we find an indeterministic behaviour */ 3134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegexpPtr comp; /* the compiled regexp */ 3144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegExecCallbacks callback; 3154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard void *data; 3164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state;/* the current state */ 3184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int transno; /* the current transition on that state */ 319ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack int transcount; /* the number of chars in char counted transitions */ 3204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 3224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * A stack of rollback states 3234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 3244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int maxRollbacks; 3254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int nbRollbacks; 3264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegExecRollback *rollbacks; 3274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 3294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The state of the automata if any 3304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 3314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int *counts; 3324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 3344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The input stack 3354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 3364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int inputStackMax; 3374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int inputStackNr; 3384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int index; 3394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int *charStack; 3404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard const xmlChar *inputString; /* when operating on characters */ 3414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegInputTokenPtr inputStack;/* when operating on strings */ 3424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3437bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard /* 3447bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * error handling 3457bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard */ 3467bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int errStateNo; /* the error state number */ 3477bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlRegStatePtr errState; /* the error state */ 3487bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlChar *errString; /* the string raising the error */ 3497bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int *errCounts; /* counters at the error state */ 35094cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard int nbPush; 3514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 3524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 353441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard#define REGEXP_ALL_COUNTER 0x123456 354441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard#define REGEXP_ALL_LAX_COUNTER 0x123457 3557646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard 3564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top); 35723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillardstatic void xmlRegFreeState(xmlRegStatePtr state); 35823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillardstatic void xmlRegFreeAtom(xmlRegAtomPtr atom); 3599efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillardstatic int xmlRegStrEqualWildcard(const xmlChar *expStr, const xmlChar *valStr); 360567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillardstatic int xmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint); 361567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillardstatic int xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, 362567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int neg, int start, int end, const xmlChar *blockName); 3634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3641ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillardvoid xmlAutomataSetFlags(xmlAutomataPtr am, int flags); 3651ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard 3664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 367ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * * 368f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Regexp memory error handler * 369ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * * 370ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard ************************************************************************/ 371ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard/** 372ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * xmlRegexpErrMemory: 373ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * @extra: extra information 374ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * 375ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * Handle an out of memory condition 376ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard */ 377ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillardstatic void 378ff46a0443e6b999297e52c160b88536b8089ec56Daniel VeillardxmlRegexpErrMemory(xmlRegParserCtxtPtr ctxt, const char *extra) 379ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard{ 380ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard const char *regexp = NULL; 381ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard if (ctxt != NULL) { 382ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard regexp = (const char *) ctxt->string; 383ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard ctxt->error = XML_ERR_NO_MEMORY; 384ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard } 385659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_REGEXP, 386ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra, 387ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard regexp, NULL, 0, 0, 388ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard "Memory allocation failed : %s\n", extra); 389ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard} 390ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard 391ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard/** 392ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * xmlRegexpErrCompile: 393ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * @extra: extra information 394ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard * 395ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Handle a compilation failure 396ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard */ 397ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillardstatic void 398ff46a0443e6b999297e52c160b88536b8089ec56Daniel VeillardxmlRegexpErrCompile(xmlRegParserCtxtPtr ctxt, const char *extra) 399ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard{ 400ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard const char *regexp = NULL; 401ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard int idx = 0; 402ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard 403ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard if (ctxt != NULL) { 404ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard regexp = (const char *) ctxt->string; 405ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard idx = ctxt->cur - ctxt->string; 406ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard ctxt->error = XML_REGEXP_COMPILE_ERROR; 407ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard } 408659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_REGEXP, 409ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard XML_REGEXP_COMPILE_ERROR, XML_ERR_FATAL, NULL, 0, extra, 410ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard regexp, NULL, idx, 0, 411ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard "failed to compile: %s\n", extra); 412ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard} 413ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard 414ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard/************************************************************************ 415f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 416f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Allocation/Deallocation * 417f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 4184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 4194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 42023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillardstatic int xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt); 4214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 4224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegEpxFromParse: 4234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @ctxt: the parser context used to build it 4244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 425ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Allocate a new regexp and fill it with the result from the parser 4264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 4274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new regexp or NULL in case of error 4284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 4294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegexpPtr 4304255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) { 4314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegexpPtr ret; 4324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 4334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = (xmlRegexpPtr) xmlMalloc(sizeof(xmlRegexp)); 434a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (ret == NULL) { 435ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "compiling regexp"); 4364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 437a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 4384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(ret, 0, sizeof(xmlRegexp)); 4394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->string = ctxt->string; 4404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->nbStates = ctxt->nbStates; 4414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->states = ctxt->states; 4424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->nbAtoms = ctxt->nbAtoms; 4434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->atoms = ctxt->atoms; 4444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->nbCounters = ctxt->nbCounters; 4454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->counters = ctxt->counters; 446e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard ret->determinist = ctxt->determinist; 4471ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard ret->flags = ctxt->flags; 448567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (ret->determinist == -1) { 449567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegexpIsDeterminist(ret); 450567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 45123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 45223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if ((ret->determinist != 0) && 45323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard (ret->nbCounters == 0) && 4546e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard (ctxt->negs == 0) && 455118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard (ret->atoms != NULL) && 45623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard (ret->atoms[0] != NULL) && 45723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard (ret->atoms[0]->type == XML_REGEXP_STRING)) { 45823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int i, j, nbstates = 0, nbatoms = 0; 45923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int *stateRemap; 46023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int *stringRemap; 46123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int *transitions; 462118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard void **transdata; 46323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlChar **stringMap; 46423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlChar *value; 46523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 46623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 46723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Switch to a compact representation 46823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * 1/ counting the effective number of states left 469ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * 2/ counting the unique number of atoms, and check that 47023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * they are all of the string type 47123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * 3/ build a table state x atom for the transitions 47223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 47323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 47423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stateRemap = xmlMalloc(ret->nbStates * sizeof(int)); 475a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (stateRemap == NULL) { 476ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "compiling regexp"); 477a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(ret); 478a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 479a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 48023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < ret->nbStates;i++) { 48123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (ret->states[i] != NULL) { 48223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stateRemap[i] = nbstates; 48323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard nbstates++; 48423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } else { 48523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stateRemap[i] = -1; 48623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 48723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 48823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_COMPACTION 48923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("Final: %d states\n", nbstates); 49023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 49123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stringMap = xmlMalloc(ret->nbAtoms * sizeof(char *)); 492a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (stringMap == NULL) { 493ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "compiling regexp"); 494a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stateRemap); 495a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(ret); 496a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 497a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 49823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stringRemap = xmlMalloc(ret->nbAtoms * sizeof(int)); 499a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (stringRemap == NULL) { 500ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "compiling regexp"); 501a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stringMap); 502a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stateRemap); 503a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(ret); 504a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 505a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 50623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < ret->nbAtoms;i++) { 50723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if ((ret->atoms[i]->type == XML_REGEXP_STRING) && 50823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard (ret->atoms[i]->quant == XML_REGEXP_QUANT_ONCE)) { 50923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard value = ret->atoms[i]->valuep; 51023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (j = 0;j < nbatoms;j++) { 51123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (xmlStrEqual(stringMap[j], value)) { 51223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stringRemap[i] = j; 51323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard break; 51423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 51523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 51623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (j >= nbatoms) { 51723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stringRemap[i] = nbatoms; 51823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stringMap[nbatoms] = xmlStrdup(value); 519a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (stringMap[nbatoms] == NULL) { 520a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard for (i = 0;i < nbatoms;i++) 521a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stringMap[i]); 522a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stringRemap); 523a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stringMap); 524a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stateRemap); 525a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(ret); 526a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 527a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 52823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard nbatoms++; 52923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 53023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } else { 53123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stateRemap); 53223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringRemap); 53323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < nbatoms;i++) 53423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringMap[i]); 53523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringMap); 536a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(ret); 537a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 53823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 53923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 54023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_COMPACTION 54123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("Final: %d atoms\n", nbatoms); 54223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 543a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard transitions = (int *) xmlMalloc((nbstates + 1) * 544a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard (nbatoms + 1) * sizeof(int)); 545a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (transitions == NULL) { 546a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stateRemap); 547a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stringRemap); 548a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(stringMap); 549a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFree(ret); 550a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 551a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 552a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard memset(transitions, 0, (nbstates + 1) * (nbatoms + 1) * sizeof(int)); 55323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 55423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 55523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Allocate the transition table. The first entry for each 556ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * state corresponds to the state type. 55723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 558118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard transdata = NULL; 55923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 56023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < ret->nbStates;i++) { 56123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int stateno, atomno, targetno, prev; 56223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegStatePtr state; 56323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegTransPtr trans; 56423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 56523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard stateno = stateRemap[i]; 56623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (stateno == -1) 56723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard continue; 56823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard state = ret->states[i]; 56923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 57023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard transitions[stateno * (nbatoms + 1)] = state->type; 57123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 57223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (j = 0;j < state->nbTrans;j++) { 57323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard trans = &(state->trans[j]); 57423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if ((trans->to == -1) || (trans->atom == NULL)) 57523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard continue; 57623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard atomno = stringRemap[trans->atom->no]; 577118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if ((trans->atom->data != NULL) && (transdata == NULL)) { 578118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard transdata = (void **) xmlMalloc(nbstates * nbatoms * 579118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard sizeof(void *)); 580118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if (transdata != NULL) 581118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard memset(transdata, 0, 582118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard nbstates * nbatoms * sizeof(void *)); 583a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard else { 584ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "compiling regexp"); 585a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard break; 586a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 587118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard } 58823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard targetno = stateRemap[trans->to]; 58923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 590ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * if the same atom can generate transitions to 2 different 59123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * states then it means the automata is not determinist and 59223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * the compact form can't be used ! 59323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 59423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard prev = transitions[stateno * (nbatoms + 1) + atomno + 1]; 59523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (prev != 0) { 59623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (prev != targetno + 1) { 59723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->determinist = 0; 59823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_COMPACTION 59923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("Indet: state %d trans %d, atom %d to %d : %d to %d\n", 60023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard i, j, trans->atom->no, trans->to, atomno, targetno); 60123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf(" previous to is %d\n", prev); 60223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 603118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if (transdata != NULL) 604118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard xmlFree(transdata); 60523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(transitions); 60623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stateRemap); 60723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringRemap); 60823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < nbatoms;i++) 60923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringMap[i]); 61023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringMap); 611a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard goto not_determ; 61223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 61323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } else { 61423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#if 0 61523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("State %d trans %d: atom %d to %d : %d to %d\n", 61623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard i, j, trans->atom->no, trans->to, atomno, targetno); 61723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 61823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard transitions[stateno * (nbatoms + 1) + atomno + 1] = 619118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard targetno + 1; /* to avoid 0 */ 620118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if (transdata != NULL) 621118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard transdata[stateno * nbatoms + atomno] = 622118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard trans->atom->data; 62323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 62423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 62523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 62623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->determinist = 1; 62723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_COMPACTION 62823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 62923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Debug 63023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 63123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < nbstates;i++) { 63223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (j = 0;j < nbatoms + 1;j++) { 63323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("%02d ", transitions[i * (nbatoms + 1) + j]); 63423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 63523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("\n"); 63623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 63723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("\n"); 63823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 63923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 64023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Cleanup of the old data 64123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 64223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (ret->states != NULL) { 64323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < ret->nbStates;i++) 64423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegFreeState(ret->states[i]); 64523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(ret->states); 64623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 64723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->states = NULL; 64823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->nbStates = 0; 64923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (ret->atoms != NULL) { 65023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < ret->nbAtoms;i++) 65123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegFreeAtom(ret->atoms[i]); 65223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(ret->atoms); 65323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 65423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->atoms = NULL; 65523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->nbAtoms = 0; 65623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 65723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->compact = transitions; 658118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard ret->transdata = transdata; 65923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->stringMap = stringMap; 66023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->nbstrings = nbatoms; 66123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret->nbstates = nbstates; 66223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stateRemap); 66323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(stringRemap); 66423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 665a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillardnot_determ: 666a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->string = NULL; 667a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->nbStates = 0; 668a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->states = NULL; 669a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->nbAtoms = 0; 670a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->atoms = NULL; 671a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->nbCounters = 0; 672a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard ctxt->counters = NULL; 6734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 6744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 6754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 6764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 6774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegNewParserCtxt: 6784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @string: the string to parse 6794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 6804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Allocate a new regexp parser context 6814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 6824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new context or NULL in case of error 6834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 6844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegParserCtxtPtr 6854255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewParserCtxt(const xmlChar *string) { 6864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegParserCtxtPtr ret; 6874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 6884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = (xmlRegParserCtxtPtr) xmlMalloc(sizeof(xmlRegParserCtxt)); 6894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == NULL) 6904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 6914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(ret, 0, sizeof(xmlRegParserCtxt)); 6924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (string != NULL) 6934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->string = xmlStrdup(string); 6944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->cur = ret->string; 6954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->neg = 0; 6966e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard ret->negs = 0; 6974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->error = 0; 698e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard ret->determinist = -1; 6994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 7004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 7014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 7024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 7034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegNewRange: 7044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @ctxt: the regexp parser context 7054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @neg: is that negative 7064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @type: the type of range 7074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @start: the start codepoint 7084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @end: the end codepoint 7094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 7104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Allocate a new regexp range 7114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 7124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new range or NULL in case of error 7134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 7144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegRangePtr 7154255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewRange(xmlRegParserCtxtPtr ctxt, 7164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int neg, xmlRegAtomType type, int start, int end) { 7174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegRangePtr ret; 7184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 7194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = (xmlRegRangePtr) xmlMalloc(sizeof(xmlRegRange)); 7204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == NULL) { 721ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating range"); 7224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 7234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 7244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->neg = neg; 7254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->type = type; 7264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->start = start; 7274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->end = end; 7284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 7294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 7304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 7314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 7324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeRange: 7334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @range: the regexp range 7344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 7354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp range 7364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 7374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 7384255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeRange(xmlRegRangePtr range) { 7394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (range == NULL) 7404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 7414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 7424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (range->blockName != NULL) 7434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(range->blockName); 7444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(range); 7454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 7464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 7474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 74876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * xmlRegCopyRange: 74976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * @range: the regexp range 75076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * 75176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * Copy a regexp range 75276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * 75376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * Returns the new copy or NULL in case of error. 75476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard */ 75576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillardstatic xmlRegRangePtr 75676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel VeillardxmlRegCopyRange(xmlRegParserCtxtPtr ctxt, xmlRegRangePtr range) { 75776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegRangePtr ret; 75876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 75976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (range == NULL) 76076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(NULL); 76176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 76276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret = xmlRegNewRange(ctxt, range->neg, range->type, range->start, 76376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard range->end); 76476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (ret == NULL) 76576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(NULL); 76676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (range->blockName != NULL) { 76776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->blockName = xmlStrdup(range->blockName); 76876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (ret->blockName == NULL) { 76976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating range"); 77076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegFreeRange(ret); 77176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(NULL); 77276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 77376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 77476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(ret); 77576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard} 77676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 77776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard/** 7784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegNewAtom: 7794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @ctxt: the regexp parser context 7804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @type: the type of atom 7814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 78276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * Allocate a new atom 7834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 7844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new atom or NULL in case of error 7854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 7864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegAtomPtr 7874255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewAtom(xmlRegParserCtxtPtr ctxt, xmlRegAtomType type) { 7884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr ret; 7894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 7904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = (xmlRegAtomPtr) xmlMalloc(sizeof(xmlRegAtom)); 7914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == NULL) { 792ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating atom"); 7934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 7944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 7954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(ret, 0, sizeof(xmlRegAtom)); 7964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->type = type; 7974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->quant = XML_REGEXP_QUANT_ONCE; 7984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->min = 0; 7994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->max = 0; 8004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 8014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 8024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 8034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 8044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeAtom: 8054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @atom: the regexp atom 8064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 8074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp atom 8084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 8094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 8104255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeAtom(xmlRegAtomPtr atom) { 8114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 8124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 8134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom == NULL) 8144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 8154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 8164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < atom->nbRanges;i++) 8174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeRange(atom->ranges[i]); 8184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->ranges != NULL) 8194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(atom->ranges); 820de0e498b426e8493ab9e7b22a2f88501e96db000Daniel Veillard if ((atom->type == XML_REGEXP_STRING) && (atom->valuep != NULL)) 821de0e498b426e8493ab9e7b22a2f88501e96db000Daniel Veillard xmlFree(atom->valuep); 82277005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard if ((atom->type == XML_REGEXP_STRING) && (atom->valuep2 != NULL)) 82377005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard xmlFree(atom->valuep2); 824de0e498b426e8493ab9e7b22a2f88501e96db000Daniel Veillard if ((atom->type == XML_REGEXP_BLOCK_NAME) && (atom->valuep != NULL)) 8254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(atom->valuep); 8264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(atom); 8274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 8284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 82976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard/** 83076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * xmlRegCopyAtom: 83176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * @ctxt: the regexp parser context 83276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * @atom: the oiginal atom 83376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * 83476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * Allocate a new regexp range 83576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * 83676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * Returns the new atom or NULL in case of error 83776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard */ 83876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillardstatic xmlRegAtomPtr 83976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel VeillardxmlRegCopyAtom(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) { 84076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegAtomPtr ret; 84176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 84276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret = (xmlRegAtomPtr) xmlMalloc(sizeof(xmlRegAtom)); 84376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (ret == NULL) { 84476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegexpErrMemory(ctxt, "copying atom"); 84576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(NULL); 84676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 84776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard memset(ret, 0, sizeof(xmlRegAtom)); 84876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->type = atom->type; 84976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->quant = atom->quant; 85076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->min = atom->min; 85176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->max = atom->max; 85276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (atom->nbRanges > 0) { 85376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard int i; 85476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 85576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->ranges = (xmlRegRangePtr *) xmlMalloc(sizeof(xmlRegRangePtr) * 85676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard atom->nbRanges); 85776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (ret->ranges == NULL) { 85876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegexpErrMemory(ctxt, "copying atom"); 85976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard goto error; 86076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 86176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard for (i = 0;i < atom->nbRanges;i++) { 86276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->ranges[i] = xmlRegCopyRange(ctxt, atom->ranges[i]); 86376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (ret->ranges[i] == NULL) 86476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard goto error; 86576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ret->nbRanges = i + 1; 86676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 86776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 86876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(ret); 86976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 87076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillarderror: 87176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegFreeAtom(ret); 87276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(NULL); 87376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard} 87476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 8754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlRegStatePtr 8764255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewState(xmlRegParserCtxtPtr ctxt) { 8774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr ret; 8784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 8794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = (xmlRegStatePtr) xmlMalloc(sizeof(xmlRegState)); 8804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == NULL) { 881ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating state"); 8824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 8834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 8844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(ret, 0, sizeof(xmlRegState)); 8854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->type = XML_REGEXP_TRANS_STATE; 8864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->mark = XML_REGEXP_MARK_NORMAL; 8874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 8884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 8894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 8904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 8914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeState: 8924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @state: the regexp state 8934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 8944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp state 8954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 8964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 8974255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeState(xmlRegStatePtr state) { 8984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state == NULL) 8994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 9004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 9014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state->trans != NULL) 9024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(state->trans); 903db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (state->transTo != NULL) 904db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlFree(state->transTo); 9054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(state); 9064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 9074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 9084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 9094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeParserCtxt: 9104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @ctxt: the regexp parser context 9114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 9124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp parser context 9134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 9144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 9154255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeParserCtxt(xmlRegParserCtxtPtr ctxt) { 9164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 9174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt == NULL) 9184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 9194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 9204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->string != NULL) 9214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(ctxt->string); 9224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->states != NULL) { 9234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < ctxt->nbStates;i++) 9244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeState(ctxt->states[i]); 9254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(ctxt->states); 9264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 9274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atoms != NULL) { 9284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < ctxt->nbAtoms;i++) 9294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeAtom(ctxt->atoms[i]); 9304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(ctxt->atoms); 9314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 9324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->counters != NULL) 9334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(ctxt->counters); 9344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(ctxt); 9354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 9364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 9374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 938f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 939f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Display of Data structures * 940f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 9414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 9424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 9434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 9444255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintAtomType(FILE *output, xmlRegAtomType type) { 9454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (type) { 9464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_EPSILON: 9474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "epsilon "); break; 9484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_CHARVAL: 9494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "charval "); break; 9504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_RANGES: 9514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "ranges "); break; 9524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SUBREG: 9534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "subexpr "); break; 9544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_STRING: 9554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "string "); break; 9564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_ANYCHAR: 9574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "anychar "); break; 9584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_ANYSPACE: 9594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "anyspace "); break; 9604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTSPACE: 9614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "notspace "); break; 9624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_INITNAME: 9634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "initname "); break; 9644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTINITNAME: 9654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "notinitname "); break; 9664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NAMECHAR: 9674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "namechar "); break; 9684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTNAMECHAR: 9694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "notnamechar "); break; 9704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_DECIMAL: 9714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "decimal "); break; 9724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTDECIMAL: 9734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "notdecimal "); break; 9744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_REALCHAR: 9754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "realchar "); break; 9764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTREALCHAR: 9774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "notrealchar "); break; 9784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER: 9794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "LETTER "); break; 9804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_UPPERCASE: 9814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "LETTER_UPPERCASE "); break; 9824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_LOWERCASE: 9834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "LETTER_LOWERCASE "); break; 9844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_TITLECASE: 9854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "LETTER_TITLECASE "); break; 9864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_MODIFIER: 9874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "LETTER_MODIFIER "); break; 9884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_OTHERS: 9894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "LETTER_OTHERS "); break; 9904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK: 9914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "MARK "); break; 9924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_NONSPACING: 9934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "MARK_NONSPACING "); break; 9944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_SPACECOMBINING: 9954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "MARK_SPACECOMBINING "); break; 9964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_ENCLOSING: 9974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "MARK_ENCLOSING "); break; 9984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER: 9994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NUMBER "); break; 10004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_DECIMAL: 10014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NUMBER_DECIMAL "); break; 10024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_LETTER: 10034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NUMBER_LETTER "); break; 10044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_OTHERS: 10054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NUMBER_OTHERS "); break; 10064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT: 10074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT "); break; 10084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_CONNECTOR: 10094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_CONNECTOR "); break; 10104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_DASH: 10114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_DASH "); break; 10124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_OPEN: 10134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_OPEN "); break; 10144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_CLOSE: 10154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_CLOSE "); break; 10164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_INITQUOTE: 10174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_INITQUOTE "); break; 10184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_FINQUOTE: 10194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_FINQUOTE "); break; 10204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_OTHERS: 10214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "PUNCT_OTHERS "); break; 10224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR: 10234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SEPAR "); break; 10244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_SPACE: 10254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SEPAR_SPACE "); break; 10264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_LINE: 10274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SEPAR_LINE "); break; 10284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_PARA: 10294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SEPAR_PARA "); break; 10304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL: 10314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SYMBOL "); break; 10324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_MATH: 10334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SYMBOL_MATH "); break; 10344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_CURRENCY: 10354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SYMBOL_CURRENCY "); break; 10364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_MODIFIER: 10374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SYMBOL_MODIFIER "); break; 10384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_OTHERS: 10394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "SYMBOL_OTHERS "); break; 10404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER: 10414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "OTHER "); break; 10424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_CONTROL: 10434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "OTHER_CONTROL "); break; 10444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_FORMAT: 10454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "OTHER_FORMAT "); break; 10464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_PRIVATE: 10474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "OTHER_PRIVATE "); break; 10484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_NA: 10494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "OTHER_NA "); break; 10504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_BLOCK_NAME: 10514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "BLOCK "); break; 10524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 10534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 10544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 10554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 10564255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintQuantType(FILE *output, xmlRegQuantType type) { 10574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (type) { 10584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_EPSILON: 10594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "epsilon "); break; 10604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_ONCE: 10614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "once "); break; 10624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_OPT: 10634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "? "); break; 10644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_MULT: 10654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "* "); break; 10664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_PLUS: 10674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "+ "); break; 10684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_RANGE: 10694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "range "); break; 10707646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard case XML_REGEXP_QUANT_ONCEONLY: 10717646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard fprintf(output, "onceonly "); break; 10727646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard case XML_REGEXP_QUANT_ALL: 10737646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard fprintf(output, "all "); break; 10744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 10754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 10764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 10774255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintRange(FILE *output, xmlRegRangePtr range) { 10784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " range: "); 10794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (range->neg) 10804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "negative "); 10814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintAtomType(output, range->type); 10824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%c - %c\n", range->start, range->end); 10834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 10844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 10854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 10864255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintAtom(FILE *output, xmlRegAtomPtr atom) { 10874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " atom: "); 10884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom == NULL) { 10894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NULL\n"); 10904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 10914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 10929efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if (atom->neg) 10939efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard fprintf(output, "not "); 10944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintAtomType(output, atom->type); 10954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintQuantType(output, atom->quant); 10964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->quant == XML_REGEXP_QUANT_RANGE) 10974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d-%d ", atom->min, atom->max); 10984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->type == XML_REGEXP_STRING) 10994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "'%s' ", (char *) atom->valuep); 11004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->type == XML_REGEXP_CHARVAL) 11014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "char %c\n", atom->codepoint); 11024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else if (atom->type == XML_REGEXP_RANGES) { 11034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 11044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d entries\n", atom->nbRanges); 11054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0; i < atom->nbRanges;i++) 11064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintRange(output, atom->ranges[i]); 11074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (atom->type == XML_REGEXP_SUBREG) { 11084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "start %d end %d\n", atom->start->no, atom->stop->no); 11094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 11104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "\n"); 11114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 11134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 11144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 11154255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintTrans(FILE *output, xmlRegTransPtr trans) { 11164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " trans: "); 11174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans == NULL) { 11184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NULL\n"); 11194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 11204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->to < 0) { 11224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "removed\n"); 11234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 11244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 1125567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (trans->nd != 0) { 1126567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (trans->nd == 2) 1127567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard fprintf(output, "last not determinist, "); 1128567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else 1129567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard fprintf(output, "not determinist, "); 1130567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 11314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->counter >= 0) { 11324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "counted %d, ", trans->counter); 11334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11348a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard if (trans->count == REGEXP_ALL_COUNTER) { 11358a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard fprintf(output, "all transition, "); 11368a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard } else if (trans->count >= 0) { 11374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "count based %d, ", trans->count); 11384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->atom == NULL) { 11404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "epsilon to %d\n", trans->to); 11414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 11424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->atom->type == XML_REGEXP_CHARVAL) 11444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "char %c ", trans->atom->codepoint); 11454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "atom %d, to %d\n", trans->atom->no, trans->to); 11464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 1147f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 11484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 11494255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintState(FILE *output, xmlRegStatePtr state) { 11504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 11514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 11524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " state: "); 11534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state == NULL) { 11544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NULL\n"); 11554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 11564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state->type == XML_REGEXP_START_STATE) 11584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "START "); 11594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state->type == XML_REGEXP_FINAL_STATE) 11604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "FINAL "); 1161f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 11624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d, %d transitions:\n", state->no, state->nbTrans); 11634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < state->nbTrans; i++) { 11644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintTrans(output, &(state->trans[i])); 11654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 11674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 116823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 11694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 11704255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegPrintCtxt(FILE *output, xmlRegParserCtxtPtr ctxt) { 11714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 11724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 11734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " ctxt: "); 11744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt == NULL) { 11754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NULL\n"); 11764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 11774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "'%s' ", ctxt->string); 11794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->error) 11804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "error "); 11814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->neg) 11824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "neg "); 11834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "\n"); 11844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d atoms:\n", ctxt->nbAtoms); 11854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < ctxt->nbAtoms; i++) { 11864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " %02d ", i); 11874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintAtom(output, ctxt->atoms[i]); 11884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom != NULL) { 11904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "current atom:\n"); 11914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintAtom(output, ctxt->atom); 11924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d states:", ctxt->nbStates); 11944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->start != NULL) 11954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " start: %d", ctxt->start->no); 11964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->end != NULL) 11974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " end: %d", ctxt->end->no); 11984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "\n"); 11994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < ctxt->nbStates; i++) { 12004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintState(output, ctxt->states[i]); 12014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d counters:\n", ctxt->nbCounters); 12034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < ctxt->nbCounters; i++) { 12044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " %d: min %d max %d\n", i, ctxt->counters[i].min, 12054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->counters[i].max); 12064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 120823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 12094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 12104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 1211f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 12124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Finite Automata structures manipulations * 1213f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 12144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 12154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1216f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic void 12174255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom, 12184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int neg, xmlRegAtomType type, int start, int end, 12194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *blockName) { 12204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegRangePtr range; 12214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 12224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom == NULL) { 12234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("add range: atom is NULL"); 12244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 12254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->type != XML_REGEXP_RANGES) { 12274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("add range: atom is not ranges"); 12284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 12294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->maxRanges == 0) { 12314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->maxRanges = 4; 12324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->ranges = (xmlRegRangePtr *) xmlMalloc(atom->maxRanges * 12334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegRangePtr)); 12344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->ranges == NULL) { 1235ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "adding ranges"); 12364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->maxRanges = 0; 12374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 12384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (atom->nbRanges >= atom->maxRanges) { 12404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegRangePtr *tmp; 12414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->maxRanges *= 2; 12424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegRangePtr *) xmlRealloc(atom->ranges, atom->maxRanges * 12434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegRangePtr)); 12444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 1245ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "adding ranges"); 12464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->maxRanges /= 2; 12474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 12484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->ranges = tmp; 12504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard range = xmlRegNewRange(ctxt, neg, type, start, end); 12524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (range == NULL) 12534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 12544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard range->blockName = blockName; 12554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->ranges[atom->nbRanges++] = range; 1256f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 12574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 12584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 12594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 12604255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegGetCounter(xmlRegParserCtxtPtr ctxt) { 12614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->maxCounters == 0) { 12624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxCounters = 4; 12634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->counters = (xmlRegCounter *) xmlMalloc(ctxt->maxCounters * 12644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegCounter)); 12654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->counters == NULL) { 1266ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating counter"); 12674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxCounters = 0; 12684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 12694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->nbCounters >= ctxt->maxCounters) { 12714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegCounter *tmp; 12724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxCounters *= 2; 12734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegCounter *) xmlRealloc(ctxt->counters, ctxt->maxCounters * 12744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegCounter)); 12754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 1276ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating counter"); 12774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxCounters /= 2; 12784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 12794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->counters = tmp; 12814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->counters[ctxt->nbCounters].min = -1; 12834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->counters[ctxt->nbCounters].max = -1; 12844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ctxt->nbCounters++); 12854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 12864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1287f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic int 12884255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegAtomPush(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) { 12894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom == NULL) { 12904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("atom push: atom is NULL"); 1291a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 12924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 12934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->maxAtoms == 0) { 12944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxAtoms = 4; 12954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atoms = (xmlRegAtomPtr *) xmlMalloc(ctxt->maxAtoms * 12964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegAtomPtr)); 12974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atoms == NULL) { 1298ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "pushing atom"); 12994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxAtoms = 0; 1300a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 13014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 13024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->nbAtoms >= ctxt->maxAtoms) { 13034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr *tmp; 13044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxAtoms *= 2; 13054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegAtomPtr *) xmlRealloc(ctxt->atoms, ctxt->maxAtoms * 13064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegAtomPtr)); 13074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 1308ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "allocating counter"); 13094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxAtoms /= 2; 1310a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 13114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 13124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atoms = tmp; 13134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 13144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->no = ctxt->nbAtoms; 13154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atoms[ctxt->nbAtoms++] = atom; 1316a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(0); 13174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 13184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1319f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic void 1320db68b74dc7ec531361a736de7769a3e8ce881f79Daniel VeillardxmlRegStateAddTransTo(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr target, 1321db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int from) { 1322db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (target->maxTransTo == 0) { 1323db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->maxTransTo = 8; 1324db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->transTo = (int *) xmlMalloc(target->maxTransTo * 1325db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard sizeof(int)); 1326db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (target->transTo == NULL) { 1327db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlRegexpErrMemory(ctxt, "adding transition"); 1328db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->maxTransTo = 0; 1329db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard return; 1330db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1331db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } else if (target->nbTransTo >= target->maxTransTo) { 1332db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int *tmp; 1333db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->maxTransTo *= 2; 1334db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard tmp = (int *) xmlRealloc(target->transTo, target->maxTransTo * 1335db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard sizeof(int)); 1336db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (tmp == NULL) { 1337db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlRegexpErrMemory(ctxt, "adding transition"); 1338db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->maxTransTo /= 2; 1339db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard return; 1340db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1341db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->transTo = tmp; 1342db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1343db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->transTo[target->nbTransTo] = from; 1344db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard target->nbTransTo++; 1345db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard} 1346db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard 1347f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic void 13484255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state, 13494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom, xmlRegStatePtr target, 13505de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard int counter, int count) { 1351f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack 1352f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack int nrtrans; 1353f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack 13544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state == NULL) { 13554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("add state: state is NULL"); 13564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 13574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 13584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (target == NULL) { 13594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("add state: target is NULL"); 13604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 13614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 1362f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack /* 1363f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack * Other routines follow the philosophy 'When in doubt, add a transition' 1364f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack * so we check here whether such a transition is already present and, if 1365f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack * so, silently ignore this request. 1366f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack */ 1367f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack 13685de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard for (nrtrans = state->nbTrans - 1; nrtrans >= 0; nrtrans--) { 13695de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegTransPtr trans = &(state->trans[nrtrans]); 13705de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard if ((trans->atom == atom) && 13715de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard (trans->to == target->no) && 13725de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard (trans->counter == counter) && 13735de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard (trans->count == count)) { 1374f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack#ifdef DEBUG_REGEXP_GRAPH 13755de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard printf("Ignoring duplicate transition from %d to %d\n", 13765de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard state->no, target->no); 1377f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack#endif 13785de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard return; 1379db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1380f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack } 1381f9b5fa2dec22e88683d96d0a2782c244df2ca766William M. Brack 13824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state->maxTrans == 0) { 1383db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard state->maxTrans = 8; 13844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans = (xmlRegTrans *) xmlMalloc(state->maxTrans * 13854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegTrans)); 13864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state->trans == NULL) { 1387ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "adding transition"); 13884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->maxTrans = 0; 13894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 13904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 13914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (state->nbTrans >= state->maxTrans) { 13924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegTrans *tmp; 13934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->maxTrans *= 2; 13944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegTrans *) xmlRealloc(state->trans, state->maxTrans * 13954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegTrans)); 13964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 1397ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "adding transition"); 13984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->maxTrans /= 2; 13994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 14004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 14014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans = tmp; 14024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 14034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 14044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Add trans from %d to %d ", state->no, target->no); 14058a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard if (count == REGEXP_ALL_COUNTER) 14062cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard printf("all transition\n"); 14074402ab420f68d9384bd6c2066c1676848d98d27cDaniel Veillard else if (count >= 0) 14082cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard printf("count based %d\n", count); 14094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else if (counter >= 0) 14102cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard printf("counted %d\n", counter); 14114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else if (atom == NULL) 14122cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard printf("epsilon transition\n"); 1413f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard else if (atom != NULL) 14142cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard xmlRegPrintAtom(stdout, atom); 14154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 14164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 14174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans[state->nbTrans].atom = atom; 14184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans[state->nbTrans].to = target->no; 14194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans[state->nbTrans].counter = counter; 14204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans[state->nbTrans].count = count; 1421567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard state->trans[state->nbTrans].nd = 0; 14224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->nbTrans++; 1423db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlRegStateAddTransTo(ctxt, target, state->no); 14244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 14254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1426a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillardstatic int 14274255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegStatePush(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state) { 1428a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (state == NULL) return(-1); 14294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->maxStates == 0) { 14304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxStates = 4; 14314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->states = (xmlRegStatePtr *) xmlMalloc(ctxt->maxStates * 14324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegStatePtr)); 14334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->states == NULL) { 1434ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "adding state"); 14354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxStates = 0; 1436a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 14374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 14384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->nbStates >= ctxt->maxStates) { 14394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr *tmp; 14404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxStates *= 2; 14414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegStatePtr *) xmlRealloc(ctxt->states, ctxt->maxStates * 14424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegStatePtr)); 14434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 1444ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(ctxt, "adding state"); 14454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->maxStates /= 2; 1446a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 14474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 14484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->states = tmp; 14494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 14504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->no = ctxt->nbStates; 14514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->states[ctxt->nbStates++] = state; 1452a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(0); 14534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 14544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 14554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 14567646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * xmlFAGenerateAllTransition: 1457441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 1458441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @from: the from state 1459441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @to: the target state or NULL for building a new one 1460441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @lax: 14617646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * 14627646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard */ 14637646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillardstatic void 14647646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlFAGenerateAllTransition(xmlRegParserCtxtPtr ctxt, 1465441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard xmlRegStatePtr from, xmlRegStatePtr to, 1466441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard int lax) { 14677646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if (to == NULL) { 14687646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard to = xmlRegNewState(ctxt); 14697646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard xmlRegStatePush(ctxt, to); 14707646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard ctxt->state = to; 14717646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard } 1472441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if (lax) 14735de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_LAX_COUNTER); 1474441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard else 14755de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_COUNTER); 14767646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard} 14777646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard 14787646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard/** 14794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAGenerateEpsilonTransition: 1480441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 1481441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @from: the from state 1482441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @to: the target state or NULL for building a new one 14834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 14844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 14854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 14864255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAGenerateEpsilonTransition(xmlRegParserCtxtPtr ctxt, 14874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr from, xmlRegStatePtr to) { 14884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) { 14894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to = xmlRegNewState(ctxt); 14904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePush(ctxt, to); 14914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->state = to; 14924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 14935de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, from, NULL, to, -1, -1); 14944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 14954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 14964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 14974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAGenerateCountedEpsilonTransition: 1498441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 1499441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @from: the from state 1500441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @to: the target state or NULL for building a new one 15014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * counter: the counter for that transition 15024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 15034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 15044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 15054255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAGenerateCountedEpsilonTransition(xmlRegParserCtxtPtr ctxt, 15064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr from, xmlRegStatePtr to, int counter) { 15074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) { 15084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to = xmlRegNewState(ctxt); 15094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePush(ctxt, to); 15104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->state = to; 15114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 15125de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, from, NULL, to, counter, -1); 15134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 15144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 15154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 15164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAGenerateCountedTransition: 1517441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 1518441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @from: the from state 1519441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @to: the target state or NULL for building a new one 15204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * counter: the counter for that transition 15214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 15224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 15234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 15244255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAGenerateCountedTransition(xmlRegParserCtxtPtr ctxt, 15254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr from, xmlRegStatePtr to, int counter) { 15264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) { 15274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to = xmlRegNewState(ctxt); 15284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePush(ctxt, to); 15294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->state = to; 15304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 15315de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, from, NULL, to, -1, counter); 15324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 15334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 15344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 15354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAGenerateTransitions: 1536441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 1537441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @from: the from state 1538441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @to: the target state or NULL for building a new one 1539441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @atom: the atom generating the transition 15404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 1541ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Returns 0 if success and -1 in case of error. 15424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 1543a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillardstatic int 15444255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, 15454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr to, xmlRegAtomPtr atom) { 154610bda629bf8fe279f02493f0921110c552be3171Daniel Veillard xmlRegStatePtr end; 154734b350048d1ee97c4f42dd6729a77b3f36753b3aDaniel Veillard int nullable = 0; 154810bda629bf8fe279f02493f0921110c552be3171Daniel Veillard 15494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom == NULL) { 15504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("genrate transition: atom == NULL"); 1551a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 15524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 15534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->type == XML_REGEXP_SUBREG) { 15544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 15554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * this is a subexpression handling one should not need to 1556ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * create a new node except for XML_REGEXP_QUANT_RANGE. 15574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 1558a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (xmlRegAtomPush(ctxt, atom) < 0) { 1559a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 1560a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 15614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((to != NULL) && (atom->stop != to) && 15624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (atom->quant != XML_REGEXP_QUANT_RANGE)) { 15634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 15644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Generate an epsilon transition to link to the target 15654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 15664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to); 1567aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard#ifdef DV 1568f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } else if ((to == NULL) && (atom->quant != XML_REGEXP_QUANT_RANGE) && 1569aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard (atom->quant != XML_REGEXP_QUANT_ONCE)) { 1570aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard to = xmlRegNewState(ctxt); 1571aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard xmlRegStatePush(ctxt, to); 1572aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard ctxt->state = to; 1573aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to); 1574aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard#endif 15754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 15764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (atom->quant) { 15774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_OPT: 15784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 157954eb0243c442292953b4a3df39568735039ebc82Daniel Veillard /* 158054eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * transition done to the state after end of atom. 158154eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * 1. set transition from atom start to new state 1582f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * 2. set transition from atom end to this state. 158354eb0243c442292953b4a3df39568735039ebc82Daniel Veillard */ 1584d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard if (to == NULL) { 1585d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->start, 0); 1586d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->stop, 1587d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard ctxt->state); 1588d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard } else { 1589d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->start, to); 1590d80d0728bfa1b3b7412aff01e520ecc0b8e3f14fDaniel Veillard } 15914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 15924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_MULT: 15934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 15944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->start, atom->stop); 15954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start); 15964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 15974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_PLUS: 15984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 15994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start); 16004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 16014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_RANGE: { 16024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int counter; 160376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegStatePtr inter, newstate; 16044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 16054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 160676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * create the final state now if needed 16074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 160876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (to != NULL) { 160976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard newstate = to; 161076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } else { 1611ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack newstate = xmlRegNewState(ctxt); 1612ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack xmlRegStatePush(ctxt, newstate); 161376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } 161476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 161576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* 161676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * The principle here is to use counted transition 161776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * to avoid explosion in the number of states in the 161876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * graph. This is clearly more complex but should not 161976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * be exploitable at runtime. 162076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard */ 162176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if ((atom->min == 0) && (atom->start0 == NULL)) { 162276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegAtomPtr copy; 162376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* 162476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * duplicate a transition based on atom to count next 162576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * occurences after 1. We cannot loop to atom->start 1626f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * directly because we need an epsilon transition to 162776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * newstate. 162876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard */ 162976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* ???? For some reason it seems we never reach that 163076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard case, I suppose this got optimized out before when 163176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard building the automata */ 1632c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard copy = xmlRegCopyAtom(ctxt, atom); 163376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (copy == NULL) 163476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(-1); 163576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard copy->quant = XML_REGEXP_QUANT_ONCE; 163676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard copy->min = 0; 163776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard copy->max = 0; 163876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 163976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (xmlFAGenerateTransitions(ctxt, atom->start, NULL, copy) 164076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard < 0) 164176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard return(-1); 164276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard inter = ctxt->state; 164376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard counter = xmlRegGetCounter(ctxt); 164476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ctxt->counters[counter].min = atom->min - 1; 164576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ctxt->counters[counter].max = atom->max - 1; 164676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* count the number of times we see it again */ 164776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlFAGenerateCountedEpsilonTransition(ctxt, inter, 164876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard atom->stop, counter); 164976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* allow a way out based on the count */ 165076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlFAGenerateCountedTransition(ctxt, inter, 165176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard newstate, counter); 165276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* and also allow a direct exit for 0 */ 1653ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack xmlFAGenerateEpsilonTransition(ctxt, atom->start, 165476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard newstate); 165576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard } else { 165676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* 165776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * either we need the atom at least once or there 165876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * is an atom->start0 allowing to easilly plug the 165976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * epsilon transition. 166076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard */ 166176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard counter = xmlRegGetCounter(ctxt); 166276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ctxt->counters[counter].min = atom->min - 1; 166376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ctxt->counters[counter].max = atom->max - 1; 166476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* count the number of times we see it again */ 166576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlFAGenerateCountedEpsilonTransition(ctxt, atom->stop, 166676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard atom->start, counter); 166776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* allow a way out based on the count */ 166876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlFAGenerateCountedTransition(ctxt, atom->stop, 166976d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard newstate, counter); 167076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* and if needed allow a direct exit for 0 */ 167176d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard if (atom->min == 0) 167276d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, atom->start0, 167376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard newstate); 167476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard 1675ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack } 16764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->min = 0; 16774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->max = 0; 16784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 16799a00fd2991433a6ce04075c91b3ac6b976bdd806Daniel Veillard ctxt->state = newstate; 16804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 16814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard default: 16824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 16834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 1684a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(0); 1685f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 1686567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((atom->min == 0) && (atom->max == 0) && 168799c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard (atom->quant == XML_REGEXP_QUANT_RANGE)) { 168899c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard /* 168999c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard * we can discard the atom and generate an epsilon transition instead 169099c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard */ 169199c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard if (to == NULL) { 169299c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard to = xmlRegNewState(ctxt); 169399c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard if (to != NULL) 169499c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard xmlRegStatePush(ctxt, to); 169599c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard else { 169699c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard return(-1); 169799c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard } 169899c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard } 169999c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, from, to); 170099c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard ctxt->state = to; 170199c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard xmlRegFreeAtom(atom); 170299c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard return(0); 1703567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 1704567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (to == NULL) { 1705567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard to = xmlRegNewState(ctxt); 1706567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (to != NULL) 1707567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegStatePush(ctxt, to); 1708567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else { 1709a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 17104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 1711f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 171210bda629bf8fe279f02493f0921110c552be3171Daniel Veillard end = to; 1713f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if ((atom->quant == XML_REGEXP_QUANT_MULT) || 171410bda629bf8fe279f02493f0921110c552be3171Daniel Veillard (atom->quant == XML_REGEXP_QUANT_PLUS)) { 171510bda629bf8fe279f02493f0921110c552be3171Daniel Veillard /* 171610bda629bf8fe279f02493f0921110c552be3171Daniel Veillard * Do not pollute the target state by adding transitions from 171710bda629bf8fe279f02493f0921110c552be3171Daniel Veillard * it as it is likely to be the shared target of multiple branches. 171810bda629bf8fe279f02493f0921110c552be3171Daniel Veillard * So isolate with an epsilon transition. 171910bda629bf8fe279f02493f0921110c552be3171Daniel Veillard */ 172010bda629bf8fe279f02493f0921110c552be3171Daniel Veillard xmlRegStatePtr tmp; 1721f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 172210bda629bf8fe279f02493f0921110c552be3171Daniel Veillard tmp = xmlRegNewState(ctxt); 172310bda629bf8fe279f02493f0921110c552be3171Daniel Veillard if (tmp != NULL) 172410bda629bf8fe279f02493f0921110c552be3171Daniel Veillard xmlRegStatePush(ctxt, tmp); 172510bda629bf8fe279f02493f0921110c552be3171Daniel Veillard else { 172610bda629bf8fe279f02493f0921110c552be3171Daniel Veillard return(-1); 172710bda629bf8fe279f02493f0921110c552be3171Daniel Veillard } 172810bda629bf8fe279f02493f0921110c552be3171Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, tmp, to); 172910bda629bf8fe279f02493f0921110c552be3171Daniel Veillard to = tmp; 17304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 1731567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (xmlRegAtomPush(ctxt, atom) < 0) { 1732567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(-1); 1733567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 173434b350048d1ee97c4f42dd6729a77b3f36753b3aDaniel Veillard if ((atom->quant == XML_REGEXP_QUANT_RANGE) && 173534b350048d1ee97c4f42dd6729a77b3f36753b3aDaniel Veillard (atom->min == 0) && (atom->max > 0)) { 173634b350048d1ee97c4f42dd6729a77b3f36753b3aDaniel Veillard nullable = 1; 173734b350048d1ee97c4f42dd6729a77b3f36753b3aDaniel Veillard atom->min = 1; 173834b350048d1ee97c4f42dd6729a77b3f36753b3aDaniel Veillard if (atom->max == 1) 173934b350048d1ee97c4f42dd6729a77b3f36753b3aDaniel Veillard atom->quant = XML_REGEXP_QUANT_OPT; 174034b350048d1ee97c4f42dd6729a77b3f36753b3aDaniel Veillard } 1741567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegStateAddTrans(ctxt, from, atom, to, -1, -1); 174210bda629bf8fe279f02493f0921110c552be3171Daniel Veillard ctxt->state = end; 17434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (atom->quant) { 17444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_OPT: 17454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 17464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, from, to); 17474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 17484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_MULT: 17494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 17504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, from, to); 17515de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1); 17524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 17534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_QUANT_PLUS: 17544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCE; 17555de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1); 17564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 1757f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case XML_REGEXP_QUANT_RANGE: 175834b350048d1ee97c4f42dd6729a77b3f36753b3aDaniel Veillard if (nullable) 17595657837103e9938b42135cb993f197d1235221e0William M. Brack xmlFAGenerateEpsilonTransition(ctxt, from, to); 17605657837103e9938b42135cb993f197d1235221e0William M. Brack break; 17614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard default: 17624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 17634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 1764a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(0); 17654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 17664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 17674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 17684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAReduceEpsilonTransitions: 1769441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 17704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @fromnr: the from state 1771f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @tonr: the to state 1772ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * @counter: should that transition be associated to a counted 17734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 17744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 17754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 17764255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int fromnr, 17774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int tonr, int counter) { 17784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int transnr; 17794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr from; 17804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr to; 17814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 17824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 17834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("xmlFAReduceEpsilonTransitions(%d, %d)\n", fromnr, tonr); 17844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 17854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard from = ctxt->states[fromnr]; 17864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (from == NULL) 17874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 17884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to = ctxt->states[tonr]; 17894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) 17904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 17914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((to->mark == XML_REGEXP_MARK_START) || 17924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (to->mark == XML_REGEXP_MARK_VISITED)) 17934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 17944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 17954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to->mark = XML_REGEXP_MARK_VISITED; 17964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to->type == XML_REGEXP_FINAL_STATE) { 17974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 17984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("State %d is final, so %d becomes final\n", tonr, fromnr); 17994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 18004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard from->type = XML_REGEXP_FINAL_STATE; 18014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 18024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (transnr = 0;transnr < to->nbTrans;transnr++) { 1803db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (to->trans[transnr].to < 0) 1804db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard continue; 18054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to->trans[transnr].atom == NULL) { 18064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 18074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Don't remove counted transitions 18084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Don't loop either 18094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 1810b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (to->trans[transnr].to != fromnr) { 1811b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (to->trans[transnr].count >= 0) { 1812b509f1543df71549969eeac076349e05d2f78044Daniel Veillard int newto = to->trans[transnr].to; 1813b509f1543df71549969eeac076349e05d2f78044Daniel Veillard 1814b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlRegStateAddTrans(ctxt, from, NULL, 1815f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ctxt->states[newto], 18165de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard -1, to->trans[transnr].count); 1817b509f1543df71549969eeac076349e05d2f78044Daniel Veillard } else { 18184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 1819b509f1543df71549969eeac076349e05d2f78044Daniel Veillard printf("Found epsilon trans %d from %d to %d\n", 1820b509f1543df71549969eeac076349e05d2f78044Daniel Veillard transnr, tonr, to->trans[transnr].to); 18214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 1822b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (to->trans[transnr].counter >= 0) { 1823b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlFAReduceEpsilonTransitions(ctxt, fromnr, 1824b509f1543df71549969eeac076349e05d2f78044Daniel Veillard to->trans[transnr].to, 1825b509f1543df71549969eeac076349e05d2f78044Daniel Veillard to->trans[transnr].counter); 1826b509f1543df71549969eeac076349e05d2f78044Daniel Veillard } else { 1827b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlFAReduceEpsilonTransitions(ctxt, fromnr, 1828b509f1543df71549969eeac076349e05d2f78044Daniel Veillard to->trans[transnr].to, 1829b509f1543df71549969eeac076349e05d2f78044Daniel Veillard counter); 1830b509f1543df71549969eeac076349e05d2f78044Daniel Veillard } 1831b509f1543df71549969eeac076349e05d2f78044Daniel Veillard } 18324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 18334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 18344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int newto = to->trans[transnr].to; 18354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1836b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (to->trans[transnr].counter >= 0) { 1837f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom, 1838f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ctxt->states[newto], 18395de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard to->trans[transnr].counter, -1); 1840b509f1543df71549969eeac076349e05d2f78044Daniel Veillard } else { 1841f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom, 18425de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard ctxt->states[newto], counter, -1); 1843b509f1543df71549969eeac076349e05d2f78044Daniel Veillard } 18444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 18454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 18464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to->mark = XML_REGEXP_MARK_NORMAL; 18474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 18484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 18494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 1850db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * xmlFAEliminateSimpleEpsilonTransitions: 1851db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * @ctxt: a regexp parser context 1852db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * 1853f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Eliminating general epsilon transitions can get costly in the general 1854db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * algorithm due to the large amount of generated new transitions and 1855db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * associated comparisons. However for simple epsilon transition used just 1856db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * to separate building blocks when generating the automata this can be 1857db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * reduced to state elimination: 1858db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * - if there exists an epsilon from X to Y 1859db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * - if there is no other transition from X 1860db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * then X and Y are semantically equivalent and X can be eliminated 1861db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * If X is the start state then make Y the start state, else replace the 1862db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard * target of all transitions to X by transitions to Y. 1863db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard */ 1864db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillardstatic void 1865db68b74dc7ec531361a736de7769a3e8ce881f79Daniel VeillardxmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) { 1866db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int statenr, i, j, newto; 1867db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlRegStatePtr state, tmp; 1868db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard 1869db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 1870db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard state = ctxt->states[statenr]; 1871db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (state == NULL) 1872db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard continue; 1873db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (state->nbTrans != 1) 1874db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard continue; 18750e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard if (state->type == XML_REGEXP_UNREACH_STATE) 18760e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard continue; 1877db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard /* is the only transition out a basic transition */ 1878db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if ((state->trans[0].atom == NULL) && 1879db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard (state->trans[0].to >= 0) && 1880db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard (state->trans[0].to != statenr) && 1881db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard (state->trans[0].counter < 0) && 1882db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard (state->trans[0].count < 0)) { 1883db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard newto = state->trans[0].to; 1884db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard 1885db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (state->type == XML_REGEXP_START_STATE) { 1886db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 1887db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard printf("Found simple epsilon trans from start %d to %d\n", 1888db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard statenr, newto); 1889f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#endif 1890db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } else { 1891db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 1892db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard printf("Found simple epsilon trans from %d to %d\n", 1893db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard statenr, newto); 1894f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#endif 1895db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard for (i = 0;i < state->nbTransTo;i++) { 1896db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard tmp = ctxt->states[state->transTo[i]]; 1897db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard for (j = 0;j < tmp->nbTrans;j++) { 1898db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (tmp->trans[j].to == statenr) { 1899db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 1900db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard printf("Changed transition %d on %d to go to %d\n", 1901db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard j, tmp->no, newto); 1902f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#endif 19030e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard tmp->trans[j].to = -1; 19040e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard xmlRegStateAddTrans(ctxt, tmp, tmp->trans[j].atom, 1905f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ctxt->states[newto], 19060e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard tmp->trans[j].counter, 19070e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard tmp->trans[j].count); 1908db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1909db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1910db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1911db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (state->type == XML_REGEXP_FINAL_STATE) 1912db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard ctxt->states[newto]->type = XML_REGEXP_FINAL_STATE; 1913db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard /* eliminate the transition completely */ 1914db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard state->nbTrans = 0; 1915db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard 19160e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard state->type = XML_REGEXP_UNREACH_STATE; 1917db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard 1918db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1919f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 1920db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1921db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 1922db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard} 1923db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard/** 19244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAEliminateEpsilonTransitions: 1925441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 19264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 19274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 19284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 19294255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAEliminateEpsilonTransitions(xmlRegParserCtxtPtr ctxt) { 19304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int statenr, transnr; 19314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state; 1932db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard int has_epsilon; 19334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1934a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (ctxt->states == NULL) return; 1935a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard 19360e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard /* 19370e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard * Eliminate simple epsilon transition and the associated unreachable 19380e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard * states. 19390e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard */ 1940db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlFAEliminateSimpleEpsilonTransitions(ctxt); 19410e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 19420e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard state = ctxt->states[statenr]; 19430e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard if ((state != NULL) && (state->type == XML_REGEXP_UNREACH_STATE)) { 19440e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard#ifdef DEBUG_REGEXP_GRAPH 19450e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard printf("Removed unreachable state %d\n", statenr); 19460e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard#endif 19470e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard xmlRegFreeState(state); 19480e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard ctxt->states[statenr] = NULL; 19490e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard } 19500e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard } 1951db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard 1952db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard has_epsilon = 0; 1953a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard 19544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 1955fcd18ff8f753dd7308b619476266f1a2ddcc8859Daniel Veillard * Build the completed transitions bypassing the epsilons 19564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Use a marking algorithm to avoid loops 1957fcd18ff8f753dd7308b619476266f1a2ddcc8859Daniel Veillard * Mark sink states too. 1958fcd18ff8f753dd7308b619476266f1a2ddcc8859Daniel Veillard * Process from the latests states backward to the start when 1959fcd18ff8f753dd7308b619476266f1a2ddcc8859Daniel Veillard * there is long cascading epsilon chains this minimize the 1960fcd18ff8f753dd7308b619476266f1a2ddcc8859Daniel Veillard * recursions and transition compares when adding the new ones 19614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 1962fcd18ff8f753dd7308b619476266f1a2ddcc8859Daniel Veillard for (statenr = ctxt->nbStates - 1;statenr >= 0;statenr--) { 19634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state = ctxt->states[statenr]; 19644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state == NULL) 19654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 1966cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((state->nbTrans == 0) && 1967cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (state->type != XML_REGEXP_FINAL_STATE)) { 1968cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard state->type = XML_REGEXP_SINK_STATE; 1969cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 19704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (transnr = 0;transnr < state->nbTrans;transnr++) { 19714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((state->trans[transnr].atom == NULL) && 19724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (state->trans[transnr].to >= 0)) { 19734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (state->trans[transnr].to == statenr) { 19744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->trans[transnr].to = -1; 19754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 19764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Removed loopback epsilon trans %d on %d\n", 19774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard transnr, statenr); 19784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 19794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (state->trans[transnr].count < 0) { 19804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int newto = state->trans[transnr].to; 19814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 19824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 19834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Found epsilon trans %d from %d to %d\n", 19844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard transnr, statenr, newto); 19854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 1986db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard has_epsilon = 1; 19870e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard state->trans[transnr].to = -2; 19880e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard state->mark = XML_REGEXP_MARK_START; 19894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAReduceEpsilonTransitions(ctxt, statenr, 19904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard newto, state->trans[transnr].counter); 19914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->mark = XML_REGEXP_MARK_NORMAL; 19924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 19934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 19944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Found counted transition %d on %d\n", 19954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard transnr, statenr); 19964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 19974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 19984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 19994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 20004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 20014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 20024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Eliminate the epsilon transitions 20034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 2004db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (has_epsilon) { 2005db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 2006db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard state = ctxt->states[statenr]; 2007db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if (state == NULL) 2008db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard continue; 2009db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard for (transnr = 0;transnr < state->nbTrans;transnr++) { 2010db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard xmlRegTransPtr trans = &(state->trans[transnr]); 2011db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard if ((trans->atom == NULL) && 2012db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard (trans->count < 0) && 2013db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard (trans->to >= 0)) { 2014db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard trans->to = -1; 2015db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard } 20164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 20174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 20184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 201923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 202023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 202123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Use this pass to detect unreachable states too 202223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 202323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 202423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard state = ctxt->states[statenr]; 202523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (state != NULL) 2026779af00750fa86045e94422287d67a2cf5723f65William M. Brack state->reached = XML_REGEXP_MARK_NORMAL; 202723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 202823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard state = ctxt->states[0]; 202923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (state != NULL) 2030779af00750fa86045e94422287d67a2cf5723f65William M. Brack state->reached = XML_REGEXP_MARK_START; 203123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard while (state != NULL) { 203223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegStatePtr target = NULL; 2033779af00750fa86045e94422287d67a2cf5723f65William M. Brack state->reached = XML_REGEXP_MARK_VISITED; 203423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 2035ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Mark all states reachable from the current reachable state 203623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 203723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (transnr = 0;transnr < state->nbTrans;transnr++) { 203823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if ((state->trans[transnr].to >= 0) && 203923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ((state->trans[transnr].atom != NULL) || 204023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard (state->trans[transnr].count >= 0))) { 204123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int newto = state->trans[transnr].to; 204223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 204323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (ctxt->states[newto] == NULL) 204423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard continue; 2045779af00750fa86045e94422287d67a2cf5723f65William M. Brack if (ctxt->states[newto]->reached == XML_REGEXP_MARK_NORMAL) { 2046779af00750fa86045e94422287d67a2cf5723f65William M. Brack ctxt->states[newto]->reached = XML_REGEXP_MARK_START; 204723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard target = ctxt->states[newto]; 204823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 204923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 205023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 2051cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard 205223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 205323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * find the next accessible state not explored 205423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 205523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (target == NULL) { 205623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (statenr = 1;statenr < ctxt->nbStates;statenr++) { 205723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard state = ctxt->states[statenr]; 2058779af00750fa86045e94422287d67a2cf5723f65William M. Brack if ((state != NULL) && (state->reached == 2059779af00750fa86045e94422287d67a2cf5723f65William M. Brack XML_REGEXP_MARK_START)) { 206023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard target = state; 206123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard break; 206223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 206323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 206423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 206523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard state = target; 206623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 206723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 206823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard state = ctxt->states[statenr]; 2069779af00750fa86045e94422287d67a2cf5723f65William M. Brack if ((state != NULL) && (state->reached == XML_REGEXP_MARK_NORMAL)) { 207023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 207123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("Removed unreachable state %d\n", statenr); 207223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 207323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegFreeState(state); 207423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ctxt->states[statenr] = NULL; 207523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 207623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 207723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 20784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 20794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2080567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillardstatic int 2081567a45b5e931388acf850d56f937f1f66ff0f860Daniel VeillardxmlFACompareRanges(xmlRegRangePtr range1, xmlRegRangePtr range2) { 2082567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int ret = 0; 2083567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2084567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range1->type == XML_REGEXP_RANGES) || 2085567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_RANGES) || 2086567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_SUBREG) || 2087567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range1->type == XML_REGEXP_SUBREG) || 2088567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range1->type == XML_REGEXP_STRING) || 2089567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_STRING)) 2090567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(-1); 2091567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2092567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* put them in order */ 2093567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (range1->type > range2->type) { 2094567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegRangePtr tmp; 2095567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2096567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard tmp = range1; 2097567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard range1 = range2; 2098567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard range2 = tmp; 2099567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2100567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range1->type == XML_REGEXP_ANYCHAR) || 2101567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_ANYCHAR)) { 2102567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2103567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else if ((range1->type == XML_REGEXP_EPSILON) || 2104567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_EPSILON)) { 2105567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(0); 2106567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else if (range1->type == range2->type) { 21079332b48f16123cac16a207425b3a0206e5da35c1Daniel Veillard if (range1->type != XML_REGEXP_CHARVAL) 21089332b48f16123cac16a207425b3a0206e5da35c1Daniel Veillard ret = 1; 21099332b48f16123cac16a207425b3a0206e5da35c1Daniel Veillard else if ((range1->end < range2->start) || 21109332b48f16123cac16a207425b3a0206e5da35c1Daniel Veillard (range2->end < range1->start)) 2111567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 21129332b48f16123cac16a207425b3a0206e5da35c1Daniel Veillard else 21139332b48f16123cac16a207425b3a0206e5da35c1Daniel Veillard ret = 1; 2114567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else if (range1->type == XML_REGEXP_CHARVAL) { 2115567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int codepoint; 2116567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int neg = 0; 2117567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2118567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* 2119567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * just check all codepoints in the range for acceptance, 2120567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * this is usually way cheaper since done only once at 2121f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * compilation than testing over and over at runtime or 2122567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * pushing too many states when evaluating. 2123567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard */ 2124567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (((range1->neg == 0) && (range2->neg != 0)) || 2125567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ((range1->neg != 0) && (range2->neg == 0))) 2126567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard neg = 1; 2127567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2128567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard for (codepoint = range1->start;codepoint <= range1->end ;codepoint++) { 2129567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = xmlRegCheckCharacterRange(range2->type, codepoint, 2130567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 0, range2->start, range2->end, 2131567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard range2->blockName); 2132567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (ret < 0) 2133567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(-1); 2134567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (((neg == 1) && (ret == 0)) || 2135567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ((neg == 0) && (ret == 1))) 2136567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(1); 2137567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2138567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(0); 2139567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else if ((range1->type == XML_REGEXP_BLOCK_NAME) || 2140567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_BLOCK_NAME)) { 2141567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (range1->type == range2->type) { 2142567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = xmlStrEqual(range1->blockName, range2->blockName); 2143567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else { 2144567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* 2145567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * comparing a block range with anything else is way 2146567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * too costly, and maintining the table is like too much 2147567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * memory too, so let's force the automata to save state 2148567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * here. 2149567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard */ 2150567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(1); 2151567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2152567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else if ((range1->type < XML_REGEXP_LETTER) || 2153567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type < XML_REGEXP_LETTER)) { 2154567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range1->type == XML_REGEXP_ANYSPACE) && 2155567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NOTSPACE)) 2156567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2157567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else if ((range1->type == XML_REGEXP_INITNAME) && 2158567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NOTINITNAME)) 2159567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2160567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else if ((range1->type == XML_REGEXP_NAMECHAR) && 2161567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NOTNAMECHAR)) 2162567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2163567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else if ((range1->type == XML_REGEXP_DECIMAL) && 2164567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NOTDECIMAL)) 2165567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2166567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else if ((range1->type == XML_REGEXP_REALCHAR) && 2167567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NOTREALCHAR)) 2168567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2169567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else { 2170567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* same thing to limit complexity */ 2171567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(1); 2172567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2173567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else { 2174567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2175567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* range1->type < range2->type here */ 2176567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard switch (range1->type) { 2177567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_LETTER: 2178567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* all disjoint except in the subgroups */ 2179567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_LETTER_UPPERCASE) || 2180567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_LETTER_LOWERCASE) || 2181567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_LETTER_TITLECASE) || 2182567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_LETTER_MODIFIER) || 2183567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_LETTER_OTHERS)) 2184567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2185567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2186567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_MARK: 2187567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_MARK_NONSPACING) || 2188567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_MARK_SPACECOMBINING) || 2189567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_MARK_ENCLOSING)) 2190567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2191567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2192567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_NUMBER: 2193567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_NUMBER_DECIMAL) || 2194567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NUMBER_LETTER) || 2195567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_NUMBER_OTHERS)) 2196567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2197567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2198567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_PUNCT: 2199567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_PUNCT_CONNECTOR) || 2200567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_PUNCT_DASH) || 2201567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_PUNCT_OPEN) || 2202567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_PUNCT_CLOSE) || 2203567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_PUNCT_INITQUOTE) || 2204567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_PUNCT_FINQUOTE) || 2205567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_PUNCT_OTHERS)) 2206567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2207567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2208567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_SEPAR: 2209567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_SEPAR_SPACE) || 2210567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_SEPAR_LINE) || 2211567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_SEPAR_PARA)) 2212567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2213567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2214567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_SYMBOL: 2215567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_SYMBOL_MATH) || 2216567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_SYMBOL_CURRENCY) || 2217567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_SYMBOL_MODIFIER) || 2218567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_SYMBOL_OTHERS)) 2219567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2220567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2221567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard case XML_REGEXP_OTHER: 2222567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type == XML_REGEXP_OTHER_CONTROL) || 2223567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_OTHER_FORMAT) || 2224567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type == XML_REGEXP_OTHER_PRIVATE)) 2225567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2226567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2227567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard default: 2228567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((range2->type >= XML_REGEXP_LETTER) && 2229567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (range2->type < XML_REGEXP_BLOCK_NAME)) 2230567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2231567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard else { 2232567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* safety net ! */ 2233567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(1); 2234567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2235567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2236567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2237567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (((range1->neg == 0) && (range2->neg != 0)) || 2238567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ((range1->neg != 0) && (range2->neg == 0))) 2239567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = !ret; 2240594e5dfb48ee6fbac1b64155839063648022fc57Daniel Veillard return(ret); 2241567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard} 2242567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2243e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard/** 2244fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * xmlFACompareAtomTypes: 2245fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * @type1: an atom type 2246fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * @type2: an atom type 2247fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * 2248fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * Compares two atoms type to check whether they intersect in some ways, 2249fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * this is used by xmlFACompareAtoms only 2250fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * 2251fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * Returns 1 if they may intersect and 0 otherwise 2252fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard */ 2253fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillardstatic int 2254fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel VeillardxmlFACompareAtomTypes(xmlRegAtomType type1, xmlRegAtomType type2) { 2255fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type1 == XML_REGEXP_EPSILON) || 2256fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type1 == XML_REGEXP_CHARVAL) || 2257fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type1 == XML_REGEXP_RANGES) || 2258fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type1 == XML_REGEXP_SUBREG) || 2259fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type1 == XML_REGEXP_STRING) || 2260fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type1 == XML_REGEXP_ANYCHAR)) 2261fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2262fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type2 == XML_REGEXP_EPSILON) || 2263fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 == XML_REGEXP_CHARVAL) || 2264fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 == XML_REGEXP_RANGES) || 2265fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 == XML_REGEXP_SUBREG) || 2266fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 == XML_REGEXP_STRING) || 2267fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 == XML_REGEXP_ANYCHAR)) 2268fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2269fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2270fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type1 == type2) return(1); 2271fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2272fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* simplify subsequent compares by making sure type1 < type2 */ 2273fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type1 > type2) { 2274fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard xmlRegAtomType tmp = type1; 2275fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard type1 = type2; 2276fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard type2 = tmp; 2277fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard } 2278fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard switch (type1) { 2279fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_ANYSPACE: /* \s */ 2280fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* can't be a letter, number, mark, pontuation, symbol */ 2281fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type2 == XML_REGEXP_NOTSPACE) || 2282fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_LETTER) && 2283fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_LETTER_OTHERS)) || 2284fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_NUMBER) && 2285fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_NUMBER_OTHERS)) || 2286fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_MARK) && 2287fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 2288fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_PUNCT) && 2289fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 2290fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SYMBOL) && 2291fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SYMBOL_OTHERS)) 2292fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ) return(0); 2293fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2294fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NOTSPACE: /* \S */ 2295fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2296fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_INITNAME: /* \l */ 2297fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* can't be a number, mark, separator, pontuation, symbol or other */ 2298fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type2 == XML_REGEXP_NOTINITNAME) || 2299fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_NUMBER) && 2300fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_NUMBER_OTHERS)) || 2301fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_MARK) && 2302fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 2303fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SEPAR) && 2304fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SEPAR_PARA)) || 2305fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_PUNCT) && 2306fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 2307fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SYMBOL) && 2308fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SYMBOL_OTHERS)) || 2309fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_OTHER) && 2310fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_OTHER_NA)) 2311fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ) return(0); 2312fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2313fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NOTINITNAME: /* \L */ 2314fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2315fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NAMECHAR: /* \c */ 2316fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* can't be a mark, separator, pontuation, symbol or other */ 2317fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type2 == XML_REGEXP_NOTNAMECHAR) || 2318fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_MARK) && 2319fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 2320fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_PUNCT) && 2321fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 2322fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SEPAR) && 2323fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SEPAR_PARA)) || 2324fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SYMBOL) && 2325fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SYMBOL_OTHERS)) || 2326fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_OTHER) && 2327fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_OTHER_NA)) 2328fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ) return(0); 2329fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2330fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NOTNAMECHAR: /* \C */ 2331fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2332fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_DECIMAL: /* \d */ 2333fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* can't be a letter, mark, separator, pontuation, symbol or other */ 2334fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type2 == XML_REGEXP_NOTDECIMAL) || 2335fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 == XML_REGEXP_REALCHAR) || 2336fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_LETTER) && 2337fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_LETTER_OTHERS)) || 2338fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_MARK) && 2339fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 2340fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_PUNCT) && 2341fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 2342fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SEPAR) && 2343fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SEPAR_PARA)) || 2344fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SYMBOL) && 2345fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SYMBOL_OTHERS)) || 2346fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_OTHER) && 2347fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_OTHER_NA)) 2348fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard )return(0); 2349fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2350fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NOTDECIMAL: /* \D */ 2351fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2352fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_REALCHAR: /* \w */ 2353fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* can't be a mark, separator, pontuation, symbol or other */ 2354fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((type2 == XML_REGEXP_NOTDECIMAL) || 2355fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_MARK) && 2356fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 2357fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_PUNCT) && 2358fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 2359fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SEPAR) && 2360fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SEPAR_PARA)) || 2361fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_SYMBOL) && 2362fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_SYMBOL_OTHERS)) || 2363fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ((type2 >= XML_REGEXP_OTHER) && 2364fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (type2 <= XML_REGEXP_OTHER_NA)) 2365fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard )return(0); 2366fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2367fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NOTREALCHAR: /* \W */ 2368fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2369fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* 2370fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * at that point we know both type 1 and type2 are from 2371fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * character categories are ordered and are different, 2372fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * it becomes simple because this is a partition 2373fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard */ 2374fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_LETTER: 2375fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_LETTER_OTHERS) 2376fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2377fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2378fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_LETTER_UPPERCASE: 2379fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_LETTER_LOWERCASE: 2380fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_LETTER_TITLECASE: 2381fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_LETTER_MODIFIER: 2382fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_LETTER_OTHERS: 2383fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2384fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_MARK: 2385fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_MARK_ENCLOSING) 2386fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2387fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2388fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_MARK_NONSPACING: 2389fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_MARK_SPACECOMBINING: 2390fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_MARK_ENCLOSING: 2391fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2392fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NUMBER: 2393fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_NUMBER_OTHERS) 2394fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2395fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2396fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NUMBER_DECIMAL: 2397fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NUMBER_LETTER: 2398fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_NUMBER_OTHERS: 2399fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2400fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT: 2401fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_PUNCT_OTHERS) 2402fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2403fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2404fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_CONNECTOR: 2405fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_DASH: 2406fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_OPEN: 2407fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_CLOSE: 2408fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_INITQUOTE: 2409fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_FINQUOTE: 2410fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_PUNCT_OTHERS: 2411fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2412fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SEPAR: 2413fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_SEPAR_PARA) 2414fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2415fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2416fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SEPAR_SPACE: 2417fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SEPAR_LINE: 2418fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SEPAR_PARA: 2419fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2420fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SYMBOL: 2421fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_SYMBOL_OTHERS) 2422fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2423fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2424fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SYMBOL_MATH: 2425fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SYMBOL_CURRENCY: 2426fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SYMBOL_MODIFIER: 2427fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_SYMBOL_OTHERS: 2428fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2429fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_OTHER: 2430fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (type2 <= XML_REGEXP_OTHER_NA) 2431fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2432fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2433fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_OTHER_CONTROL: 2434fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_OTHER_FORMAT: 2435fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_OTHER_PRIVATE: 2436fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_OTHER_NA: 2437fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2438fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard default: 2439fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2440fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard } 2441fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2442fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard} 2443fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2444fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard/** 2445fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * xmlFAEqualAtoms: 2446fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * @atom1: an atom 2447fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * @atom2: an atom 24481ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * @deep: if not set only compare string pointers 2449fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * 2450fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * Compares two atoms to check whether they are the same exactly 2451fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * this is used to remove equivalent transitions 2452fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * 2453fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * Returns 1 if same and 0 otherwise 2454fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard */ 2455fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillardstatic int 24561ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel VeillardxmlFAEqualAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) { 2457fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard int ret = 0; 2458fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2459fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (atom1 == atom2) 2460fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2461fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((atom1 == NULL) || (atom2 == NULL)) 2462fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2463fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2464fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (atom1->type != atom2->type) 2465fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2466fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard switch (atom1->type) { 2467fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_EPSILON: 2468fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = 0; 2469fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2470fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_STRING: 24711ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (!deep) 24721ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard ret = (atom1->valuep == atom2->valuep); 24731ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard else 24741ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard ret = xmlStrEqual((xmlChar *)atom1->valuep, 24751ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard (xmlChar *)atom2->valuep); 2476fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2477fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_CHARVAL: 2478fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = (atom1->codepoint == atom2->codepoint); 2479fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2480fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_RANGES: 2481fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* too hard to do in the general case */ 2482fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = 0; 2483fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard default: 2484fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2485fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard } 2486fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(ret); 2487fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard} 2488fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2489fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard/** 2490e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * xmlFACompareAtoms: 2491e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * @atom1: an atom 2492e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * @atom2: an atom 24931ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * @deep: if not set only compare string pointers 2494e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 2495567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * Compares two atoms to check whether they intersect in some ways, 2496fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard * this is used by xmlFAComputesDeterminism and xmlFARecurseDeterminism only 2497e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 2498e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * Returns 1 if yes and 0 otherwise 2499e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2500e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillardstatic int 25011ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel VeillardxmlFACompareAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) { 2502fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard int ret = 1; 25039efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 2504e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (atom1 == atom2) 2505e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(1); 2506e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if ((atom1 == NULL) || (atom2 == NULL)) 2507e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(0); 2508e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 2509fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if ((atom1->type == XML_REGEXP_ANYCHAR) || 2510fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard (atom2->type == XML_REGEXP_ANYCHAR)) 2511fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(1); 2512fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard 2513fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (atom1->type > atom2->type) { 2514567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegAtomPtr tmp; 2515567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard tmp = atom1; 2516567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard atom1 = atom2; 2517567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard atom2 = tmp; 2518fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard } 2519fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (atom1->type != atom2->type) { 2520fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = xmlFACompareAtomTypes(atom1->type, atom2->type); 2521fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard /* if they can't intersect at the type level break now */ 2522fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (ret == 0) 2523fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard return(0); 2524567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2525e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard switch (atom1->type) { 2526e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard case XML_REGEXP_STRING: 25271ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (!deep) 25281ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard ret = (atom1->valuep != atom2->valuep); 25291ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard else 25301ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard ret = xmlRegStrEqualWildcard((xmlChar *)atom1->valuep, 25311ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard (xmlChar *)atom2->valuep); 25329efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard break; 2533e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard case XML_REGEXP_EPSILON: 2534567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard goto not_determinist; 2535e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard case XML_REGEXP_CHARVAL: 2536567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (atom2->type == XML_REGEXP_CHARVAL) { 2537fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = (atom1->codepoint == atom2->codepoint); 2538567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } else { 2539fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = xmlRegCheckCharacter(atom2, atom1->codepoint); 2540fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (ret < 0) 2541fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard ret = 1; 2542fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard } 2543fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard break; 2544fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard case XML_REGEXP_RANGES: 2545fc011b7fb895ed3b43f6c2e5b7a6fbfc078da349Daniel Veillard if (atom2->type == XML_REGEXP_RANGES) { 2546567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int i, j, res; 2547567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegRangePtr r1, r2; 2548567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2549567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* 2550567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * need to check that none of the ranges eventually matches 2551567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard */ 2552567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard for (i = 0;i < atom1->nbRanges;i++) { 2553567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard for (j = 0;j < atom2->nbRanges;j++) { 2554567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard r1 = atom1->ranges[i]; 2555567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard r2 = atom2->ranges[j]; 2556567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard res = xmlFACompareRanges(r1, r2); 2557567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (res == 1) { 2558567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 1; 2559567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard goto done; 2560567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2561567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2562567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2563567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2564567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2565567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; 2566e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard default: 2567567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard goto not_determinist; 2568e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2569567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillarddone: 25706e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard if (atom1->neg != atom2->neg) { 25719efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard ret = !ret; 25726e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard } 2573567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (ret == 0) 2574567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(0); 2575567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillardnot_determinist: 2576567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard return(1); 2577e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard} 2578e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 2579e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard/** 2580e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * xmlFARecurseDeterminism: 2581e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * @ctxt: a regexp parser context 2582e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 2583e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * Check whether the associated regexp is determinist, 2584e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * should be called after xmlFAEliminateEpsilonTransitions() 2585e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 2586e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2587e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillardstatic int 2588e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel VeillardxmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state, 2589e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int to, xmlRegAtomPtr atom) { 2590e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int ret = 1; 2591567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int res; 25925de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard int transnr, nbTrans; 2593e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard xmlRegTransPtr t1; 25941ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard int deep = 1; 2595e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 2596e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (state == NULL) 2597e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(ret); 2598466fcdaa33258cf3633887222146b891d202cc6cDaniel Veillard if (state->markd == XML_REGEXP_MARK_VISITED) 2599466fcdaa33258cf3633887222146b891d202cc6cDaniel Veillard return(ret); 26001ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard 26011ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (ctxt->flags & AM_AUTOMATA_RNG) 26021ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard deep = 0; 26031ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard 26045de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard /* 26055de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard * don't recurse on transitions potentially added in the course of 26065de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard * the elimination. 26075de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard */ 26085de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard nbTrans = state->nbTrans; 26095de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard for (transnr = 0;transnr < nbTrans;transnr++) { 2610e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard t1 = &(state->trans[transnr]); 2611e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard /* 2612e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * check transitions conflicting with the one looked at 2613e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2614e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (t1->atom == NULL) { 26150e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard if (t1->to < 0) 2616e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 2617466fcdaa33258cf3633887222146b891d202cc6cDaniel Veillard state->markd = XML_REGEXP_MARK_VISITED; 2618567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard res = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to], 2619e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard to, atom); 2620466fcdaa33258cf3633887222146b891d202cc6cDaniel Veillard state->markd = 0; 2621567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (res == 0) { 2622567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2623aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard /* t1->nd = 1; */ 2624567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2625e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 2626e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2627e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (t1->to != to) 2628e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 26291ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (xmlFACompareAtoms(t1->atom, atom, deep)) { 2630567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2631567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* mark the transition as non-deterministic */ 2632567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard t1->nd = 1; 2633567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2634e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2635e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(ret); 2636e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard} 2637e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 2638e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard/** 2639e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * xmlFAComputesDeterminism: 2640e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * @ctxt: a regexp parser context 2641e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 2642e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * Check whether the associated regexp is determinist, 2643e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * should be called after xmlFAEliminateEpsilonTransitions() 2644e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 2645e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2646e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillardstatic int 2647e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel VeillardxmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) { 2648e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int statenr, transnr; 2649e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard xmlRegStatePtr state; 2650567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard xmlRegTransPtr t1, t2, last; 2651e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int i; 2652e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int ret = 1; 26531ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard int deep = 1; 2654e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 26554402ab420f68d9384bd6c2066c1676848d98d27cDaniel Veillard#ifdef DEBUG_REGEXP_GRAPH 26564402ab420f68d9384bd6c2066c1676848d98d27cDaniel Veillard printf("xmlFAComputesDeterminism\n"); 26574402ab420f68d9384bd6c2066c1676848d98d27cDaniel Veillard xmlRegPrintCtxt(stdout, ctxt); 26584402ab420f68d9384bd6c2066c1676848d98d27cDaniel Veillard#endif 2659e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (ctxt->determinist != -1) 2660e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(ctxt->determinist); 2661e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 26621ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (ctxt->flags & AM_AUTOMATA_RNG) 26631ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard deep = 0; 26641ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard 2665e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard /* 2666567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * First cleanup the automata removing cancelled transitions 2667e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2668e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 2669e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard state = ctxt->states[statenr]; 2670e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (state == NULL) 2671e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 26724f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard if (state->nbTrans < 2) 26734f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard continue; 2674e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard for (transnr = 0;transnr < state->nbTrans;transnr++) { 2675e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard t1 = &(state->trans[transnr]); 2676e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard /* 2677e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * Determinism checks in case of counted or all transitions 2678e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * will have to be handled separately 2679e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2680567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (t1->atom == NULL) { 2681aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard /* t1->nd = 1; */ 2682e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 2683567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2684e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (t1->to == -1) /* eliminated */ 2685e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 2686e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard for (i = 0;i < transnr;i++) { 2687e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard t2 = &(state->trans[i]); 2688e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (t2->to == -1) /* eliminated */ 2689e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard continue; 2690e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (t2->atom != NULL) { 2691e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (t1->to == t2->to) { 26921ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard /* 26931ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * Here we use deep because we want to keep the 26941ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * transitions which indicate a conflict 26951ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard */ 26961ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (xmlFAEqualAtoms(t1->atom, t2->atom, deep) && 269711e28e4dfb84804474a3d7a4bfb08bae8f00bc0aDaniel Veillard (t1->counter == t2->counter) && 269811e28e4dfb84804474a3d7a4bfb08bae8f00bc0aDaniel Veillard (t1->count == t2->count)) 2699ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack t2->to = -1; /* eliminated */ 2700567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2701567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2702567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2703567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2704567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2705567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2706567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* 2707567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * Check for all states that there aren't 2 transitions 2708567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * with the same atom and a different target. 2709567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard */ 2710567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 2711567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard state = ctxt->states[statenr]; 2712567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (state == NULL) 2713567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard continue; 2714567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (state->nbTrans < 2) 2715567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard continue; 2716567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard last = NULL; 2717567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard for (transnr = 0;transnr < state->nbTrans;transnr++) { 2718567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard t1 = &(state->trans[transnr]); 2719567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* 2720567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * Determinism checks in case of counted or all transitions 2721567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * will have to be handled separately 2722567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard */ 2723567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (t1->atom == NULL) { 2724567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard continue; 2725567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2726567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (t1->to == -1) /* eliminated */ 2727567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard continue; 2728567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard for (i = 0;i < transnr;i++) { 2729567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard t2 = &(state->trans[i]); 2730567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (t2->to == -1) /* eliminated */ 2731567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard continue; 2732567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (t2->atom != NULL) { 27331ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard /* 27341ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * But here we don't use deep because we want to 27351ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * find transitions which indicate a conflict 27361ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard */ 27371ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (xmlFACompareAtoms(t1->atom, t2->atom, 1)) { 2738567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ret = 0; 2739567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* mark the transitions as non-deterministic ones */ 2740567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard t1->nd = 1; 2741567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard t2->nd = 1; 2742567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard last = t1; 2743e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2744e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } else if (t1->to != -1) { 2745e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard /* 2746e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * do the closure in case of remaining specific 2747e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * epsilon transitions like choices or all 2748e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 2749e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard ret = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to], 2750e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard t2->to, t2->atom); 2751567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* don't shortcut the computation so all non deterministic 2752567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard transition get marked down 2753e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (ret == 0) 2754aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard return(0); 2755aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard */ 2756567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (ret == 0) { 2757567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard t1->nd = 1; 2758aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard /* t2->nd = 1; */ 2759567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard last = t1; 2760567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2761e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2762e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2763567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* don't shortcut the computation so all non deterministic 2764567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard transition get marked down 2765e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (ret == 0) 2766567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; */ 2767e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2768567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2769567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* 2770567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * mark specifically the last non-deterministic transition 2771567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * from a state since there is no need to set-up rollback 2772567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard * from it 2773567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard */ 2774567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if (last != NULL) { 2775567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard last->nd = 2; 2776567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard } 2777567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2778567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard /* don't shortcut the computation so all non deterministic 2779567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard transition get marked down 2780e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (ret == 0) 2781567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard break; */ 2782e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 2783567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard 2784e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard ctxt->determinist = ret; 2785e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(ret); 2786e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard} 2787e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 27884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 2789f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 27904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Routines to check input against transition atoms * 2791f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 27924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 27934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 27944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 27954255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, int neg, 27964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int start, int end, const xmlChar *blockName) { 27974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ret = 0; 27984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 27994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (type) { 28004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_STRING: 28014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SUBREG: 28024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_RANGES: 28034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_EPSILON: 28044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 28054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_ANYCHAR: 28064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ((codepoint != '\n') && (codepoint != '\r')); 28074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_CHARVAL: 28094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ((codepoint >= start) && (codepoint <= end)); 28104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTSPACE: 28124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard neg = !neg; 28134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_ANYSPACE: 28144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ((codepoint == '\n') || (codepoint == '\r') || 28154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (codepoint == '\t') || (codepoint == ' ')); 28164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTINITNAME: 28184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard neg = !neg; 28194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_INITNAME: 2820f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ret = (IS_LETTER(codepoint) || 28214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (codepoint == '_') || (codepoint == ':')); 28224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTNAMECHAR: 28244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard neg = !neg; 28254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NAMECHAR: 2826871611bb0325095b30559ff1edc1fdaa2ad5fd2fWilliam M. Brack ret = (IS_LETTER(codepoint) || IS_DIGIT(codepoint) || 28274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (codepoint == '.') || (codepoint == '-') || 28284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (codepoint == '_') || (codepoint == ':') || 2829871611bb0325095b30559ff1edc1fdaa2ad5fd2fWilliam M. Brack IS_COMBINING(codepoint) || IS_EXTENDER(codepoint)); 28304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTDECIMAL: 28324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard neg = !neg; 28334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_DECIMAL: 28344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatNd(codepoint); 28354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_REALCHAR: 28374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard neg = !neg; 28384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTREALCHAR: 28394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatP(codepoint); 28404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 0) 28414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatZ(codepoint); 28424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 0) 28434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatC(codepoint); 28444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER: 28464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatL(codepoint); 28474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_UPPERCASE: 28494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatLu(codepoint); 28504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_LOWERCASE: 28524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatLl(codepoint); 28534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_TITLECASE: 28554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatLt(codepoint); 28564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_MODIFIER: 28584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatLm(codepoint); 28594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_OTHERS: 28614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatLo(codepoint); 28624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK: 28644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatM(codepoint); 28654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_NONSPACING: 28674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatMn(codepoint); 28684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_SPACECOMBINING: 28704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatMc(codepoint); 28714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_ENCLOSING: 28734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatMe(codepoint); 28744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER: 28764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatN(codepoint); 28774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_DECIMAL: 28794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatNd(codepoint); 28804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_LETTER: 28824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatNl(codepoint); 28834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_OTHERS: 28854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatNo(codepoint); 28864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT: 28884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatP(codepoint); 28894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_CONNECTOR: 28914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPc(codepoint); 28924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_DASH: 28944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPd(codepoint); 28954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_OPEN: 28974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPs(codepoint); 28984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 28994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_CLOSE: 29004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPe(codepoint); 29014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_INITQUOTE: 29034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPi(codepoint); 29044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_FINQUOTE: 29064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPf(codepoint); 29074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_OTHERS: 29094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatPo(codepoint); 29104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR: 29124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatZ(codepoint); 29134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_SPACE: 29154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatZs(codepoint); 29164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_LINE: 29184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatZl(codepoint); 29194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_PARA: 29214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatZp(codepoint); 29224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL: 29244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatS(codepoint); 29254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_MATH: 29274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatSm(codepoint); 29284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_CURRENCY: 29304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatSc(codepoint); 29314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_MODIFIER: 29334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatSk(codepoint); 29344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_OTHERS: 29364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatSo(codepoint); 29374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER: 29394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatC(codepoint); 29404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_CONTROL: 29424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatCc(codepoint); 29434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_FORMAT: 29454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatCf(codepoint); 29464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_PRIVATE: 29484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsCatCo(codepoint); 29494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_NA: 29514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* ret = xmlUCSIsCatCn(codepoint); */ 29524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* Seems it doesn't exist anymore in recent Unicode releases */ 29534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 29544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_BLOCK_NAME: 29564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlUCSIsBlock(codepoint, (const char *) blockName); 29574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 29584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 29594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (neg) 29604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(!ret); 29614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 29624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 29634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 29644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 29654255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint) { 29664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i, ret = 0; 29674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegRangePtr range; 29684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2969871611bb0325095b30559ff1edc1fdaa2ad5fd2fWilliam M. Brack if ((atom == NULL) || (!IS_CHAR(codepoint))) 29704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 29714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 29724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (atom->type) { 29734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SUBREG: 29744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_EPSILON: 29754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 29764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_CHARVAL: 29774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(codepoint == atom->codepoint); 29784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_RANGES: { 29794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int accept = 0; 2980f2a1283564df8ded1942b231c60c3a7ae4ff748aDaniel Veillard 29814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < atom->nbRanges;i++) { 29824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard range = atom->ranges[i]; 2983f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard if (range->neg == 2) { 29844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacterRange(range->type, codepoint, 29854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 0, range->start, range->end, 29864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard range->blockName); 29874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret != 0) 29884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); /* excluded char */ 2989f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard } else if (range->neg) { 2990f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard ret = xmlRegCheckCharacterRange(range->type, codepoint, 2991f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard 0, range->start, range->end, 2992f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard range->blockName); 2993f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard if (ret == 0) 2994f2a1283564df8ded1942b231c60c3a7ae4ff748aDaniel Veillard accept = 1; 2995f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard else 2996f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard return(0); 29974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 29984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacterRange(range->type, codepoint, 29994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 0, range->start, range->end, 30004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard range->blockName); 30014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret != 0) 30024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard accept = 1; /* might still be excluded */ 30034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 30044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 30054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(accept); 30064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 30074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_STRING: 30084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("TODO: XML_REGEXP_STRING\n"); 30094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 30104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_ANYCHAR: 30114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_ANYSPACE: 30124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTSPACE: 30134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_INITNAME: 30144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTINITNAME: 30154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NAMECHAR: 30164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTNAMECHAR: 30174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_DECIMAL: 30184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTDECIMAL: 30194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_REALCHAR: 30204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NOTREALCHAR: 30214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER: 30224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_UPPERCASE: 30234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_LOWERCASE: 30244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_TITLECASE: 30254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_MODIFIER: 30264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_LETTER_OTHERS: 30274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK: 30284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_NONSPACING: 30294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_SPACECOMBINING: 30304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_MARK_ENCLOSING: 30314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER: 30324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_DECIMAL: 30334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_LETTER: 30344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_NUMBER_OTHERS: 30354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT: 30364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_CONNECTOR: 30374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_DASH: 30384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_OPEN: 30394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_CLOSE: 30404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_INITQUOTE: 30414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_FINQUOTE: 30424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_PUNCT_OTHERS: 30434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR: 30444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_SPACE: 30454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_LINE: 30464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SEPAR_PARA: 30474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL: 30484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_MATH: 30494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_CURRENCY: 30504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_MODIFIER: 30514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_SYMBOL_OTHERS: 30524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER: 30534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_CONTROL: 30544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_FORMAT: 30554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_PRIVATE: 30564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_OTHER_NA: 30574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_REGEXP_BLOCK_NAME: 30584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacterRange(atom->type, codepoint, 0, 0, 0, 30594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (const xmlChar *)atom->valuep); 30604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom->neg) 30614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = !ret; 30624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 30634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 30644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 30654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 30664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 30674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 3068f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 3069ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Saving and restoring state of an execution context * 3070f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 30714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 30724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 30734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 30744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 30754255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegDebugExec(xmlRegExecCtxtPtr exec) { 30764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("state: %d:%d:idx %d", exec->state->no, exec->transno, exec->index); 30774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStack != NULL) { 30784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 30794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf(": "); 30804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;(i < 3) && (i < exec->inputStackNr);i++) 30810e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard printf("%s ", (const char *) 30820e05f4c2e0bf18930d4019426de31c9ae4d6411aDaniel Veillard exec->inputStack[exec->inputStackNr - (i + 1)].value); 30834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 30844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf(": %s", &(exec->inputString[exec->index])); 30854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 30864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("\n"); 30874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 30884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 30894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 30904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 30914255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegExecSave(xmlRegExecCtxtPtr exec) { 30924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 30934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("saving "); 30944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno++; 30954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegDebugExec(exec); 30964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno--; 30974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 309894cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard#ifdef MAX_PUSH 309994cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard if (exec->nbPush > MAX_PUSH) { 310094cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard return; 310194cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard } 310294cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard exec->nbPush++; 310394cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard#endif 31044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 31054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->maxRollbacks == 0) { 31064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks = 4; 31074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks = (xmlRegExecRollback *) xmlMalloc(exec->maxRollbacks * 31084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sizeof(xmlRegExecRollback)); 31094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks == NULL) { 3110ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "saving regexp"); 31114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks = 0; 31124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 31134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(exec->rollbacks, 0, 31154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks * sizeof(xmlRegExecRollback)); 31164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (exec->nbRollbacks >= exec->maxRollbacks) { 31174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegExecRollback *tmp; 31184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int len = exec->maxRollbacks; 31194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 31204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks *= 2; 31214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegExecRollback *) xmlRealloc(exec->rollbacks, 31224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks * sizeof(xmlRegExecRollback)); 31234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 3124ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "saving regexp"); 31254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks /= 2; 31264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 31274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks = tmp; 31294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = &exec->rollbacks[len]; 31304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(tmp, 0, (exec->maxRollbacks - len) * sizeof(xmlRegExecRollback)); 31314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks[exec->nbRollbacks].state = exec->state; 31334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks[exec->nbRollbacks].index = exec->index; 31344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks[exec->nbRollbacks].nextbranch = exec->transno + 1; 31354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->comp->nbCounters > 0) { 31364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks[exec->nbRollbacks].counts == NULL) { 31374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks[exec->nbRollbacks].counts = (int *) 31384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlMalloc(exec->comp->nbCounters * sizeof(int)); 31394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks[exec->nbRollbacks].counts == NULL) { 3140ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "saving regexp"); 31414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -5; 31424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 31434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memcpy(exec->rollbacks[exec->nbRollbacks].counts, exec->counts, 31464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->comp->nbCounters * sizeof(int)); 31474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->nbRollbacks++; 31494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 31504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 31514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 31524255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegExecRollBack(xmlRegExecCtxtPtr exec) { 31534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->nbRollbacks <= 0) { 31544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -1; 31554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 31564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("rollback failed on empty stack\n"); 31574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 31584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 31594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->nbRollbacks--; 31614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = exec->rollbacks[exec->nbRollbacks].state; 31624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index = exec->rollbacks[exec->nbRollbacks].index; 31634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = exec->rollbacks[exec->nbRollbacks].nextbranch; 31644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->comp->nbCounters > 0) { 31654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks[exec->nbRollbacks].counts == NULL) { 31664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(stderr, "exec save: allocation failed"); 31674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -6; 31684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 31694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31702671b013d88b381d8a9139ef85381234aafc5ce0Gaurav if (exec->counts) { 31712671b013d88b381d8a9139ef85381234aafc5ce0Gaurav memcpy(exec->counts, exec->rollbacks[exec->nbRollbacks].counts, 31724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->comp->nbCounters * sizeof(int)); 31732671b013d88b381d8a9139ef85381234aafc5ce0Gaurav } 31744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 31754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 31764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 31774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("restored "); 31784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegDebugExec(exec); 31794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 31804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 31814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 31824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 3183f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 3184ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Verifier, running an input against a compiled regexp * 3185f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 31864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 31874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 31884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 31894255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) { 31904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegExecCtxt execval; 31914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegExecCtxtPtr exec = &execval; 3192567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard int ret, codepoint = 0, len, deter; 31934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 31944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputString = content; 31954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index = 0; 319694cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard exec->nbPush = 0; 31974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->determinist = 1; 31984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks = 0; 31994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->nbRollbacks = 0; 32004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks = NULL; 32014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = 0; 32024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->comp = comp; 32034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = comp->states[0]; 32044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = 0; 32054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 0; 3206f2a1283564df8ded1942b231c60c3a7ae4ff748aDaniel Veillard exec->inputStack = NULL; 3207f2a1283564df8ded1942b231c60c3a7ae4ff748aDaniel Veillard exec->inputStackMax = 0; 32084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (comp->nbCounters > 0) { 32094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int)); 3210ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard if (exec->counts == NULL) { 3211ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "running regexp"); 32124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 3213ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard } 32144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(exec->counts, 0, comp->nbCounters * sizeof(int)); 32154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else 32164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->counts = NULL; 321740851d0c5975a8fde9498f72f3f5d96ad3194dc5Daniel Veillard while ((exec->status == 0) && (exec->state != NULL) && 32184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ((exec->inputString[exec->index] != 0) || 3219ad55998f74ab7f89cc5ed454589fb8f528873a02Daniel Veillard ((exec->state != NULL) && 3220ad55998f74ab7f89cc5ed454589fb8f528873a02Daniel Veillard (exec->state->type != XML_REGEXP_FINAL_STATE)))) { 32214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegTransPtr trans; 32224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 32234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 32244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 32250e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * If end of input on non-terminal state, rollback, however we may 32264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * still have epsilon like transition for counted transitions 32270e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * on counters, in that case don't break too early. Additionally, 32280e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * if we are working on a range like "AB{0,2}", where B is not present, 32290e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * we don't want to break. 32304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 323111ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard len = 1; 32320e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL)) { 3233ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack /* 3234ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * if there is a transition, we must check if 3235ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * atom allows minOccurs of 0 3236ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack */ 3237ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack if (exec->transno < exec->state->nbTrans) { 32380e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack trans = &exec->state->trans[exec->transno]; 32390e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack if (trans->to >=0) { 32400e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack atom = trans->atom; 32410e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack if (!((atom->min == 0) && (atom->max > 0))) 32420e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack goto rollback; 32430e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack } 32440e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack } else 32450e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack goto rollback; 32460e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack } 32474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 32484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 0; 32494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (;exec->transno < exec->state->nbTrans;exec->transno++) { 32504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard trans = &exec->state->trans[exec->transno]; 32514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->to < 0) 32524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 32534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom = trans->atom; 32544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 3255567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard deter = 1; 32564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->count >= 0) { 32574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int count; 32584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegCounterPtr counter; 32594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 326011ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (exec->counts == NULL) { 326111ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard exec->status = -1; 326211ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard goto error; 326311ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard } 32644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 32654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * A counted transition. 32664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 32674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 32684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard count = exec->counts[trans->count]; 32694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard counter = &exec->comp->counters[trans->count]; 32704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 32714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("testing count %d: val %d, min %d, max %d\n", 32724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard trans->count, count, counter->min, counter->max); 32734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 32744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ((count >= counter->min) && (count <= counter->max)); 3275567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((ret) && (counter->min != counter->max)) 3276567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard deter = 0; 32774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (atom == NULL) { 32784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(stderr, "epsilon transition left at runtime\n"); 32794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -2; 32804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 32814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (exec->inputString[exec->index] != 0) { 32824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len); 32834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacter(atom, codepoint); 32840e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack if ((ret == 1) && (atom->min >= 0) && (atom->max > 0)) { 32854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr to = comp->states[trans->to]; 32864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 32874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 32884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * this is a multiple input sequence 3289fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard * If there is a counter associated increment it now. 3290fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard * before potentially saving and rollback 3291c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard * do not increment if the counter is already over the 3292c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard * maximum limit in which case get to next transition 32934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 3294fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard if (trans->counter >= 0) { 3295c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard xmlRegCounterPtr counter; 3296c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard 3297c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard if ((exec->counts == NULL) || 3298c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard (exec->comp == NULL) || 3299c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard (exec->comp->counters == NULL)) { 330011ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard exec->status = -1; 330111ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard goto error; 330211ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard } 3303c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard counter = &exec->comp->counters[trans->counter]; 3304c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard if (exec->counts[trans->counter] >= counter->max) 3305c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard continue; /* for loop on transitions */ 3306c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard 3307fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard#ifdef DEBUG_REGEXP_EXEC 3308fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard printf("Increasing count %d\n", trans->counter); 3309fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard#endif 3310fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard exec->counts[trans->counter]++; 3311fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard } 33124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->state->nbTrans > exec->transno + 1) { 33134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 33144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 33154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 1; 33164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard do { 33174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 33184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Try to progress as much as possible on the input 33194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 33204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount == atom->max) { 33214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 33224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 33234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index += len; 33244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 33254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * End of input: stop here 33264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 33274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputString[exec->index] == 0) { 33284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index -= len; 33294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 33304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 33314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount >= atom->min) { 33324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int transno = exec->transno; 33334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state = exec->state; 33344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 33354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 33364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The transition is acceptable save it 33374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 33384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = -1; /* trick */ 33394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = to; 33404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 33414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = transno; 33424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = state; 33434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 33444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), 33454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard len); 33464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacter(atom, codepoint); 33474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount++; 33484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } while (ret == 1); 33494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount < atom->min) 33504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 33514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 33524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 33534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * If the last check failed but one transition was found 33544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * possible, rollback 33554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 33564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret < 0) 33574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 33584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 0) { 33594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto rollback; 33604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 3361fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard if (trans->counter >= 0) { 336211ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (exec->counts == NULL) { 336311ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard exec->status = -1; 336411ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard goto error; 336511ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard } 3366fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard#ifdef DEBUG_REGEXP_EXEC 3367fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard printf("Decreasing count %d\n", trans->counter); 3368fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard#endif 3369fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard exec->counts[trans->counter]--; 3370fc6eca0d8196f200da4bf4083b0d9dbc7079460aDaniel Veillard } 33710e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack } else if ((ret == 0) && (atom->min == 0) && (atom->max > 0)) { 33720e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack /* 33730e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * we don't match on the codepoint, but minOccurs of 0 33740e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * says that's ok. Setting len to 0 inhibits stepping 33750e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack * over the codepoint. 33760e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack */ 33770e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack exec->transcount = 1; 33780e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack len = 0; 33790e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack ret = 1; 33804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 33810e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack } else if ((atom->min == 0) && (atom->max > 0)) { 33820e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack /* another spot to match when minOccurs is 0 */ 33830e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack exec->transcount = 1; 33840e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack len = 0; 33850e00b28db65e0ad7f56e22874286682e90ffe9fbWilliam M. Brack ret = 1; 33864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 33874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 1) { 3388567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard if ((trans->nd == 1) || 3389567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard ((trans->count >= 0) && (deter == 0) && 3390567a45b5e931388acf850d56f937f1f66ff0f860Daniel Veillard (exec->state->nbTrans > exec->transno + 1))) { 3391aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 3392aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard if (trans->nd == 1) 3393aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard printf("Saving on nd transition atom %d for %c at %d\n", 3394aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard trans->atom->no, codepoint, exec->index); 3395aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard else 3396aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard printf("Saving on counted transition count %d for %c at %d\n", 3397aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard trans->count, codepoint, exec->index); 3398aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard#endif 33994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 34004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 34014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->counter >= 0) { 3402c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard xmlRegCounterPtr counter; 3403c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard 3404c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard /* make sure we don't go over the counter maximum value */ 3405c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard if ((exec->counts == NULL) || 3406c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard (exec->comp == NULL) || 3407c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard (exec->comp->counters == NULL)) { 3408c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard exec->status = -1; 340911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard goto error; 341011ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard } 3411c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard counter = &exec->comp->counters[trans->counter]; 3412c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard if (exec->counts[trans->counter] >= counter->max) 3413c821e03c66873f74d1eda5c6b4a7b0bb9ca9105bDaniel Veillard continue; /* for loop on transitions */ 34144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 34154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Increasing count %d\n", trans->counter); 34164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 34174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->counts[trans->counter]++; 34184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 341910752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard if ((trans->count >= 0) && 342010752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard (trans->count < REGEXP_ALL_COUNTER)) { 342111ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (exec->counts == NULL) { 342211ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard exec->status = -1; 342311ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard goto error; 342411ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard } 342510752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard#ifdef DEBUG_REGEXP_EXEC 342610752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard printf("resetting count %d on transition\n", 342710752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard trans->count); 342810752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard#endif 342910752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard exec->counts[trans->count] = 0; 343010752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard } 34314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 34324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("entering state %d\n", trans->to); 34334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 34344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = comp->states[trans->to]; 34354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = 0; 34364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->atom != NULL) { 34374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index += len; 34384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 34394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto progress; 34404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ret < 0) { 34414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -4; 34424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 34434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 34444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 34454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((exec->transno != 0) || (exec->state->nbTrans == 0)) { 34464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardrollback: 34474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 34484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Failed to find a way out 34494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 34504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->determinist = 0; 3451aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 3452aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard printf("rollback from state %d on %d:%c\n", exec->state->no, 3453aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard codepoint,codepoint); 3454aa62201290b6f3f3305f0fff504faf89c286a360Daniel Veillard#endif 34554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecRollBack(exec); 34564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 34574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardprogress: 34584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 34594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 346011ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillarderror: 34614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks != NULL) { 34624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->counts != NULL) { 34634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 34644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 34654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < exec->maxRollbacks;i++) 34664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks[i].counts != NULL) 34674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->rollbacks[i].counts); 34684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 34694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->rollbacks); 34704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 347140851d0c5975a8fde9498f72f3f5d96ad3194dc5Daniel Veillard if (exec->state == NULL) 347240851d0c5975a8fde9498f72f3f5d96ad3194dc5Daniel Veillard return(-1); 34734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->counts != NULL) 34744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->counts); 34754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->status == 0) 34764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 347794cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard if (exec->status == -1) { 347894cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard if (exec->nbPush > MAX_PUSH) 347994cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard return(-1); 34804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 348194cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard } 34824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(exec->status); 34834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 34844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 34854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 3486f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 3487ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Progressive interface to the verifier one atom at a time * 3488f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 34894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 34907bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#ifdef DEBUG_ERR 34917bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillardstatic void testerr(xmlRegExecCtxtPtr exec); 34927bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#endif 34934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 34944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 349501c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlRegNewExecCtxt: 34964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @comp: a precompiled regular expression 34974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @callback: a callback function used for handling progresses in the 34984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * automata matching phase 34994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @data: the context data associated to the callback in this context 35004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 35014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Build a context used for progressive evaluation of a regexp. 350201c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * 350301c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * Returns the new context 35044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 35054255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegExecCtxtPtr 35064255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegNewExecCtxt(xmlRegexpPtr comp, xmlRegExecCallbacks callback, void *data) { 35074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegExecCtxtPtr exec; 35084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 35094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (comp == NULL) 35104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 3511a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if ((comp->compact == NULL) && (comp->states == NULL)) 3512a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 35134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec = (xmlRegExecCtxtPtr) xmlMalloc(sizeof(xmlRegExecCtxt)); 35144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec == NULL) { 3515ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "creating execution context"); 35164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 35174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 35184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(exec, 0, sizeof(xmlRegExecCtxt)); 35194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputString = NULL; 35204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index = 0; 35214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->determinist = 1; 35224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->maxRollbacks = 0; 35234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->nbRollbacks = 0; 35244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->rollbacks = NULL; 35254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = 0; 35264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->comp = comp; 352723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (comp->compact == NULL) 352823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard exec->state = comp->states[0]; 35294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = 0; 35304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 0; 35314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->callback = callback; 35324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->data = data; 35334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (comp->nbCounters > 0) { 35347bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard /* 35357bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * For error handling, exec->counts is allocated twice the size 35367bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * the second half is used to store the data in case of rollback 35377bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard */ 35387bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int) 35397bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * 2); 35404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->counts == NULL) { 3541ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "creating execution context"); 35424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec); 35434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 35444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 35457bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard memset(exec->counts, 0, comp->nbCounters * sizeof(int) * 2); 35467bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->errCounts = &exec->counts[comp->nbCounters]; 35477bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } else { 35484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->counts = NULL; 35497bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->errCounts = NULL; 35507bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 35514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackMax = 0; 35524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackNr = 0; 35534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStack = NULL; 35547bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->errStateNo = -1; 35557bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->errString = NULL; 355694cc103b8cfcfb040b5aad121d7fbd928f6a1336Daniel Veillard exec->nbPush = 0; 35574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(exec); 35584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 35594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 35604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 35614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeExecCtxt: 35624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @exec: a regular expression evaulation context 35634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 35644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free the structures associated to a regular expression evaulation context. 35654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 35664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid 35674255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeExecCtxt(xmlRegExecCtxtPtr exec) { 35684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec == NULL) 35694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 35704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 35714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks != NULL) { 35724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->counts != NULL) { 35734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 35744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 35754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < exec->maxRollbacks;i++) 35764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->rollbacks[i].counts != NULL) 35774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->rollbacks[i].counts); 35784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 35794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->rollbacks); 35804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 35814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->counts != NULL) 35824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->counts); 35834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStack != NULL) { 35844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 35854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 35863237023d6a8036dff817c3d46485ce6495d8ae21Daniel Veillard for (i = 0;i < exec->inputStackNr;i++) { 35873237023d6a8036dff817c3d46485ce6495d8ae21Daniel Veillard if (exec->inputStack[i].value != NULL) 35883237023d6a8036dff817c3d46485ce6495d8ae21Daniel Veillard xmlFree(exec->inputStack[i].value); 35893237023d6a8036dff817c3d46485ce6495d8ae21Daniel Veillard } 35904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec->inputStack); 35914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 35927bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard if (exec->errString != NULL) 35937bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlFree(exec->errString); 35944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(exec); 35954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 35964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 35974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 35984255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFARegExecSaveInputString(xmlRegExecCtxtPtr exec, const xmlChar *value, 35994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard void *data) { 36004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 36014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("saving value: %d:%s\n", exec->inputStackNr, value); 36024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 36034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStackMax == 0) { 36044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackMax = 4; 3605f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard exec->inputStack = (xmlRegInputTokenPtr) 36064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlMalloc(exec->inputStackMax * sizeof(xmlRegInputToken)); 36074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStack == NULL) { 3608ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "pushing input string"); 36094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackMax = 0; 36104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 36114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 36124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (exec->inputStackNr + 1 >= exec->inputStackMax) { 36134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegInputTokenPtr tmp; 36144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 36154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackMax *= 2; 36164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = (xmlRegInputTokenPtr) xmlRealloc(exec->inputStack, 36174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackMax * sizeof(xmlRegInputToken)); 36184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp == NULL) { 3619ff46a0443e6b999297e52c160b88536b8089ec56Daniel Veillard xmlRegexpErrMemory(NULL, "pushing input string"); 36204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackMax /= 2; 36214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 36224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 36234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStack = tmp; 36244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 36254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStack[exec->inputStackNr].value = xmlStrdup(value); 36264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStack[exec->inputStackNr].data = data; 36274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStackNr++; 36284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStack[exec->inputStackNr].value = NULL; 36294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->inputStack[exec->inputStackNr].data = NULL; 36304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 36314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 3632c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard/** 3633c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * xmlRegStrEqualWildcard: 3634f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @expStr: the string to be evaluated 3635c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * @valStr: the validation string 3636c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * 3637c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * Checks if both strings are equal or have the same content. "*" 3638f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * can be used as a wildcard in @valStr; "|" is used as a seperator of 3639c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * substrings in both @expStr and @valStr. 3640c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * 3641c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * Returns 1 if the comparison is satisfied and the number of substrings 3642c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * is equal, 0 otherwise. 3643c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard */ 3644c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard 3645c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillardstatic int 3646c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel VeillardxmlRegStrEqualWildcard(const xmlChar *expStr, const xmlChar *valStr) { 3647c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (expStr == valStr) return(1); 3648c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (expStr == NULL) return(0); 3649c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (valStr == NULL) return(0); 3650c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard do { 3651c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard /* 3652c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard * Eval if we have a wildcard for the current item. 3653c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard */ 3654c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (*expStr != *valStr) { 36554f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard /* if one of them starts with a wildcard make valStr be it */ 36564f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard if (*valStr == '*') { 36574f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard const xmlChar *tmp; 36584f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard 36594f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard tmp = valStr; 36604f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard valStr = expStr; 36614f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard expStr = tmp; 36624f82c8a161404d1fe6ca9fe6edb404df00e14f11Daniel Veillard } 3663c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if ((*valStr != 0) && (*expStr != 0) && (*expStr++ == '*')) { 3664c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard do { 3665c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (*valStr == XML_REG_STRING_SEPARATOR) 3666c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard break; 3667c0e833f0024d46f50772620f24e6cf9d93748017Kasimier T. Buchcik valStr++; 3668c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard } while (*valStr != 0); 3669c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard continue; 3670c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard } else 3671c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard return(0); 3672c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard } 3673c0e833f0024d46f50772620f24e6cf9d93748017Kasimier T. Buchcik expStr++; 3674c0e833f0024d46f50772620f24e6cf9d93748017Kasimier T. Buchcik valStr++; 3675c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard } while (*valStr != 0); 3676c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (*expStr != 0) 3677c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard return (0); 3678c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard else 3679c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard return (1); 3680c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard} 36814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 36824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 368323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * xmlRegCompactPushString: 368423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * @exec: a regexp execution context 368523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * @comp: the precompiled exec with a compact table 368623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * @value: a string token input 368723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * @data: data associated to the token to reuse in callbacks 368823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * 368923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Push one input token in the execution context 369023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * 369123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Returns: 1 if the regexp reached a final state, 0 if non-final, and 369223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * a negative value in case of error. 369323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 369423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillardstatic int 369523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel VeillardxmlRegCompactPushString(xmlRegExecCtxtPtr exec, 369623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlRegexpPtr comp, 369723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard const xmlChar *value, 369823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard void *data) { 369923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int state = exec->index; 370023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int i, target; 370123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 370223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if ((comp == NULL) || (comp->compact == NULL) || (comp->stringMap == NULL)) 370323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(-1); 3704f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 370523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (value == NULL) { 370623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 370723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * are we at a final state ? 370823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 370923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (comp->compact[state * (comp->nbstrings + 1)] == 371023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard XML_REGEXP_FINAL_STATE) 371123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(1); 371223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(0); 371323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 371423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 371523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_PUSH 371623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("value pushed: %s\n", value); 371723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 371823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 371923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 3720ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Examine all outside transitions from current state 372123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 372223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0;i < comp->nbstrings;i++) { 372323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard target = comp->compact[state * (comp->nbstrings + 1) + i + 1]; 372423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if ((target > 0) && (target <= comp->nbstates)) { 3725f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard target--; /* to avoid 0 */ 3726c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard if (xmlRegStrEqualWildcard(comp->stringMap[i], value)) { 3727f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard exec->index = target; 3728118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if ((exec->callback != NULL) && (comp->transdata != NULL)) { 3729118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard exec->callback(exec->data, value, 3730118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard comp->transdata[state * comp->nbstrings + i], data); 3731118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard } 373223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_PUSH 373323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("entering state %d\n", target); 373423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 373523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (comp->compact[target * (comp->nbstrings + 1)] == 3736cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_SINK_STATE) 3737cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard goto error; 3738cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard 3739cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if (comp->compact[target * (comp->nbstrings + 1)] == 374023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard XML_REGEXP_FINAL_STATE) 374123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(1); 374223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(0); 374323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 374423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 374523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 374623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* 374723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Failed to find an exit transition out from current state for the 374823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * current token 374923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 375023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#ifdef DEBUG_PUSH 375123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard printf("failed to find a transition for %s on state %d\n", value, state); 375223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard#endif 3753cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillarderror: 37547bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard if (exec->errString != NULL) 37557bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlFree(exec->errString); 37567bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->errString = xmlStrdup(value); 37577bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard exec->errStateNo = state; 375823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard exec->status = -1; 37597bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#ifdef DEBUG_ERR 37607bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard testerr(exec); 37617bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#endif 376223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(-1); 376323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard} 376423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 376523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard/** 37666e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * xmlRegExecPushStringInternal: 3767ea7751d53bf497e873dca39b2c305e300e2574f9Daniel Veillard * @exec: a regexp execution context or NULL to indicate the end 37684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @value: a string token input 37694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @data: data associated to the token to reuse in callbacks 37706e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * @compound: value was assembled from 2 strings 37714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 37724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Push one input token in the execution context 37734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 37744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns: 1 if the regexp reached a final state, 0 if non-final, and 37754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * a negative value in case of error. 37764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 37776e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillardstatic int 37786e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel VeillardxmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value, 37796e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard void *data, int compound) { 37804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegTransPtr trans; 37814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 37824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ret; 37834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int final = 0; 37849070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard int progress = 1; 37854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 37864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec == NULL) 37874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 378823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (exec->comp == NULL) 378923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(-1); 37904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->status != 0) 37914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(exec->status); 37924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 379323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (exec->comp->compact != NULL) 379423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(xmlRegCompactPushString(exec, exec->comp, value, data)); 379523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 37964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (value == NULL) { 37974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->state->type == XML_REGEXP_FINAL_STATE) 37984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 37994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard final = 1; 38004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 38014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 38024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 38034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("value pushed: %s\n", value); 38044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 38054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 38064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * If we have an active rollback stack push the new value there 38074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * and get back to where we were left 38084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 38094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((value != NULL) && (exec->inputStackNr > 0)) { 38104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSaveInputString(exec, value, data); 38114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value = exec->inputStack[exec->index].value; 38124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard data = exec->inputStack[exec->index].data; 38134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 38144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("value loaded: %s\n", value); 38154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 38164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 38174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 38184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((exec->status == 0) && 38194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ((value != NULL) || 38204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ((final == 1) && 38214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (exec->state->type != XML_REGEXP_FINAL_STATE)))) { 38224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 38234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 38244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * End of input on non-terminal state, rollback, however we may 38254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * still have epsilon like transition for counted transitions 38264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * on counters, in that case don't break too early. 38274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 3828b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if ((value == NULL) && (exec->counts == NULL)) 38294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto rollback; 38304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 38314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 0; 38324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (;exec->transno < exec->state->nbTrans;exec->transno++) { 38334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard trans = &exec->state->trans[exec->transno]; 38344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->to < 0) 38354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 38364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom = trans->atom; 38374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 3838441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if (trans->count == REGEXP_ALL_LAX_COUNTER) { 3839441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard int i; 3840441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard int count; 3841441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard xmlRegTransPtr t; 3842441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard xmlRegCounterPtr counter; 3843441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard 3844441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard ret = 0; 3845441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard 3846441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard#ifdef DEBUG_PUSH 3847441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard printf("testing all lax %d\n", trans->count); 3848441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard#endif 3849441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard /* 3850441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * Check all counted transitions from the current state 3851441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard */ 3852441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if ((value == NULL) && (final)) { 3853441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard ret = 1; 3854441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } else if (value != NULL) { 3855441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard for (i = 0;i < exec->state->nbTrans;i++) { 3856441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard t = &exec->state->trans[i]; 3857441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if ((t->counter < 0) || (t == trans)) 3858441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard continue; 3859441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard counter = &exec->comp->counters[t->counter]; 3860441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard count = exec->counts[t->counter]; 3861f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if ((count < counter->max) && 3862441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard (t->atom != NULL) && 3863441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard (xmlStrEqual(value, t->atom->valuep))) { 3864441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard ret = 0; 3865441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard break; 3866441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } 3867441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if ((count >= counter->min) && 3868441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard (count < counter->max) && 386911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard (t->atom != NULL) && 3870441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard (xmlStrEqual(value, t->atom->valuep))) { 3871441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard ret = 1; 3872441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard break; 3873441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } 3874441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } 3875441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } 3876441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } else if (trans->count == REGEXP_ALL_COUNTER) { 38778a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard int i; 38788a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard int count; 38798a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard xmlRegTransPtr t; 38808a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard xmlRegCounterPtr counter; 38818a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard 38828a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard ret = 1; 38838a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard 38848a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard#ifdef DEBUG_PUSH 38858a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard printf("testing all %d\n", trans->count); 38868a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard#endif 38878a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard /* 38888a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard * Check all counted transitions from the current state 38898a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard */ 38908a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard for (i = 0;i < exec->state->nbTrans;i++) { 38918a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard t = &exec->state->trans[i]; 38928a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard if ((t->counter < 0) || (t == trans)) 38938a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard continue; 38948a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard counter = &exec->comp->counters[t->counter]; 38958a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard count = exec->counts[t->counter]; 38968a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard if ((count < counter->min) || (count > counter->max)) { 38978a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard ret = 0; 38988a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard break; 38998a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard } 39008a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard } 39018a001f62c195f956c7655df7464ff753b28bc957Daniel Veillard } else if (trans->count >= 0) { 39024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int count; 39034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegCounterPtr counter; 39044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 39054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 39064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * A counted transition. 39074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 39084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 39094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard count = exec->counts[trans->count]; 39104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard counter = &exec->comp->counters[trans->count]; 39114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 39124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("testing count %d: val %d, min %d, max %d\n", 39134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard trans->count, count, counter->min, counter->max); 39144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 39154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ((count >= counter->min) && (count <= counter->max)); 39164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (atom == NULL) { 39174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(stderr, "epsilon transition left at runtime\n"); 39184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -2; 39194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 39204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (value != NULL) { 3921c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard ret = xmlRegStrEqualWildcard(atom->valuep, value); 39226e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard if (atom->neg) { 39239efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard ret = !ret; 39246e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard if (!compound) 39256e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard ret = 0; 39266e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard } 3927441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if ((ret == 1) && (trans->counter >= 0)) { 3928441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard xmlRegCounterPtr counter; 3929441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard int count; 3930441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard 3931441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard count = exec->counts[trans->counter]; 3932441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard counter = &exec->comp->counters[trans->counter]; 3933441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard if (count >= counter->max) 3934441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard ret = 0; 3935441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard } 3936441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard 39374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) { 39384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr to = exec->comp->states[trans->to]; 39394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 39404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 39414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * this is a multiple input sequence 39424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 39434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->state->nbTrans > exec->transno + 1) { 39444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStackNr <= 0) { 39454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSaveInputString(exec, value, data); 39464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 39484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 1; 39504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard do { 39514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 39524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Try to progress as much as possible on the input 39534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 39544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount == atom->max) { 39554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 39564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index++; 39584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value = exec->inputStack[exec->index].value; 39594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard data = exec->inputStack[exec->index].data; 39604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 39614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("value loaded: %s\n", value); 39624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 39634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 39644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 39654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * End of input: stop here 39664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 39674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (value == NULL) { 39684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index --; 39694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 39704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount >= atom->min) { 39724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int transno = exec->transno; 39734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state = exec->state; 39744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 39754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 39764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The transition is acceptable save it 39774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 39784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = -1; /* trick */ 39794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = to; 39804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStackNr <= 0) { 39814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSaveInputString(exec, value, data); 39824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 39844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = transno; 39854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = state; 39864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 39874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlStrEqual(value, atom->valuep); 39884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount++; 39894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } while (ret == 1); 39904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount < atom->min) 39914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 39924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 39934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 39944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * If the last check failed but one transition was found 39954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * possible, rollback 39964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 39974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret < 0) 39984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 39994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 0) { 40004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto rollback; 40014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 1) { 40059887395b556af391306245b52487c215337c4054William M. Brack if ((exec->callback != NULL) && (atom != NULL) && 40069887395b556af391306245b52487c215337c4054William M. Brack (data != NULL)) { 40074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->callback(exec->data, atom->valuep, 40084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->data, data); 40094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->state->nbTrans > exec->transno + 1) { 40114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStackNr <= 0) { 40124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSaveInputString(exec, value, data); 40134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 40154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->counter >= 0) { 40174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 40184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Increasing count %d\n", trans->counter); 40194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 40204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->counts[trans->counter]++; 40214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 402210752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard if ((trans->count >= 0) && 402310752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard (trans->count < REGEXP_ALL_COUNTER)) { 402410752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard#ifdef DEBUG_REGEXP_EXEC 402510752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard printf("resetting count %d on transition\n", 402610752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard trans->count); 402710752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard#endif 402810752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard exec->counts[trans->count] = 0; 402910752284e3e3401725a2ab49fee1367201eeff6aDaniel Veillard } 40304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 40314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("entering state %d\n", trans->to); 40324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 4033cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((exec->comp->states[trans->to] != NULL) && 4034cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (exec->comp->states[trans->to]->type == 4035cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_SINK_STATE)) { 4036cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard /* 4037cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * entering a sink state, save the current state as error 4038cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * state. 4039cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard */ 4040cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if (exec->errString != NULL) 4041cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard xmlFree(exec->errString); 4042cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard exec->errString = xmlStrdup(value); 4043cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard exec->errState = exec->state; 4044cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard memcpy(exec->errCounts, exec->counts, 4045cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard exec->comp->nbCounters * sizeof(int)); 4046cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 40474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = exec->comp->states[trans->to]; 40484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = 0; 40494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->atom != NULL) { 40504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputStack != NULL) { 40514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index++; 40524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->index < exec->inputStackNr) { 40534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value = exec->inputStack[exec->index].value; 40544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard data = exec->inputStack[exec->index].data; 40554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 40564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("value loaded: %s\n", value); 40574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 40584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 40594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value = NULL; 40604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard data = NULL; 40614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 40624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("end of input\n"); 40634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 40644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 40664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value = NULL; 40674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard data = NULL; 40684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 40694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("end of input\n"); 40704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 40714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto progress; 40744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ret < 0) { 40754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -4; 40764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 40774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 40794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((exec->transno != 0) || (exec->state->nbTrans == 0)) { 40804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardrollback: 40819070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard /* 4082cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * if we didn't yet rollback on the current input 4083cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * store the current state as the error state. 40849070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard */ 4085cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((progress) && (exec->state != NULL) && 4086cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (exec->state->type != XML_REGEXP_SINK_STATE)) { 40879070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard progress = 0; 40889070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard if (exec->errString != NULL) 40899070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard xmlFree(exec->errString); 40909070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard exec->errString = xmlStrdup(value); 40919070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard exec->errState = exec->state; 40929070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard memcpy(exec->errCounts, exec->counts, 40939070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard exec->comp->nbCounters * sizeof(int)); 40949070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard } 40959070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard 40964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 40974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Failed to find a way out 40984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 40994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->determinist = 0; 41004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecRollBack(exec); 41012671b013d88b381d8a9139ef85381234aafc5ce0Gaurav if ((exec->inputStack != NULL ) && (exec->status == 0)) { 41024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value = exec->inputStack[exec->index].value; 41034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard data = exec->inputStack[exec->index].data; 41044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_PUSH 41054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("value loaded: %s\n", value); 41064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 41074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 41084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 41099070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard continue; 41104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardprogress: 41119070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard progress = 1; 41124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 41134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 41144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->status == 0) { 41154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(exec->state->type == XML_REGEXP_FINAL_STATE); 41164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 41177bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#ifdef DEBUG_ERR 41189070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard if (exec->status < 0) { 41197bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard testerr(exec); 41207bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 41219070015b406518e7215f04c0c17eb3cac3e9849bDaniel Veillard#endif 41224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(exec->status); 41234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 41244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 412552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard/** 41266e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * xmlRegExecPushString: 41276e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * @exec: a regexp execution context or NULL to indicate the end 41286e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * @value: a string token input 41296e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * @data: data associated to the token to reuse in callbacks 41306e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * 41316e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * Push one input token in the execution context 41326e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * 41336e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * Returns: 1 if the regexp reached a final state, 0 if non-final, and 41346e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * a negative value in case of error. 41356e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard */ 41366e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillardint 41376e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel VeillardxmlRegExecPushString(xmlRegExecCtxtPtr exec, const xmlChar *value, 41386e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard void *data) { 41396e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard return(xmlRegExecPushStringInternal(exec, value, data, 0)); 41406e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard} 41416e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard 41426e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard/** 414352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * xmlRegExecPushString2: 414452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @exec: a regexp execution context or NULL to indicate the end 414552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @value: the first string token input 414652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @value2: the second string token input 414752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @data: data associated to the token to reuse in callbacks 414852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * 414952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * Push one input token in the execution context 415052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * 415152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * Returns: 1 if the regexp reached a final state, 0 if non-final, and 415252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * a negative value in case of error. 415352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard */ 415452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillardint 415552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel VeillardxmlRegExecPushString2(xmlRegExecCtxtPtr exec, const xmlChar *value, 415652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard const xmlChar *value2, void *data) { 415752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard xmlChar buf[150]; 415852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard int lenn, lenp, ret; 415952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard xmlChar *str; 416052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 416152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (exec == NULL) 416252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(-1); 416352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (exec->comp == NULL) 416452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(-1); 416552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (exec->status != 0) 416652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(exec->status); 416752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 416852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (value2 == NULL) 416952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(xmlRegExecPushString(exec, value, data)); 417052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 417152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard lenn = strlen((char *) value2); 417252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard lenp = strlen((char *) value); 417352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 417452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (150 < lenn + lenp + 2) { 41753c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 417652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (str == NULL) { 417752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard exec->status = -1; 417852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(-1); 417952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard } 418052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard } else { 418152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard str = buf; 418252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard } 418352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard memcpy(&str[0], value, lenp); 4184c0826a7709eddbf10ade02f0ce80e5d077ac05f6Daniel Veillard str[lenp] = XML_REG_STRING_SEPARATOR; 418552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard memcpy(&str[lenp + 1], value2, lenn); 418652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard str[lenn + lenp + 1] = 0; 418752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 418852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (exec->comp->compact != NULL) 418952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard ret = xmlRegCompactPushString(exec, exec->comp, str, data); 419052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard else 41916e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard ret = xmlRegExecPushStringInternal(exec, str, data, 1); 419252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 419352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (str != buf) 41940b1ff14bd0c7c50f8cdce96478615570e1435c4fDaniel Veillard xmlFree(str); 419552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(ret); 419652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard} 419752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 41987bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard/** 419977005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard * xmlRegExecGetValues: 4200fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @exec: a regexp execution context 4201fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @err: error extraction or normal one 42027bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * @nbval: pointer to the number of accepted values IN/OUT 4203cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * @nbneg: return number of negative transitions 42047bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * @values: pointer to the array of acceptable values 4205fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @terminal: return value if this was a terminal state 42067bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * 4207fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * Extract informations from the regexp execution, internal routine to 4208fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * implement xmlRegExecNextValues() and xmlRegExecErrInfo() 42097bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * 42107bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard * Returns: 0 in case of success or -1 in case of error. 42117bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard */ 4212fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillardstatic int 4213fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel VeillardxmlRegExecGetValues(xmlRegExecCtxtPtr exec, int err, 4214cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard int *nbval, int *nbneg, 4215cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard xmlChar **values, int *terminal) { 42167bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int maxval; 4217cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard int nb = 0; 42187bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard 4219f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if ((exec == NULL) || (nbval == NULL) || (nbneg == NULL) || 4220cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (values == NULL) || (*nbval <= 0)) 42217bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard return(-1); 4222fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard 42237bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard maxval = *nbval; 42247bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard *nbval = 0; 4225cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard *nbneg = 0; 42267bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard if ((exec->comp != NULL) && (exec->comp->compact != NULL)) { 42277bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlRegexpPtr comp; 42287bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int target, i, state; 42297bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard 42307bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard comp = exec->comp; 4231fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard 4232fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (err) { 4233fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (exec->errStateNo == -1) return(-1); 4234fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard state = exec->errStateNo; 4235fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } else { 4236fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard state = exec->index; 4237fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } 4238fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (terminal != NULL) { 4239fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (comp->compact[state * (comp->nbstrings + 1)] == 4240fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard XML_REGEXP_FINAL_STATE) 4241fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard *terminal = 1; 4242fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard else 4243fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard *terminal = 0; 4244fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } 4245cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard for (i = 0;(i < comp->nbstrings) && (nb < maxval);i++) { 42467bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard target = comp->compact[state * (comp->nbstrings + 1) + i + 1]; 4247cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((target > 0) && (target <= comp->nbstates) && 4248cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (comp->compact[(target - 1) * (comp->nbstrings + 1)] != 4249cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_SINK_STATE)) { 4250cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard values[nb++] = comp->stringMap[i]; 42517bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard (*nbval)++; 42527bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 42537bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 4254cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard for (i = 0;(i < comp->nbstrings) && (nb < maxval);i++) { 4255cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard target = comp->compact[state * (comp->nbstrings + 1) + i + 1]; 4256cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((target > 0) && (target <= comp->nbstates) && 4257cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (comp->compact[(target - 1) * (comp->nbstrings + 1)] == 4258cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_SINK_STATE)) { 4259cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard values[nb++] = comp->stringMap[i]; 4260cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (*nbneg)++; 4261cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 4262cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 42637bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } else { 42647bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int transno; 42657bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlRegTransPtr trans; 42667bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard xmlRegAtomPtr atom; 4267fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard xmlRegStatePtr state; 4268fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard 4269fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (terminal != NULL) { 4270fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (exec->state->type == XML_REGEXP_FINAL_STATE) 4271fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard *terminal = 1; 4272fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard else 4273fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard *terminal = 0; 4274fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } 42757bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard 4276fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (err) { 4277fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (exec->errState == NULL) return(-1); 4278fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard state = exec->errState; 4279fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } else { 4280fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (exec->state == NULL) return(-1); 4281fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard state = exec->state; 4282fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } 42837bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard for (transno = 0; 4284cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (transno < state->nbTrans) && (nb < maxval); 42857bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard transno++) { 4286fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard trans = &state->trans[transno]; 42877bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard if (trans->to < 0) 42887bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard continue; 42897bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard atom = trans->atom; 42907bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard if ((atom == NULL) || (atom->valuep == NULL)) 42917bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard continue; 42927bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard if (trans->count == REGEXP_ALL_LAX_COUNTER) { 4293cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard /* this should not be reached but ... */ 42947bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard TODO; 42957bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } else if (trans->count == REGEXP_ALL_COUNTER) { 4296cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard /* this should not be reached but ... */ 42977bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard TODO; 42987bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } else if (trans->counter >= 0) { 429911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard xmlRegCounterPtr counter = NULL; 43007bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int count; 43017bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard 4302fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (err) 4303fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard count = exec->errCounts[trans->counter]; 4304fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard else 4305fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard count = exec->counts[trans->counter]; 430611ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (exec->comp != NULL) 430711ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard counter = &exec->comp->counters[trans->counter]; 430811ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if ((counter == NULL) || (count < counter->max)) { 430977005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard if (atom->neg) 431077005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard values[nb++] = (xmlChar *) atom->valuep2; 431177005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard else 431277005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard values[nb++] = (xmlChar *) atom->valuep; 43137bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard (*nbval)++; 43147bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 43157bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } else { 43162671b013d88b381d8a9139ef85381234aafc5ce0Gaurav if ((exec->comp != NULL) && (exec->comp->states[trans->to] != NULL) && 4317cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (exec->comp->states[trans->to]->type != 4318cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_SINK_STATE)) { 431977005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard if (atom->neg) 432077005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard values[nb++] = (xmlChar *) atom->valuep2; 432177005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard else 432277005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard values[nb++] = (xmlChar *) atom->valuep; 4323cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (*nbval)++; 4324cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 4325f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 4326cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 4327cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard for (transno = 0; 4328cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (transno < state->nbTrans) && (nb < maxval); 4329cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard transno++) { 4330cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard trans = &state->trans[transno]; 4331cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if (trans->to < 0) 4332cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard continue; 4333cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard atom = trans->atom; 4334cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((atom == NULL) || (atom->valuep == NULL)) 4335cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard continue; 4336cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if (trans->count == REGEXP_ALL_LAX_COUNTER) { 4337cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard continue; 4338cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } else if (trans->count == REGEXP_ALL_COUNTER) { 4339cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard continue; 4340cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } else if (trans->counter >= 0) { 4341cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard continue; 4342cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } else { 4343cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard if ((exec->comp->states[trans->to] != NULL) && 4344cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (exec->comp->states[trans->to]->type == 4345cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard XML_REGEXP_SINK_STATE)) { 434677005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard if (atom->neg) 434777005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard values[nb++] = (xmlChar *) atom->valuep2; 434877005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard else 434977005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard values[nb++] = (xmlChar *) atom->valuep; 4350cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard (*nbneg)++; 4351cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard } 4352f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 43537bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 43547bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard } 43557bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard return(0); 43567bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard} 43577bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard 4358fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard/** 4359fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * xmlRegExecNextValues: 4360fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @exec: a regexp execution context 4361fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @nbval: pointer to the number of accepted values IN/OUT 4362cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * @nbneg: return number of negative transitions 4363fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @values: pointer to the array of acceptable values 4364fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @terminal: return value if this was a terminal state 4365fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * 4366fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * Extract informations from the regexp execution, 4367fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * the parameter @values must point to an array of @nbval string pointers 4368fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * on return nbval will contain the number of possible strings in that 4369fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * state and the @values array will be updated with them. The string values 4370fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * returned will be freed with the @exec context and don't need to be 4371fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * deallocated. 4372fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * 4373fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * Returns: 0 in case of success or -1 in case of error. 4374fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard */ 4375fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillardint 4376cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel VeillardxmlRegExecNextValues(xmlRegExecCtxtPtr exec, int *nbval, int *nbneg, 4377cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard xmlChar **values, int *terminal) { 4378cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard return(xmlRegExecGetValues(exec, 0, nbval, nbneg, values, terminal)); 4379fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard} 4380fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard 4381fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard/** 4382fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * xmlRegExecErrInfo: 4383fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @exec: a regexp execution context generating an error 4384fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @string: return value for the error string 4385fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @nbval: pointer to the number of accepted values IN/OUT 4386cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard * @nbneg: return number of negative transitions 4387fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @values: pointer to the array of acceptable values 4388fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @terminal: return value if this was a terminal state 4389fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * 4390fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * Extract error informations from the regexp execution, the parameter 4391fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * @string will be updated with the value pushed and not accepted, 4392fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * the parameter @values must point to an array of @nbval string pointers 4393fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * on return nbval will contain the number of possible strings in that 4394fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * state and the @values array will be updated with them. The string values 4395fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * returned will be freed with the @exec context and don't need to be 4396fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * deallocated. 4397fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * 4398fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard * Returns: 0 in case of success or -1 in case of error. 4399fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard */ 4400fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillardint 4401fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel VeillardxmlRegExecErrInfo(xmlRegExecCtxtPtr exec, const xmlChar **string, 4402cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard int *nbval, int *nbneg, xmlChar **values, int *terminal) { 4403fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (exec == NULL) 4404fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard return(-1); 4405fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (string != NULL) { 4406fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard if (exec->status != 0) 4407fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard *string = exec->errString; 4408fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard else 4409fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard *string = NULL; 4410fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard } 4411cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard return(xmlRegExecGetValues(exec, 1, nbval, nbneg, values, terminal)); 4412fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard} 4413fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard 44147bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#ifdef DEBUG_ERR 44157bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillardstatic void testerr(xmlRegExecCtxtPtr exec) { 44167bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard const xmlChar *string; 4417cee2b3a5f124e19db46109132c22e1b8faec1c87Daniel Veillard xmlChar *values[5]; 44187bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard int nb = 5; 4419cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard int nbneg; 4420fc0b6f6adac16ea1bf2ca3bfe935e67d9e9fb974Daniel Veillard int terminal; 4421cc026dc6b069f38e8295bd4115e0620f4ede32adDaniel Veillard xmlRegExecErrInfo(exec, &string, &nb, &nbneg, &values[0], &terminal); 44227bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard} 44237bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard#endif 44247bd8b4b817db9f3bda399acdb9e5d9919d257e89Daniel Veillard 44254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#if 0 44264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 44274255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegExecPushChar(xmlRegExecCtxtPtr exec, int UCS) { 44284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegTransPtr trans; 44294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 44304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ret; 44314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int codepoint, len; 44324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec == NULL) 44344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 44354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->status != 0) 44364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(exec->status); 44374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((exec->status == 0) && 44394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ((exec->inputString[exec->index] != 0) || 44404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (exec->state->type != XML_REGEXP_FINAL_STATE))) { 44414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 44434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * End of input on non-terminal state, rollback, however we may 44444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * still have epsilon like transition for counted transitions 44454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * on counters, in that case don't break too early. 44464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 44474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL)) 44484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto rollback; 44494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 0; 44514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (;exec->transno < exec->state->nbTrans;exec->transno++) { 44524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard trans = &exec->state->trans[exec->transno]; 44534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->to < 0) 44544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 44554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom = trans->atom; 44564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 44574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->count >= 0) { 44584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int count; 44594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegCounterPtr counter; 44604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 44624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * A counted transition. 44634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 44644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard count = exec->counts[trans->count]; 44664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard counter = &exec->comp->counters[trans->count]; 44674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 44684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("testing count %d: val %d, min %d, max %d\n", 44694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard trans->count, count, counter->min, counter->max); 44704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 44714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ((count >= counter->min) && (count <= counter->max)); 44724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (atom == NULL) { 44734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(stderr, "epsilon transition left at runtime\n"); 44744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -2; 44754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 44764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (exec->inputString[exec->index] != 0) { 44774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len); 44784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacter(atom, codepoint); 44794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) { 44804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr to = exec->comp->states[trans->to]; 44814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 44824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 44834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * this is a multiple input sequence 44844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 44854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->state->nbTrans > exec->transno + 1) { 44864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 44874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 44884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount = 1; 44894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard do { 44904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 44914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Try to progress as much as possible on the input 44924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 44934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount == atom->max) { 44944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 44954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 44964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index += len; 44974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 44984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * End of input: stop here 44994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 45004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->inputString[exec->index] == 0) { 45014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index -= len; 45024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 45034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount >= atom->min) { 45054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int transno = exec->transno; 45064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr state = exec->state; 45074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 45084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 45094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The transition is acceptable save it 45104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 45114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = -1; /* trick */ 45124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = to; 45134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 45144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = transno; 45154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = state; 45164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), 45184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard len); 45194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegCheckCharacter(atom, codepoint); 45204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transcount++; 45214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } while (ret == 1); 45224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->transcount < atom->min) 45234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 45244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 45254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 45264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * If the last check failed but one transition was found 45274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * possible, rollback 45284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 45294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret < 0) 45304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = 0; 45314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 0) { 45324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto rollback; 45334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 1) { 45374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (exec->state->nbTrans > exec->transno + 1) { 45384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecSave(exec); 45394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 454054eb0243c442292953b4a3df39568735039ebc82Daniel Veillard /* 454154eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * restart count for expressions like this ((abc){2})* 454254eb0243c442292953b4a3df39568735039ebc82Daniel Veillard */ 454354eb0243c442292953b4a3df39568735039ebc82Daniel Veillard if (trans->count >= 0) { 454454eb0243c442292953b4a3df39568735039ebc82Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 454554eb0243c442292953b4a3df39568735039ebc82Daniel Veillard printf("Reset count %d\n", trans->count); 454654eb0243c442292953b4a3df39568735039ebc82Daniel Veillard#endif 454754eb0243c442292953b4a3df39568735039ebc82Daniel Veillard exec->counts[trans->count] = 0; 454854eb0243c442292953b4a3df39568735039ebc82Daniel Veillard } 45494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->counter >= 0) { 45504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 45514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("Increasing count %d\n", trans->counter); 45524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 45534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->counts[trans->counter]++; 45544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef DEBUG_REGEXP_EXEC 45564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard printf("entering state %d\n", trans->to); 45574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 45584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->state = exec->comp->states[trans->to]; 45594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->transno = 0; 45604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (trans->atom != NULL) { 45614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->index += len; 45624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard goto progress; 45644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ret < 0) { 45654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->status = -4; 45664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 45674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((exec->transno != 0) || (exec->state->nbTrans == 0)) { 45704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardrollback: 45714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* 45724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Failed to find a way out 45734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 45744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard exec->determinist = 0; 45754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFARegExecRollBack(exec); 45764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardprogress: 45784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard continue; 45794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 45804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 45814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif 45824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 4583f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 4584ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Parser for the Schemas Datatype Regular Expressions * 45854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#regexs * 4586f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 45874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 45884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 45894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 45904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAIsChar: 4591441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 45924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 45934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [10] Char ::= [^.\?*+()|#x5B#x5D] 45944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 45954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 45964255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAIsChar(xmlRegParserCtxtPtr ctxt) { 45974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int cur; 45984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int len; 45994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 46004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR_SCHAR(ctxt->cur, len); 46014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((cur == '.') || (cur == '\\') || (cur == '?') || 46024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == '*') || (cur == '+') || (cur == '(') || 46034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == ')') || (cur == '|') || (cur == 0x5B) || 46044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == 0x5D) || (cur == 0)) 46054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 46064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(cur); 46074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 46084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 46094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 46104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharProp: 4611441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 46124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 46134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [27] charProp ::= IsCategory | IsBlock 46144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [28] IsCategory ::= Letters | Marks | Numbers | Punctuation | 4615f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Separators | Symbols | Others 46164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [29] Letters ::= 'L' [ultmo]? 46174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [30] Marks ::= 'M' [nce]? 46184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [31] Numbers ::= 'N' [dlo]? 46194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [32] Punctuation ::= 'P' [cdseifo]? 46204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [33] Separators ::= 'Z' [slp]? 46214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [34] Symbols ::= 'S' [mcko]? 46224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [35] Others ::= 'C' [cfon]? 46234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [36] IsBlock ::= 'Is' [a-zA-Z0-9#x2D]+ 46244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 46254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 46264255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) { 46274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int cur; 4628779af00750fa86045e94422287d67a2cf5723f65William M. Brack xmlRegAtomType type = (xmlRegAtomType) 0; 46294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlChar *blockName = NULL; 4630f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 46314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 46324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'L') { 46334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 46354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'u') { 46364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_LETTER_UPPERCASE; 46384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'l') { 46394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_LETTER_LOWERCASE; 46414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 't') { 46424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_LETTER_TITLECASE; 46444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'm') { 46454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_LETTER_MODIFIER; 46474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'o') { 46484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_LETTER_OTHERS; 46504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 46514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_LETTER; 46524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 46534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'M') { 46544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 46564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'n') { 46574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* nonspacing */ 46594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_MARK_NONSPACING; 46604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'c') { 46614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* spacing combining */ 46634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_MARK_SPACECOMBINING; 46644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'e') { 46654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* enclosing */ 46674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_MARK_ENCLOSING; 46684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 46694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* all marks */ 46704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_MARK; 46714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 46724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'N') { 46734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 46754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'd') { 46764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* digital */ 46784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NUMBER_DECIMAL; 46794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'l') { 46804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* letter */ 46824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NUMBER_LETTER; 46834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'o') { 46844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* other */ 46864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NUMBER_OTHERS; 46874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 46884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* all numbers */ 46894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NUMBER; 46904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 46914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'P') { 46924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 46944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'c') { 46954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 46964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* connector */ 46974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_CONNECTOR; 46984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'd') { 46994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* dash */ 47014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_DASH; 47024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 's') { 47034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* open */ 47054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_OPEN; 47064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'e') { 47074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* close */ 47094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_CLOSE; 47104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'i') { 47114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* initial quote */ 47134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_INITQUOTE; 47144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'f') { 47154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* final quote */ 47174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_FINQUOTE; 47184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'o') { 47194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* other */ 47214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT_OTHERS; 47224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 47234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* all punctuation */ 47244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_PUNCT; 47254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 47264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'Z') { 47274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 47294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 's') { 47304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* space */ 47324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SEPAR_SPACE; 47334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'l') { 47344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* line */ 47364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SEPAR_LINE; 47374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'p') { 47384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* paragraph */ 47404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SEPAR_PARA; 47414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 47424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* all separators */ 47434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SEPAR; 47444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 47454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'S') { 47464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 47484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'm') { 47494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SYMBOL_MATH; 47514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* math */ 47524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'c') { 47534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SYMBOL_CURRENCY; 47554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* currency */ 47564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'k') { 47574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SYMBOL_MODIFIER; 47594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* modifiers */ 47604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'o') { 47614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SYMBOL_OTHERS; 47634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* other */ 47644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 47654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* all symbols */ 47664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_SYMBOL; 47674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 47684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'C') { 47694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 47714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'c') { 47724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* control */ 47744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_OTHER_CONTROL; 47754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'f') { 47764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* format */ 47784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_OTHER_FORMAT; 47794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'o') { 47804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* private use */ 47824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_OTHER_PRIVATE; 47834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'n') { 47844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* not assigned */ 47864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_OTHER_NA; 47874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 47884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* all others */ 47894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_OTHER; 47904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 47914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'I') { 47924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard const xmlChar *start; 47934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 47944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 47954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur != 's') { 47964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("IsXXXX expected"); 47974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 47984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 47994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard start = ctxt->cur; 48014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 4802f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (((cur >= 'a') && (cur <= 'z')) || 4803f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ((cur >= 'A') && (cur <= 'Z')) || 4804f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ((cur >= '0') && (cur <= '9')) || 48054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == 0x2D)) { 48064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 4808f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard while (((cur >= 'a') && (cur <= 'z')) || 4809f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ((cur >= 'A') && (cur <= 'Z')) || 4810f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ((cur >= '0') && (cur <= '9')) || 48114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == 0x2D)) { 48124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 48144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_BLOCK_NAME; 48174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard blockName = xmlStrndup(start, ctxt->cur - start); 48184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 48194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Unknown char property"); 48204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) { 48234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, type); 48244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom != NULL) 48254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->valuep = blockName; 48264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->atom->type == XML_REGEXP_RANGES) { 48274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 48284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type, 0, 0, blockName); 48294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 48314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 48324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 48334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharClassEsc: 4834441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 48354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 4836f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * [23] charClassEsc ::= ( SingleCharEsc | MultiCharEsc | catEsc | complEsc ) 48374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [24] SingleCharEsc ::= '\' [nrt\|.?*+(){}#x2D#x5B#x5D#x5E] 48384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [25] catEsc ::= '\p{' charProp '}' 48394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [26] complEsc ::= '\P{' charProp '}' 48404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [37] MultiCharEsc ::= '.' | ('\' [sSiIcCdDwW]) 48414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 48424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 48434255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharClassEsc(xmlRegParserCtxtPtr ctxt) { 48444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int cur; 48454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 48464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == '.') { 48474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) { 48484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_ANYCHAR); 48494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->atom->type == XML_REGEXP_RANGES) { 48504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 48514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_ANYCHAR, 0, 0, NULL); 48524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != '\\') { 48574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Escaped sequence: expecting \\"); 48584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 48624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == 'p') { 48634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != '{') { 48654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Expecting '{'"); 48664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharProp(ctxt); 48704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != '}') { 48714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Expecting '}'"); 48724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (cur == 'P') { 48764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != '{') { 48784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Expecting '{'"); 48794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharProp(ctxt); 48834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->neg = 1; 48844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != '}') { 48854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Expecting '}'"); 48864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 48874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 48884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 48894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if ((cur == 'n') || (cur == 'r') || (cur == 't') || (cur == '\\') || 48904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == '|') || (cur == '.') || (cur == '?') || (cur == '*') || 48914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == '+') || (cur == '(') || (cur == ')') || (cur == '{') || 48924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == '}') || (cur == 0x2D) || (cur == 0x5B) || (cur == 0x5D) || 48934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == 0x5E)) { 48944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) { 48954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL); 489699c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard if (ctxt->atom != NULL) { 489799c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard switch (cur) { 489899c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard case 'n': 489999c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard ctxt->atom->codepoint = '\n'; 490099c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard break; 490199c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard case 'r': 490299c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard ctxt->atom->codepoint = '\r'; 490399c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard break; 490499c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard case 't': 490599c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard ctxt->atom->codepoint = '\t'; 490699c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard break; 490799c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard default: 490899c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard ctxt->atom->codepoint = cur; 490999c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard } 491099c394d9c50efdaca1d4c437cf22c9c160ed9c65Daniel Veillard } 49114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->atom->type == XML_REGEXP_RANGES) { 49129543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard switch (cur) { 49139543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard case 'n': 49149543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard cur = '\n'; 49159543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard break; 49169543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard case 'r': 49179543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard cur = '\r'; 49189543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard break; 49199543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard case 't': 49209543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard cur = '\t'; 49219543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard break; 49229543aee99b39f4de58641a66a5747cadd279d0b0Daniel Veillard } 49234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 49244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_CHARVAL, cur, cur, NULL); 49254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 49264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 49274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if ((cur == 's') || (cur == 'S') || (cur == 'i') || (cur == 'I') || 49284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == 'c') || (cur == 'C') || (cur == 'd') || (cur == 'D') || 49294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (cur == 'w') || (cur == 'W')) { 4930b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlRegAtomType type = XML_REGEXP_ANYSPACE; 49314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 49324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (cur) { 4933f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case 's': 49344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_ANYSPACE; 49354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 4936f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case 'S': 49374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NOTSPACE; 49384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 4939f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case 'i': 49404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_INITNAME; 49414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 4942f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case 'I': 49434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NOTINITNAME; 49444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 4945f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case 'c': 49464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NAMECHAR; 49474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 4948f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case 'C': 49494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NOTNAMECHAR; 49504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 4951f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case 'd': 49524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_DECIMAL; 49534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 4954f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case 'D': 49554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NOTDECIMAL; 49564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 4957f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case 'w': 49584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_REALCHAR; 49594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 4960f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case 'W': 49614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type = XML_REGEXP_NOTREALCHAR; 49624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 49634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 49644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 49654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) { 49664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, type); 49674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (ctxt->atom->type == XML_REGEXP_RANGES) { 49684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 49694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard type, 0, 0, NULL); 49704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 4971cb4284e29641aa7dd990d42aba772b7f5c1ab50dDaniel Veillard } else { 4972cb4284e29641aa7dd990d42aba772b7f5c1ab50dDaniel Veillard ERROR("Wrong escape sequence, misuse of character '\\'"); 49734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 49744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 49754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 49764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 49774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharRange: 4978441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 49794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 4980f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * [17] charRange ::= seRange | XmlCharRef | XmlCharIncDash 49814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [18] seRange ::= charOrEsc '-' charOrEsc 49824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [20] charOrEsc ::= XmlChar | SingleCharEsc 49834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [21] XmlChar ::= [^\#x2D#x5B#x5D] 49844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [22] XmlCharIncDash ::= [^\#x5B#x5D] 49854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 49864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 49874255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharRange(xmlRegParserCtxtPtr ctxt) { 4988dc99df936c74b6ced82904086544fec365d1f219William M. Brack int cur, len; 49894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int start = -1; 49904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int end = -1; 49914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 4992777737ea020106db4d376f2d8b3992198892f29aDaniel Veillard if (CUR == '\0') { 4993777737ea020106db4d376f2d8b3992198892f29aDaniel Veillard ERROR("Expecting ']'"); 4994777737ea020106db4d376f2d8b3992198892f29aDaniel Veillard return; 4995777737ea020106db4d376f2d8b3992198892f29aDaniel Veillard } 4996777737ea020106db4d376f2d8b3992198892f29aDaniel Veillard 49974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 49984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == '\\') { 49994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 50004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 50014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (cur) { 50024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'n': start = 0xA; break; 50034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'r': start = 0xD; break; 50044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 't': start = 0x9; break; 50054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case '\\': case '|': case '.': case '-': case '^': case '?': 50064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case '*': case '+': case '{': case '}': case '(': case ')': 50074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case '[': case ']': 50084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard start = cur; break; 50094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard default: 50104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Invalid escape value"); 50114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 50124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 50134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard end = start; 5014dc99df936c74b6ced82904086544fec365d1f219William M. Brack len = 1; 50154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if ((cur != 0x5B) && (cur != 0x5D)) { 5016dc99df936c74b6ced82904086544fec365d1f219William M. Brack end = start = CUR_SCHAR(ctxt->cur, len); 50174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 50184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Expecting a char range"); 50194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 50204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5021a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack /* 5022a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack * Since we are "inside" a range, we can assume ctxt->cur is past 5023a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack * the start of ctxt->string, and PREV should be safe 5024a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack */ 5025a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack if ((start == '-') && (NXT(1) != ']') && (PREV != '[') && (PREV != '^')) { 5026a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack NEXTL(len); 50274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 50284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5029a9cbf28361410926c82ae47a2c9d1a22795976c1William M. Brack NEXTL(len); 50304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 503110f1ef4ce875d6affb467f33ab653cd8072e5888William M. Brack if ((cur != '-') || (NXT(1) == ']')) { 50324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 50334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_CHARVAL, start, end, NULL); 50344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 50354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 50364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 50374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 50384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == '\\') { 50394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 50404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 50414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (cur) { 50424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'n': end = 0xA; break; 50434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 'r': end = 0xD; break; 50444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case 't': end = 0x9; break; 50454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case '\\': case '|': case '.': case '-': case '^': case '?': 50464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case '*': case '+': case '{': case '}': case '(': case ')': 50474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case '[': case ']': 50484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard end = cur; break; 50494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard default: 50504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Invalid escape value"); 50514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 50524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5053dc99df936c74b6ced82904086544fec365d1f219William M. Brack len = 1; 50544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if ((cur != 0x5B) && (cur != 0x5D)) { 5055dc99df936c74b6ced82904086544fec365d1f219William M. Brack end = CUR_SCHAR(ctxt->cur, len); 50564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 50574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Expecting the end of a char range"); 50584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 50594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5060cbb271655cadeb8dbb258a64701d9a3a0c4835b4Pranjal Jumde 50614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* TODO check that the values are acceptable character ranges for XML */ 50624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (end < start) { 50634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("End of range is before start of range"); 50644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 5065cbb271655cadeb8dbb258a64701d9a3a0c4835b4Pranjal Jumde NEXTL(len); 50664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 50674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_REGEXP_CHARVAL, start, end, NULL); 50684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 50694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 50704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 50714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 50724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 50734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParsePosCharGroup: 5074441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 50754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 50764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [14] posCharGroup ::= ( charRange | charClassEsc )+ 50774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 50784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 50794255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParsePosCharGroup(xmlRegParserCtxtPtr ctxt) { 50804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard do { 5081041b687e93cc4d5806b902ed3b445a47669dc2adDaniel Veillard if (CUR == '\\') { 50824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharClassEsc(ctxt); 50834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 50844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharRange(ctxt); 50854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 50864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } while ((CUR != ']') && (CUR != '^') && (CUR != '-') && 5087777737ea020106db4d376f2d8b3992198892f29aDaniel Veillard (CUR != 0) && (ctxt->error == 0)); 50884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 50894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 50904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 50914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharGroup: 5092441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 50934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 50944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [13] charGroup ::= posCharGroup | negCharGroup | charClassSub 50954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [15] negCharGroup ::= '^' posCharGroup 5096f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * [16] charClassSub ::= ( posCharGroup | negCharGroup ) '-' charClassExpr 50974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [12] charClassExpr ::= '[' charGroup ']' 50984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 50994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 51004255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharGroup(xmlRegParserCtxtPtr ctxt) { 51014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int n = ctxt->neg; 51024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((CUR != ']') && (ctxt->error == 0)) { 51034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == '^') { 51044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int neg = ctxt->neg; 51054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 51064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 51074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->neg = !ctxt->neg; 51084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParsePosCharGroup(ctxt); 51094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->neg = neg; 511010f1ef4ce875d6affb467f33ab653cd8072e5888William M. Brack } else if ((CUR == '-') && (NXT(1) == '[')) { 5111f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard int neg = ctxt->neg; 5112f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard ctxt->neg = 2; 511310f1ef4ce875d6affb467f33ab653cd8072e5888William M. Brack NEXT; /* eat the '-' */ 511410f1ef4ce875d6affb467f33ab653cd8072e5888William M. Brack NEXT; /* eat the '[' */ 51154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharGroup(ctxt); 51164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == ']') { 51174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 51184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 51194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("charClassExpr: ']' expected"); 51204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 51214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5122f8b9de32543a23c932a392362d4e4a6704c2c953Daniel Veillard ctxt->neg = neg; 51234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard break; 51244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (CUR != ']') { 51254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParsePosCharGroup(ctxt); 51264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->neg = n; 51294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 51304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 51314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 51324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseCharClass: 5133441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 51344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 51354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [11] charClass ::= charClassEsc | charClassExpr 51364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [12] charClassExpr ::= '[' charGroup ']' 51374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 51384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 51394255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseCharClass(xmlRegParserCtxtPtr ctxt) { 51404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == '[') { 51414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 51424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_RANGES); 51434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) 51444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 51454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharGroup(ctxt); 51464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == ']') { 51474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 51484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 51494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("xmlFAParseCharClass: ']' expected"); 51504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 51524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharClassEsc(ctxt); 51534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 51554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 51564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 51574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseQuantExact: 5158441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 51594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 51604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [8] QuantExact ::= [0-9]+ 5161a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard * 5162a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard * Returns 0 if success or -1 in case of error 51634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 51644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 51654255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseQuantExact(xmlRegParserCtxtPtr ctxt) { 51664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ret = 0; 51674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ok = 0; 51684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 51694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 51704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = ret * 10 + (CUR - '0'); 51714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ok = 1; 51724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 51734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ok != 1) { 51754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 51764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 51774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 51784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 51794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 51804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 51814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseQuantifier: 5182441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 51834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 51844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [4] quantifier ::= [?*+] | ( '{' quantity '}' ) 51854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [5] quantity ::= quantRange | quantMin | QuantExact 51864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [6] quantRange ::= QuantExact ',' QuantExact 51874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [7] quantMin ::= QuantExact ',' 51884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [8] QuantExact ::= [0-9]+ 51894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 51904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 51914255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseQuantifier(xmlRegParserCtxtPtr ctxt) { 51924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int cur; 51934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 51944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = CUR; 51954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((cur == '?') || (cur == '*') || (cur == '+')) { 51964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom != NULL) { 51974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == '?') 51984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->quant = XML_REGEXP_QUANT_OPT; 51994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else if (cur == '*') 52004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->quant = XML_REGEXP_QUANT_MULT; 52014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else if (cur == '+') 52024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->quant = XML_REGEXP_QUANT_PLUS; 52034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 52044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 52054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 52064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 52074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == '{') { 52084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int min = 0, max = 0; 52094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 52104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 52114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur = xmlFAParseQuantExact(ctxt); 52124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur >= 0) 52134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard min = cur; 52144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == ',') { 52154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 5216ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard if (CUR == '}') 5217ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard max = INT_MAX; 5218ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard else { 5219ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard cur = xmlFAParseQuantExact(ctxt); 5220ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard if (cur >= 0) 5221ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard max = cur; 5222ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard else { 5223ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard ERROR("Improper quantifier"); 5224ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard } 5225ebe48c60cc941881718222e69fabf604fe23e43dDaniel Veillard } 52264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 52274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == '}') { 52284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 52294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 52304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("Unterminated quantifier"); 52314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 52324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (max == 0) 52334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard max = min; 52344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom != NULL) { 52354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->quant = XML_REGEXP_QUANT_RANGE; 52364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->min = min; 52374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->max = max; 52384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 52394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 52404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 52414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 52424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 52434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 52444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 52454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseAtom: 5246441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 52474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 52484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [9] atom ::= Char | charClass | ( '(' regExp ')' ) 52494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 52504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 52514255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseAtom(xmlRegParserCtxtPtr ctxt) { 52524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int codepoint, len; 52534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 52544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard codepoint = xmlFAIsChar(ctxt); 52554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (codepoint > 0) { 52564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL); 52574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) 52584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 52594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard codepoint = CUR_SCHAR(ctxt->cur, len); 52604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->codepoint = codepoint; 52614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXTL(len); 52624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 52634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (CUR == '|') { 52644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 52654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (CUR == 0) { 52664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 52674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (CUR == ')') { 52684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 52694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (CUR == '(') { 527076d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlRegStatePtr start, oldend, start0; 52714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 52724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 527376d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard /* 527476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * this extra Epsilon transition is needed if we count with 0 allowed 527576d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard * unfortunately this can't be known at that point 527676d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard */ 527776d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, NULL); 527876d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard start0 = ctxt->state; 52794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, NULL); 52804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard start = ctxt->state; 52814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard oldend = ctxt->end; 52824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = NULL; 52834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = NULL; 52844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseRegExp(ctxt, 0); 52854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR == ')') { 52864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 52874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 52884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("xmlFAParseAtom: expecting ')'"); 52894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 52904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_SUBREG); 52914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) 52924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 52934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->start = start; 529476d59b6d6ff8284ee6ed69ee4118e7da935d5e57Daniel Veillard ctxt->atom->start0 = start0; 52954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom->stop = ctxt->state; 52964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = oldend; 52974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 52984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if ((CUR == '[') || (CUR == '\\') || (CUR == '.')) { 52994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseCharClass(ctxt); 53004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 53014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 53024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 53034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 53044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 53054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 53064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParsePiece: 5307441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 53084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 53094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [3] piece ::= atom quantifier? 53104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 53114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 53124255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParsePiece(xmlRegParserCtxtPtr ctxt) { 53134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ret; 53144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 53154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = NULL; 53164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlFAParseAtom(ctxt); 53174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 0) 53184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 53194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->atom == NULL) { 53204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("internal: no atom generated"); 53214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 53224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseQuantifier(ctxt); 53234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 53244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 53254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 53264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 53274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseBranch: 5328441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 532954eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * @to: optional target to the end of the branch 533054eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * 533154eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * @to is used to optimize by removing duplicate path in automata 533254eb0243c442292953b4a3df39568735039ebc82Daniel Veillard * in expressions like (a|b)(c|d) 53334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 53344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [2] branch ::= piece* 53354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 5336a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillardstatic int 533754eb0243c442292953b4a3df39568735039ebc82Daniel VeillardxmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) { 53384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePtr previous; 53394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ret; 53404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 53414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard previous = ctxt->state; 53424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlFAParsePiece(ctxt); 53434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret != 0) { 5344f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (xmlFAGenerateTransitions(ctxt, previous, 534554eb0243c442292953b4a3df39568735039ebc82Daniel Veillard (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0) 53462cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard return(-1); 53472cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard previous = ctxt->state; 53484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = NULL; 53494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 53504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((ret != 0) && (ctxt->error == 0)) { 53514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlFAParsePiece(ctxt); 53524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret != 0) { 5353f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (xmlFAGenerateTransitions(ctxt, previous, 535454eb0243c442292953b4a3df39568735039ebc82Daniel Veillard (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0) 5355a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(-1); 53564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard previous = ctxt->state; 53574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->atom = NULL; 53584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 53594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5360a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(0); 53614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 53624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 53634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 53644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFAParseRegExp: 5365441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard * @ctxt: a regexp parser context 5366ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * @top: is this the top-level expression ? 53674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 53684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * [1] regExp ::= branch ( '|' branch )* 53694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 53704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic void 53714255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) { 5372c7e3cc49bade82dba0cda4ae7c07ffcd1e32fe25Daniel Veillard xmlRegStatePtr start, end; 53734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 53742cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard /* if not top start should have been generated by an epsilon trans */ 53754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard start = ctxt->state; 53762cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard ctxt->end = NULL; 537754eb0243c442292953b4a3df39568735039ebc82Daniel Veillard xmlFAParseBranch(ctxt, NULL); 53782cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard if (top) { 53792cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard#ifdef DEBUG_REGEXP_GRAPH 53802cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard printf("State %d is final\n", ctxt->state->no); 53812cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard#endif 53822cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard ctxt->state->type = XML_REGEXP_FINAL_STATE; 53832cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard } 53844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != '|') { 53854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = ctxt->state; 53864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 53874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 53884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard end = ctxt->state; 53894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((CUR == '|') && (ctxt->error == 0)) { 53904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard NEXT; 539140851d0c5975a8fde9498f72f3f5d96ad3194dc5Daniel Veillard if (CUR == 0) { 539240851d0c5975a8fde9498f72f3f5d96ad3194dc5Daniel Veillard ERROR("expecting a branch after |") 539340851d0c5975a8fde9498f72f3f5d96ad3194dc5Daniel Veillard return; 539440851d0c5975a8fde9498f72f3f5d96ad3194dc5Daniel Veillard } 53954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->state = start; 53962cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard ctxt->end = NULL; 539754eb0243c442292953b4a3df39568735039ebc82Daniel Veillard xmlFAParseBranch(ctxt, end); 53982cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard } 53992cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard if (!top) { 54002cbf596c7f6d4ef21798bb06efd7542781124300Daniel Veillard ctxt->state = end; 54014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = end; 54024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 54034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 54044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 5406f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 5407f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * The basic API * 5408f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 54094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 54104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 54124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegexpPrint: 54134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @output: the file for the output debug 54144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @regexp: the compiled regexp 54154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 54164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Print the content of the compiled regular expression 54174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 54184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid 54194255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpPrint(FILE *output, xmlRegexpPtr regexp) { 54204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 54214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 5422a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (output == NULL) 5423a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard return; 54244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " regexp: "); 54254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (regexp == NULL) { 54264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "NULL\n"); 54274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 54284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 54294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "'%s' ", regexp->string); 54304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "\n"); 54314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d atoms:\n", regexp->nbAtoms); 54324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < regexp->nbAtoms; i++) { 54334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " %02d ", i); 54344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintAtom(output, regexp->atoms[i]); 54354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 54364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d states:", regexp->nbStates); 54374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "\n"); 54384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < regexp->nbStates; i++) { 54394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegPrintState(output, regexp->states[i]); 54404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 54414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, "%d counters:\n", regexp->nbCounters); 54424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < regexp->nbCounters; i++) { 54434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard fprintf(output, " %d: min %d max %d\n", i, regexp->counters[i].min, 54444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard regexp->counters[i].max); 54454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 54464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 54474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 54494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegexpCompile: 54504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @regexp: a regular expression string 54514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 54524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Parses a regular expression conforming to XML Schemas Part 2 Datatype 5453ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Appendix F and builds an automata suitable for testing strings against 54544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * that regular expression 54554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 54564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the compiled expression or NULL in case of error 54574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 54584255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpPtr 54594255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpCompile(const xmlChar *regexp) { 54604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegexpPtr ret; 54614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegParserCtxtPtr ctxt; 54624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt = xmlRegNewParserCtxt(regexp); 54644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt == NULL) 54654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 54664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* initialize the parser */ 54684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = NULL; 54694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->start = ctxt->state = xmlRegNewState(ctxt); 54704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePush(ctxt, ctxt->start); 54714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* parse the expression building an automata */ 54734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAParseRegExp(ctxt, 1); 54744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (CUR != 0) { 54754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ERROR("xmlFAParseRegExp: extra characters"); 54764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 5477cb4284e29641aa7dd990d42aba772b7f5c1ab50dDaniel Veillard if (ctxt->error != 0) { 5478cb4284e29641aa7dd990d42aba772b7f5c1ab50dDaniel Veillard xmlRegFreeParserCtxt(ctxt); 5479cb4284e29641aa7dd990d42aba772b7f5c1ab50dDaniel Veillard return(NULL); 5480cb4284e29641aa7dd990d42aba772b7f5c1ab50dDaniel Veillard } 54814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = ctxt->state; 54824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->start->type = XML_REGEXP_START_STATE; 54834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end->type = XML_REGEXP_FINAL_STATE; 54844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* remove the Epsilon except for counted transitions */ 54864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAEliminateEpsilonTransitions(ctxt); 54874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt->error != 0) { 54904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeParserCtxt(ctxt); 54914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 54924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 54934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegEpxFromParse(ctxt); 54944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeParserCtxt(ctxt); 54954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 54964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 54974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 54984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 54994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegexpExec: 55004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @comp: the compiled regular expression 55014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @content: the value to check against the regular expression 55024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 5503ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Check if the regular expression generates the value 55044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 5505ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Returns 1 if it matches, 0 if not and a negative value in case of error 55064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 55074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardint 55084255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegexpExec(xmlRegexpPtr comp, const xmlChar *content) { 55094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((comp == NULL) || (content == NULL)) 55104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 55114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(xmlFARegExec(comp, content)); 55124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 55134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 55144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 551523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * xmlRegexpIsDeterminist: 551623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * @comp: the compiled regular expression 551723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * 551823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * Check if the regular expression is determinist 551923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard * 5520ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * Returns 1 if it yes, 0 if not and a negative value in case of error 552123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard */ 552223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillardint 552323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel VeillardxmlRegexpIsDeterminist(xmlRegexpPtr comp) { 552423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlAutomataPtr am; 552523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard int ret; 552623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 552723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (comp == NULL) 552823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(-1); 552923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (comp->determinist != -1) 553023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(comp->determinist); 553123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 553223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am = xmlNewAutomata(); 5533bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard if (am->states != NULL) { 5534bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard int i; 5535bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard 5536bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard for (i = 0;i < am->nbStates;i++) 5537bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard xmlRegFreeState(am->states[i]); 5538bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard xmlFree(am->states); 5539bd9afb529069415baf1f32d907f035de19dae788Daniel Veillard } 554023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->nbAtoms = comp->nbAtoms; 554123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->atoms = comp->atoms; 554223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->nbStates = comp->nbStates; 554323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->states = comp->states; 554423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->determinist = -1; 55451ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard am->flags = comp->flags; 554623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard ret = xmlFAComputesDeterminism(am); 554723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->atoms = NULL; 554823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard am->states = NULL; 554923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFreeAutomata(am); 55501ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard comp->determinist = ret; 555123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard return(ret); 555223e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard} 555323e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 555423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard/** 55554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlRegFreeRegexp: 55564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @regexp: the regexp 55574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 55584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free a regexp 55594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 55604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid 55614255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlRegFreeRegexp(xmlRegexpPtr regexp) { 55624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int i; 55634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (regexp == NULL) 55644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 55654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 55664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (regexp->string != NULL) 55674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(regexp->string); 55684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (regexp->states != NULL) { 55694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < regexp->nbStates;i++) 55704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeState(regexp->states[i]); 55714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(regexp->states); 55724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 55734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (regexp->atoms != NULL) { 55744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard for (i = 0;i < regexp->nbAtoms;i++) 55754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeAtom(regexp->atoms[i]); 55764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(regexp->atoms); 55774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 55784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (regexp->counters != NULL) 55794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(regexp->counters); 558023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (regexp->compact != NULL) 558123e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(regexp->compact); 5582118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if (regexp->transdata != NULL) 5583118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard xmlFree(regexp->transdata); 558423e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard if (regexp->stringMap != NULL) { 558523e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard for (i = 0; i < regexp->nbstrings;i++) 558623e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(regexp->stringMap[i]); 558723e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard xmlFree(regexp->stringMap); 558823e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard } 558923e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard 55904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(regexp); 55914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 55924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 55934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef LIBXML_AUTOMATA_ENABLED 55944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/************************************************************************ 5595f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 5596f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * The Automata interface * 5597f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 55984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ************************************************************************/ 55994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 56014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlNewAutomata: 56024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 56034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Create a new automata 56044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 56054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new object or NULL in case of failure 56064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 56074255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataPtr 56084255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlNewAutomata(void) { 56094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlAutomataPtr ctxt; 56104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt = xmlRegNewParserCtxt(NULL); 56124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ctxt == NULL) 56134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 56144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* initialize the parser */ 56164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->end = NULL; 56174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ctxt->start = ctxt->state = xmlRegNewState(ctxt); 5618a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (ctxt->start == NULL) { 5619a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFreeAutomata(ctxt); 5620a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 5621a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 5622d0271473abc7ca82a22e9a953ec525a6f4b504d5Daniel Veillard ctxt->start->type = XML_REGEXP_START_STATE; 5623a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (xmlRegStatePush(ctxt, ctxt->start) < 0) { 5624a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlRegFreeState(ctxt->start); 5625a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlFreeAutomata(ctxt); 5626a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 5627a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 56281ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard ctxt->flags = 0; 56294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ctxt); 56314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 56324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 56344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlFreeAutomata: 56354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 56364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 56374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Free an automata 56384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 56394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid 56404255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlFreeAutomata(xmlAutomataPtr am) { 56414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (am == NULL) 56424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 56434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegFreeParserCtxt(am); 56444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 56454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 5647293416828e1467f877d9dd928f174dcf81b103bcDaniel Veillard * xmlAutomataSetFlags: 56481ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * @am: an automata 56491ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * @flags: a set of internal flags 56501ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * 56511ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard * Set some flags on the automata 56521ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard */ 56531ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillardvoid 56541ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel VeillardxmlAutomataSetFlags(xmlAutomataPtr am, int flags) { 56551ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard if (am == NULL) 56561ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard return; 56571ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard am->flags |= flags; 56581ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard} 56591ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard 56601ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard/** 56614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataGetInitState: 56624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 56634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 5664a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * Initial state lookup 5665a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * 56664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the initial state of the automata 56674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 56684255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr 56694255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataGetInitState(xmlAutomataPtr am) { 56704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (am == NULL) 56714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 56724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(am->start); 56734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 56744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 56764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataSetFinalState: 56774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 56784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @state: a state in this automata 56794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 56804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Makes that state a final state 56814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 56824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns 0 or -1 in case of error 56834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 56844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardint 56854255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataSetFinalState(xmlAutomataPtr am, xmlAutomataStatePtr state) { 56864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((am == NULL) || (state == NULL)) 56874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 56884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard state->type = XML_REGEXP_FINAL_STATE; 56894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 56904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 56914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 56924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 56934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataNewTransition: 56944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 56954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @from: the starting point of the transition 56964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @to: the target point of the transition or NULL 56974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @token: the input string associated to that transition 56984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @data: data passed to the callback function if the transition is activated 56994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 5700ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 57014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * and then adds a transition from the @from state to the target state 57024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * activated by the value of @token 57034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 57044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the target state or NULL in case of error 57054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 57064255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr 57074255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataNewTransition(xmlAutomataPtr am, xmlAutomataStatePtr from, 57084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlAutomataStatePtr to, const xmlChar *token, 57094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard void *data) { 57104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 57114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 57124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((am == NULL) || (from == NULL) || (token == NULL)) 57134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 57144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 5715a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (atom == NULL) 5716a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 57174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->data = data; 57184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->valuep = xmlStrdup(token); 57194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 5720a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (xmlFAGenerateTransitions(am, from, to, atom) < 0) { 5721a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlRegFreeAtom(atom); 5722a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 5723a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 57244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) 572552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(am->state); 572652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(to); 572752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard} 572852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 572952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard/** 573052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * xmlAutomataNewTransition2: 573152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @am: an automata 573252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @from: the starting point of the transition 573352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @to: the target point of the transition or NULL 573452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @token: the first input string associated to that transition 573552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @token2: the second input string associated to that transition 573652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @data: data passed to the callback function if the transition is activated 573752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * 5738ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 573952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * and then adds a transition from the @from state to the target state 574052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * activated by the value of @token 574152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * 574252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * Returns the target state or NULL in case of error 574352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard */ 574452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel VeillardxmlAutomataStatePtr 574552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel VeillardxmlAutomataNewTransition2(xmlAutomataPtr am, xmlAutomataStatePtr from, 574652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard xmlAutomataStatePtr to, const xmlChar *token, 574752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard const xmlChar *token2, void *data) { 574852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard xmlRegAtomPtr atom; 574952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 575052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if ((am == NULL) || (from == NULL) || (token == NULL)) 575152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(NULL); 575252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 575352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (atom == NULL) 575452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(NULL); 575511ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard atom->data = data; 575652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if ((token2 == NULL) || (*token2 == 0)) { 575752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard atom->valuep = xmlStrdup(token); 575852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard } else { 575952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard int lenn, lenp; 576052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard xmlChar *str; 576152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 576252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard lenn = strlen((char *) token2); 576352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard lenp = strlen((char *) token); 576452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 57653c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 576652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (str == NULL) { 576752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard xmlRegFreeAtom(atom); 576852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard return(NULL); 576952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard } 577052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard memcpy(&str[0], token, lenp); 577152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard str[lenp] = '|'; 577252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard memcpy(&str[lenp + 1], token2, lenn); 577352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard str[lenn + lenp + 1] = 0; 577452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 577552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard atom->valuep = str; 577652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard } 577752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard 5778a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if (xmlFAGenerateTransitions(am, from, to, atom) < 0) { 5779a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard xmlRegFreeAtom(atom); 5780a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 5781a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 578252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard if (to == NULL) 57834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(am->state); 57849efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard return(to); 57859efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard} 57869efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 57879efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard/** 57889efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * xmlAutomataNewNegTrans: 57899efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * @am: an automata 57909efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * @from: the starting point of the transition 57919efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * @to: the target point of the transition or NULL 57929efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * @token: the first input string associated to that transition 57939efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * @token2: the second input string associated to that transition 57949efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * @data: data passed to the callback function if the transition is activated 57959efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * 57969efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * If @to is NULL, this creates first a new target state in the automata 57979efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * and then adds a transition from the @from state to the target state 57989efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * activated by any value except (@token,@token2) 57996e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard * Note that if @token2 is not NULL, then (X, NULL) won't match to follow 58006e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard # the semantic of XSD ##other 58019efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * 58029efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard * Returns the target state or NULL in case of error 58039efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard */ 58049efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel VeillardxmlAutomataStatePtr 58059efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel VeillardxmlAutomataNewNegTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 58069efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard xmlAutomataStatePtr to, const xmlChar *token, 58079efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard const xmlChar *token2, void *data) { 58089efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard xmlRegAtomPtr atom; 580977005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard xmlChar err_msg[200]; 58109efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 58119efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if ((am == NULL) || (from == NULL) || (token == NULL)) 58129efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard return(NULL); 58139efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 58149efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if (atom == NULL) 58159efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard return(NULL); 58169efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard atom->data = data; 58179efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard atom->neg = 1; 58189efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if ((token2 == NULL) || (*token2 == 0)) { 58199efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard atom->valuep = xmlStrdup(token); 58209efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard } else { 58219efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard int lenn, lenp; 58229efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard xmlChar *str; 58239efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 58249efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard lenn = strlen((char *) token2); 58259efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard lenp = strlen((char *) token); 58269efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 58279efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 58289efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if (str == NULL) { 58299efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard xmlRegFreeAtom(atom); 58309efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard return(NULL); 58319efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard } 58329efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard memcpy(&str[0], token, lenp); 58339efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard str[lenp] = '|'; 58349efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard memcpy(&str[lenp + 1], token2, lenn); 58359efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard str[lenn + lenp + 1] = 0; 58369efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 58379efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard atom->valuep = str; 58389efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard } 5839db68b74dc7ec531361a736de7769a3e8ce881f79Daniel Veillard snprintf((char *) err_msg, 199, "not %s", (const char *) atom->valuep); 584077005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard err_msg[199] = 0; 584177005e6ff0426ae3cfefdcfb5796f29a8e83a83bDaniel Veillard atom->valuep2 = xmlStrdup(err_msg); 58429efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard 58439efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if (xmlFAGenerateTransitions(am, from, to, atom) < 0) { 58449efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard xmlRegFreeAtom(atom); 58459efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard return(NULL); 58469efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard } 58476e65e15777ebb281aec362fa2aba51e2cb5aa87fDaniel Veillard am->negs++; 58489efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard if (to == NULL) 58499efc476bb6fe9d7d84ee0fe1190888801d9374ccDaniel Veillard return(am->state); 58504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(to); 58514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 58524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 58534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 585487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * xmlAutomataNewCountTrans2: 585587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @am: an automata 585687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @from: the starting point of the transition 585787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @to: the target point of the transition or NULL 585887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @token: the input string associated to that transition 585987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @token2: the second input string associated to that transition 586087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @min: the minimum successive occurences of token 586187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @max: the maximum successive occurences of token 586287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @data: data associated to the transition 586387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * 586487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * If @to is NULL, this creates first a new target state in the automata 586587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * and then adds a transition from the @from state to the target state 5866f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * activated by a succession of input of value @token and @token2 and 586787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * whose number is between @min and @max 586887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * 586987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * Returns the target state or NULL in case of error 587087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik */ 587187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. BuchcikxmlAutomataStatePtr 587287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. BuchcikxmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, 587387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlAutomataStatePtr to, const xmlChar *token, 587487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik const xmlChar *token2, 587587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik int min, int max, void *data) { 587687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegAtomPtr atom; 587787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik int counter; 587887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 587987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if ((am == NULL) || (from == NULL) || (token == NULL)) 588087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 588187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (min < 0) 588287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 588387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if ((max < min) || (max < 1)) 588487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 588587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 588687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (atom == NULL) 588787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 588887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if ((token2 == NULL) || (*token2 == 0)) { 588987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->valuep = xmlStrdup(token); 589087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } else { 589187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik int lenn, lenp; 589287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlChar *str; 589387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 589487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik lenn = strlen((char *) token2); 589587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik lenp = strlen((char *) token); 589687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 589787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 589887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (str == NULL) { 589987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegFreeAtom(atom); 590087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 590187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } 590287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik memcpy(&str[0], token, lenp); 590387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik str[lenp] = '|'; 590487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik memcpy(&str[lenp + 1], token2, lenn); 590587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik str[lenn + lenp + 1] = 0; 590687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 590787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->valuep = str; 590887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } 590987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->data = data; 591087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (min == 0) 591187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->min = 1; 591287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik else 591387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->min = min; 591487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->max = max; 591587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 591687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik /* 591787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * associate a counter to the transition. 591887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik */ 591987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik counter = xmlRegGetCounter(am); 592087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik am->counters[counter].min = min; 592187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik am->counters[counter].max = max; 592287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 592387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik /* xmlFAGenerateTransitions(am, from, to, atom); */ 592487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (to == NULL) { 592587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik to = xmlRegNewState(am); 592687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegStatePush(am, to); 592787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } 59285de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(am, from, atom, to, counter, -1); 592987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegAtomPush(am, atom); 593087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik am->state = to; 593187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 593287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (to == NULL) 593387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik to = am->state; 593487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (to == NULL) 593587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 593687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (min == 0) 593787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlFAGenerateEpsilonTransition(am, from, to); 593887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(to); 593987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik} 594087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 594187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik/** 59424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataNewCountTrans: 59434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 59444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @from: the starting point of the transition 59454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @to: the target point of the transition or NULL 59464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @token: the input string associated to that transition 59474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @min: the minimum successive occurences of token 5948a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * @max: the maximum successive occurences of token 5949a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * @data: data associated to the transition 59504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 5951ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 59524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * and then adds a transition from the @from state to the target state 59534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * activated by a succession of input of value @token and whose number 59544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * is between @min and @max 59554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 59564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the target state or NULL in case of error 59574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 59584255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr 59594255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 59604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlAutomataStatePtr to, const xmlChar *token, 59614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int min, int max, void *data) { 59624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegAtomPtr atom; 59630ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard int counter; 59644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 59654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((am == NULL) || (from == NULL) || (token == NULL)) 59664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 59674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (min < 0) 59684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 59694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((max < min) || (max < 1)) 59704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 59714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 59724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (atom == NULL) 59734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 59744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->valuep = xmlStrdup(token); 59754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->data = data; 59764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (min == 0) 59774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->min = 1; 59784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else 59794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->min = min; 59804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard atom->max = max; 59814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 59820ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard /* 59830ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard * associate a counter to the transition. 59840ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard */ 59850ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard counter = xmlRegGetCounter(am); 59860ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard am->counters[counter].min = min; 59870ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard am->counters[counter].max = max; 59880ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard 59890ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard /* xmlFAGenerateTransitions(am, from, to, atom); */ 59900ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard if (to == NULL) { 59910ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard to = xmlRegNewState(am); 59920ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard xmlRegStatePush(am, to); 5993a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 59945de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(am, from, atom, to, counter, -1); 59950ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard xmlRegAtomPush(am, atom); 59960ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard am->state = to; 59970ddb21c46ca6ac5297ff5f6537480de8463223eaDaniel Veillard 59984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) 59994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to = am->state; 60004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) 60014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 60024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (min == 0) 60034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(am, from, to); 60044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(to); 60054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 60064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 60074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 600887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * xmlAutomataNewOnceTrans2: 600987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @am: an automata 601087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @from: the starting point of the transition 601187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @to: the target point of the transition or NULL 601287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @token: the input string associated to that transition 601387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @token2: the second input string associated to that transition 601487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @min: the minimum successive occurences of token 601587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @max: the maximum successive occurences of token 601687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * @data: data associated to the transition 601787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * 601887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * If @to is NULL, this creates first a new target state in the automata 601987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * and then adds a transition from the @from state to the target state 6020f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * activated by a succession of input of value @token and @token2 and whose 6021f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * number is between @min and @max, moreover that transition can only be 602287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * crossed once. 602387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * 602487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * Returns the target state or NULL in case of error 602587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik */ 602687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. BuchcikxmlAutomataStatePtr 602787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. BuchcikxmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, 602887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlAutomataStatePtr to, const xmlChar *token, 602987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik const xmlChar *token2, 603087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik int min, int max, void *data) { 603187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegAtomPtr atom; 603287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik int counter; 603387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 603487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if ((am == NULL) || (from == NULL) || (token == NULL)) 603587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 603687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (min < 1) 603787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 603887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if ((max < min) || (max < 1)) 603987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 604087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 604187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (atom == NULL) 604287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 604387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if ((token2 == NULL) || (*token2 == 0)) { 604487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->valuep = xmlStrdup(token); 604587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } else { 604687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik int lenn, lenp; 604787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlChar *str; 604887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 604987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik lenn = strlen((char *) token2); 605087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik lenp = strlen((char *) token); 605187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 605287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 605387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (str == NULL) { 605487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegFreeAtom(atom); 605587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(NULL); 605687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } 605787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik memcpy(&str[0], token, lenp); 605887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik str[lenp] = '|'; 605987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik memcpy(&str[lenp + 1], token2, lenn); 606087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik str[lenn + lenp + 1] = 0; 606187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 606287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->valuep = str; 6063f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 606487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->data = data; 606587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->quant = XML_REGEXP_QUANT_ONCEONLY; 606611ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard atom->min = min; 606787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik atom->max = max; 606887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik /* 606987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik * associate a counter to the transition. 607087876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik */ 607187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik counter = xmlRegGetCounter(am); 607287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik am->counters[counter].min = 1; 607387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik am->counters[counter].max = 1; 607487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 607587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik /* xmlFAGenerateTransitions(am, from, to, atom); */ 607687876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik if (to == NULL) { 607787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik to = xmlRegNewState(am); 607887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegStatePush(am, to); 607987876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik } 60805de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(am, from, atom, to, counter, -1); 608187876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik xmlRegAtomPush(am, atom); 608287876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik am->state = to; 608387876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik return(to); 608487876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik} 608587876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 6086f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 608787876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik 608887876407ced312c9b2c8d8b03f988a7dd484a68eKasimier T. Buchcik/** 60897646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * xmlAutomataNewOnceTrans: 60907646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @am: an automata 60917646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @from: the starting point of the transition 60927646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @to: the target point of the transition or NULL 60937646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @token: the input string associated to that transition 60947646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @min: the minimum successive occurences of token 6095a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * @max: the maximum successive occurences of token 6096a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * @data: data associated to the transition 60977646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * 6098ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 60997646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * and then adds a transition from the @from state to the target state 61007646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * activated by a succession of input of value @token and whose number 6101ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * is between @min and @max, moreover that transition can only be crossed 61027646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * once. 61037646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * 61047646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * Returns the target state or NULL in case of error 61057646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard */ 61067646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlAutomataStatePtr 61077646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 61087646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard xmlAutomataStatePtr to, const xmlChar *token, 61097646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard int min, int max, void *data) { 61107646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard xmlRegAtomPtr atom; 61117646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard int counter; 61127646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard 61137646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if ((am == NULL) || (from == NULL) || (token == NULL)) 61147646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(NULL); 61157646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if (min < 1) 61167646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(NULL); 61177646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if ((max < min) || (max < 1)) 61187646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(NULL); 61197646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 61207646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if (atom == NULL) 61217646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(NULL); 61227646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard atom->valuep = xmlStrdup(token); 61237646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard atom->data = data; 61247646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard atom->quant = XML_REGEXP_QUANT_ONCEONLY; 612511ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard atom->min = min; 61267646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard atom->max = max; 61277646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard /* 61287646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * associate a counter to the transition. 61297646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard */ 61307646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard counter = xmlRegGetCounter(am); 61317646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard am->counters[counter].min = 1; 61327646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard am->counters[counter].max = 1; 61337646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard 61347646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard /* xmlFAGenerateTransitions(am, from, to, atom); */ 61357646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if (to == NULL) { 61367646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard to = xmlRegNewState(am); 61377646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard xmlRegStatePush(am, to); 61387646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard } 61395de0938fd16e2a4aabcab44f45c85a2f8a7f0a21Daniel Veillard xmlRegStateAddTrans(am, from, atom, to, counter, -1); 61407646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard xmlRegAtomPush(am, atom); 61417646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard am->state = to; 61427646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(to); 61437646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard} 61447646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard 61457646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard/** 61464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataNewState: 61474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 61484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 61494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Create a new disconnected state in the automata 61504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 61514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the new state or NULL in case of error 61524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 61534255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr 61544255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataNewState(xmlAutomataPtr am) { 6155f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlAutomataStatePtr to; 61564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 61574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (am == NULL) 61584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 61594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard to = xmlRegNewState(am); 61604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegStatePush(am, to); 61614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(to); 61624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 61634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 61644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 6165a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * xmlAutomataNewEpsilon: 61664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 61674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @from: the starting point of the transition 61684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @to: the target point of the transition or NULL 61694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 6170ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 6171ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * and then adds an epsilon transition from the @from state to the 61724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * target state 61734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 61744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the target state or NULL in case of error 61754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 61764255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataStatePtr 61774255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataNewEpsilon(xmlAutomataPtr am, xmlAutomataStatePtr from, 61784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlAutomataStatePtr to) { 61794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((am == NULL) || (from == NULL)) 61804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 61814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAGenerateEpsilonTransition(am, from, to); 61824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (to == NULL) 61834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(am->state); 61844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(to); 61854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 61864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 6187b509f1543df71549969eeac076349e05d2f78044Daniel Veillard/** 61887646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * xmlAutomataNewAllTrans: 61897646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @am: an automata 61907646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @from: the starting point of the transition 61917646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * @to: the target point of the transition or NULL 6192a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * @lax: allow to transition if not all all transitions have been activated 61937646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * 6194ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 61957646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * and then adds a an ALL transition from the @from state to the 61967646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * target state. That transition is an epsilon transition allowed only when 61977646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * all transitions from the @from node have been activated. 61987646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * 61997646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard * Returns the target state or NULL in case of error 62007646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard */ 62017646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlAutomataStatePtr 62027646b18d64b6c739d04ca453493070e88c4aab13Daniel VeillardxmlAutomataNewAllTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 6203441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard xmlAutomataStatePtr to, int lax) { 62047646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if ((am == NULL) || (from == NULL)) 62057646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(NULL); 6206441bc32e3167ed55df415500e3a22eda4eec1ac6Daniel Veillard xmlFAGenerateAllTransition(am, from, to, lax); 62077646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard if (to == NULL) 62087646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(am->state); 62097646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard return(to); 62107646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard} 62117646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard 62127646b18d64b6c739d04ca453493070e88c4aab13Daniel Veillard/** 6213b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * xmlAutomataNewCounter: 6214b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @am: an automata 6215b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @min: the minimal value on the counter 6216b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @max: the maximal value on the counter 6217b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * 6218b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * Create a new counter 6219b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * 6220b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * Returns the counter number or -1 in case of error 6221b509f1543df71549969eeac076349e05d2f78044Daniel Veillard */ 6222f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardint 6223b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataNewCounter(xmlAutomataPtr am, int min, int max) { 6224b509f1543df71549969eeac076349e05d2f78044Daniel Veillard int ret; 6225b509f1543df71549969eeac076349e05d2f78044Daniel Veillard 6226b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (am == NULL) 6227b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(-1); 6228b509f1543df71549969eeac076349e05d2f78044Daniel Veillard 6229b509f1543df71549969eeac076349e05d2f78044Daniel Veillard ret = xmlRegGetCounter(am); 6230b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (ret < 0) 6231b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(-1); 6232b509f1543df71549969eeac076349e05d2f78044Daniel Veillard am->counters[ret].min = min; 6233b509f1543df71549969eeac076349e05d2f78044Daniel Veillard am->counters[ret].max = max; 6234b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(ret); 6235b509f1543df71549969eeac076349e05d2f78044Daniel Veillard} 6236b509f1543df71549969eeac076349e05d2f78044Daniel Veillard 6237b509f1543df71549969eeac076349e05d2f78044Daniel Veillard/** 6238b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * xmlAutomataNewCountedTrans: 6239b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @am: an automata 6240b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @from: the starting point of the transition 6241b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @to: the target point of the transition or NULL 6242b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @counter: the counter associated to that transition 6243b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * 6244ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 6245b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * and then adds an epsilon transition from the @from state to the target state 6246b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * which will increment the counter provided 6247b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * 6248b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * Returns the target state or NULL in case of error 6249b509f1543df71549969eeac076349e05d2f78044Daniel Veillard */ 6250b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataStatePtr 6251b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataNewCountedTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 6252b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlAutomataStatePtr to, int counter) { 6253b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if ((am == NULL) || (from == NULL) || (counter < 0)) 6254b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(NULL); 6255b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlFAGenerateCountedEpsilonTransition(am, from, to, counter); 6256b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (to == NULL) 6257b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(am->state); 6258b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(to); 6259b509f1543df71549969eeac076349e05d2f78044Daniel Veillard} 6260b509f1543df71549969eeac076349e05d2f78044Daniel Veillard 6261b509f1543df71549969eeac076349e05d2f78044Daniel Veillard/** 6262b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * xmlAutomataNewCounterTrans: 6263b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @am: an automata 6264b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @from: the starting point of the transition 6265b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @to: the target point of the transition or NULL 6266b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * @counter: the counter associated to that transition 6267b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * 6268ddf71d61c939b561a2014f27a88e6a9899355b79William M. Brack * If @to is NULL, this creates first a new target state in the automata 6269b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * and then adds an epsilon transition from the @from state to the target state 6270b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * which will be allowed only if the counter is within the right range. 6271b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * 6272b509f1543df71549969eeac076349e05d2f78044Daniel Veillard * Returns the target state or NULL in case of error 6273b509f1543df71549969eeac076349e05d2f78044Daniel Veillard */ 6274b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataStatePtr 6275b509f1543df71549969eeac076349e05d2f78044Daniel VeillardxmlAutomataNewCounterTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 6276b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlAutomataStatePtr to, int counter) { 6277b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if ((am == NULL) || (from == NULL) || (counter < 0)) 6278b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(NULL); 6279b509f1543df71549969eeac076349e05d2f78044Daniel Veillard xmlFAGenerateCountedTransition(am, from, to, counter); 6280b509f1543df71549969eeac076349e05d2f78044Daniel Veillard if (to == NULL) 6281b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(am->state); 6282b509f1543df71549969eeac076349e05d2f78044Daniel Veillard return(to); 6283b509f1543df71549969eeac076349e05d2f78044Daniel Veillard} 62844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 62854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 62864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlAutomataCompile: 62874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @am: an automata 62884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 62894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Compile the automata into a Reg Exp ready for being executed. 62904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * The automata should be free after this point. 62914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 62924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the compiled regexp or NULL in case of error 62934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 6294f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel VeillardxmlRegexpPtr 62954255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlAutomataCompile(xmlAutomataPtr am) { 62964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlRegexpPtr ret; 62974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 6298a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard if ((am == NULL) || (am->error != 0)) return(NULL); 62994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFAEliminateEpsilonTransitions(am); 630023e73571f8f6918e4ea7be3506ee5bd24ee86c52Daniel Veillard /* xmlFAComputesDeterminism(am); */ 63014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegEpxFromParse(am); 63024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 63034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 63044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 6305e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 6306e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard/** 6307e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * xmlAutomataIsDeterminist: 6308e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * @am: an automata 6309e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 6310e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * Checks if an automata is determinist. 6311e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * 6312e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard * Returns 1 if true, 0 if not, and -1 in case of error 6313e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard */ 6314f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardint 6315e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel VeillardxmlAutomataIsDeterminist(xmlAutomataPtr am) { 6316e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard int ret; 6317e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 6318e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (am == NULL) 6319e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(-1); 6320e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 6321e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard ret = xmlFAComputesDeterminism(am); 6322e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(ret); 6323e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard} 63244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif /* LIBXML_AUTOMATA_ENABLED */ 632581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 632681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef LIBXML_EXPR_ENABLED 632781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/************************************************************************ 632881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 632981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Formal Expression handling code * 633081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 633181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ************************************************************************/ 633281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/************************************************************************ 633381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 633481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Expression handling context * 633581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 633681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ************************************************************************/ 633781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 633881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstruct _xmlExpCtxt { 633981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlDictPtr dict; 634081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr *table; 634181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int size; 634281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int nbElems; 634381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int nb_nodes; 6344594e5dfb48ee6fbac1b64155839063648022fc57Daniel Veillard int maxNodes; 634581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const char *expr; 634681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const char *cur; 634781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int nb_cons; 634881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int tabSize; 634981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard}; 635081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 635181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 635281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpNewCtxt: 635381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @maxNodes: the maximum number of nodes 6354bb654feb9a64db7fd8b5fefdbb79792883dc7795Jan Pokorný * @dict: optional dictionary to use internally 635581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 635681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Creates a new context for manipulating expressions 635781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 635881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the context or NULL in case of error 635981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 636081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpCtxtPtr 636181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpNewCtxt(int maxNodes, xmlDictPtr dict) { 636281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpCtxtPtr ret; 636381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int size = 256; 636481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 636581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (maxNodes <= 4096) 636681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard maxNodes = 4096; 6367f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 636881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = (xmlExpCtxtPtr) xmlMalloc(sizeof(xmlExpCtxt)); 636981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) 637081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 637181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard memset(ret, 0, sizeof(xmlExpCtxt)); 637281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->size = size; 637381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->nbElems = 0; 6374594e5dfb48ee6fbac1b64155839063648022fc57Daniel Veillard ret->maxNodes = maxNodes; 637581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->table = xmlMalloc(size * sizeof(xmlExpNodePtr)); 637681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret->table == NULL) { 637781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlFree(ret); 637881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 637981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 638081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard memset(ret->table, 0, size * sizeof(xmlExpNodePtr)); 638181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (dict == NULL) { 638281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->dict = xmlDictCreate(); 638381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret->dict == NULL) { 638481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlFree(ret->table); 638581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlFree(ret); 638681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 638781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 638881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 638981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->dict = dict; 639081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlDictReference(ret->dict); 639181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 639281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 639381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 639481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 639581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 639681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpFreeCtxt: 639781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: an expression context 639881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 639981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Free an expression context 640081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 640181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardvoid 640281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpFreeCtxt(xmlExpCtxtPtr ctxt) { 640381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt == NULL) 640481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return; 640581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlDictFree(ctxt->dict); 640681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt->table != NULL) 640781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlFree(ctxt->table); 640881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlFree(ctxt); 640981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 641081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 641181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/************************************************************************ 641281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 641381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Structure associated to an expression node * 641481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 641581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ************************************************************************/ 6416465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#define MAX_NODES 10000 6417465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 6418465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/* #define DEBUG_DERIV */ 6419465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 6420465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/* 6421f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * TODO: 6422465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - Wildcards 6423465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - public API for creation 6424465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 6425465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Started 6426465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - regression testing 6427465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 6428465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Done 6429465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - split into module and test tool 6430465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - memleaks 6431465a000b1080427bd62d89a925409b7db78616acDaniel Veillard */ 643281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 643381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardtypedef enum { 643481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard XML_EXP_NILABLE = (1 << 0) 643581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} xmlExpNodeInfo; 643681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 643781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#define IS_NILLABLE(node) ((node)->info & XML_EXP_NILABLE) 643881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 643981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstruct _xmlExpNode { 644081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned char type;/* xmlExpNodeType */ 644181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned char info;/* OR of xmlExpNodeInfo */ 644281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned short key; /* the hash key */ 644381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned int ref; /* The number of references */ 644481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int c_max; /* the maximum length it can consume */ 644581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr exp_left; 644681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr next;/* the next node in the hash table or free list */ 644781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard union { 644881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard struct { 644981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int f_min; 645081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int f_max; 645181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } count; 645281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard struct { 645381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr f_right; 645481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } children; 645581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar *f_str; 645681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } field; 645781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard}; 645881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 645981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#define exp_min field.count.f_min 646081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#define exp_max field.count.f_max 646181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/* #define exp_left field.children.f_left */ 646281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#define exp_right field.children.f_right 646381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#define exp_str field.f_str 646481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 646581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNodePtr xmlExpNewNode(xmlExpCtxtPtr ctxt, xmlExpNodeType type); 646681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNode forbiddenExpNode = { 646781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard XML_EXP_FORBID, 0, 0, 0, 0, NULL, NULL, {{ 0, 0}} 646881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard}; 646981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpNodePtr forbiddenExp = &forbiddenExpNode; 647081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNode emptyExpNode = { 647181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard XML_EXP_EMPTY, 1, 0, 0, 0, NULL, NULL, {{ 0, 0}} 647281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard}; 647381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpNodePtr emptyExp = &emptyExpNode; 647481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 647581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/************************************************************************ 647681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 647781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * The custom hash table for unicity and canonicalization * 647881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * of sub-expressions pointers * 647981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 648081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ************************************************************************/ 648181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/* 648281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpHashNameComputeKey: 648381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Calculate the hash key for a token 648481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 648581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic unsigned short 648681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpHashNameComputeKey(const xmlChar *name) { 648781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned short value = 0L; 648881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard char ch; 6489f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 649081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (name != NULL) { 649181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value += 30 * (*name); 649281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard while ((ch = *name++) != 0) { 649381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); 649481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 649581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 649681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return (value); 649781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 649881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 649981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/* 650081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpHashComputeKey: 650181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Calculate the hash key for a compound expression 650281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 650381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic unsigned short 650481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpHashComputeKey(xmlExpNodeType type, xmlExpNodePtr left, 650581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr right) { 650681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned long value; 650781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned short ret; 6508f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 650981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard switch (type) { 651081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_SEQ: 651181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value = left->key; 651281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value += right->key; 651381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value *= 3; 651481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = (unsigned short) value; 651581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard break; 651681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_OR: 651781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value = left->key; 651881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value += right->key; 651981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value *= 7; 652081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = (unsigned short) value; 652181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard break; 652281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_COUNT: 652381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value = left->key; 652481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard value += right->key; 652581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = (unsigned short) value; 652681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard break; 652781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard default: 652881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = 0; 652981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 653081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 653181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 653281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 653381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 653481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNodePtr 653581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpNewNode(xmlExpCtxtPtr ctxt, xmlExpNodeType type) { 653681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr ret; 653781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 653881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt->nb_nodes >= MAX_NODES) 653981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 654081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = (xmlExpNodePtr) xmlMalloc(sizeof(xmlExpNode)); 654181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) 654281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 654381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard memset(ret, 0, sizeof(xmlExpNode)); 654481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->type = type; 654581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret->next = NULL; 654681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->nb_nodes++; 654781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->nb_cons++; 654881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 654981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 655081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 655181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 655281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpHashGetEntry: 655381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @table: the hash table 655481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 655581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Get the unique entry from the hash table. The entry is created if 655681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * needed. @left and @right are consumed, i.e. their ref count will 655781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * be decremented by the operation. 655881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 655981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the pointer or NULL in case of error 656081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 656181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNodePtr 656281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpHashGetEntry(xmlExpCtxtPtr ctxt, xmlExpNodeType type, 656381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr left, xmlExpNodePtr right, 656481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar *name, int min, int max) { 656581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned short kbase, key; 656681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr entry; 656781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr insert; 656881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 656981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt == NULL) 657081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 657181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 657281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 657381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Check for duplicate and insertion location. 657481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 657581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (type == XML_EXP_ATOM) { 657681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard kbase = xmlExpHashNameComputeKey(name); 657781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (type == XML_EXP_COUNT) { 657881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* COUNT reduction rule 1 */ 657981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* a{1} -> a */ 658081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (min == max) { 658181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (min == 1) { 658281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(left); 658381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 658481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (min == 0) { 658581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, left); 658681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(emptyExp); 658781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 658881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 658981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (min < 0) { 659081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, left); 659181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 659281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 659381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (max == -1) 659481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard kbase = min + 79; 659581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 659681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard kbase = max - min; 659781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard kbase += left->key; 659881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (type == XML_EXP_OR) { 659981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Forbid reduction rules */ 660081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left->type == XML_EXP_FORBID) { 660181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, left); 660281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(right); 660381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 660481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (right->type == XML_EXP_FORBID) { 660581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, right); 660681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(left); 660781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 660881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 660981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* OR reduction rule 1 */ 661081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* a | a reduced to a */ 661181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left == right) { 661281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->ref--; 661381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(left); 661481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 661581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* OR canonicalization rule 1 */ 661681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* linearize (a | b) | c into a | (b | c) */ 661781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((left->type == XML_EXP_OR) && (right->type != XML_EXP_OR)) { 661881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp = left; 661981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left = right; 662081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right = tmp; 662181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 662281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* OR reduction rule 2 */ 662381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* a | (a | b) and b | (a | b) are reduced to a | b */ 662481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (right->type == XML_EXP_OR) { 662581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((left == right->exp_left) || 662681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (left == right->exp_right)) { 662781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, left); 662881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(right); 662981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 663081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 663181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* OR canonicalization rule 2 */ 663281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* linearize (a | b) | c into a | (b | c) */ 663381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left->type == XML_EXP_OR) { 663481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 663581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 663681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* OR canonicalization rule 2 */ 663781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((left->exp_right->type != XML_EXP_OR) && 663881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (left->exp_right->key < left->exp_left->key)) { 663981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = left->exp_right; 664081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->exp_right = left->exp_left; 664181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->exp_left = tmp; 664281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 664381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->exp_right->ref++; 664481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left->exp_right, right, 664581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0); 664681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->exp_left->ref++; 664781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left->exp_left, tmp, 664881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0); 6649f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 665081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, left); 665181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 665281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 665381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (right->type == XML_EXP_OR) { 665481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Ordering in the tree */ 665581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* C | (A | B) -> A | (B | C) */ 665681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left->key > right->exp_right->key) { 665781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 665881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right->exp_right->ref++; 665981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_right, 666081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left, NULL, 0, 0); 666181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right->exp_left->ref++; 666281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_left, 666381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp, NULL, 0, 0); 666481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, right); 666581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 666681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 666781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Ordering in the tree */ 666881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* B | (A | C) -> A | (B | C) */ 666981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left->key > right->exp_left->key) { 667081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 667181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right->exp_right->ref++; 667281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left, 667381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right->exp_right, NULL, 0, 0); 667481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right->exp_left->ref++; 667581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_left, 667681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp, NULL, 0, 0); 667781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, right); 667881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 667981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 668081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 668181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* we know both types are != XML_EXP_OR here */ 668281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else if (left->key > right->key) { 668381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp = left; 668481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left = right; 668581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right = tmp; 668681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 668781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard kbase = xmlExpHashComputeKey(type, left, right); 668881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (type == XML_EXP_SEQ) { 668981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Forbid reduction rules */ 669081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left->type == XML_EXP_FORBID) { 669181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, right); 669281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(left); 669381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 669481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (right->type == XML_EXP_FORBID) { 669581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, left); 669681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(right); 669781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 669881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Empty reduction rules */ 669981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (right->type == XML_EXP_EMPTY) { 670081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(left); 670181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 670281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (left->type == XML_EXP_EMPTY) { 670381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(right); 670481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 670581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard kbase = xmlExpHashComputeKey(type, left, right); 6706f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } else 670781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 670881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 670981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard key = kbase % ctxt->size; 671081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt->table[key] != NULL) { 671181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard for (insert = ctxt->table[key]; insert != NULL; 671281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard insert = insert->next) { 671381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((insert->key == kbase) && 671481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (insert->type == type)) { 671581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (type == XML_EXP_ATOM) { 671681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (name == insert->exp_str) { 671781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard insert->ref++; 671881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(insert); 671981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 672081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (type == XML_EXP_COUNT) { 672181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((insert->exp_min == min) && (insert->exp_max == max) && 672281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (insert->exp_left == left)) { 672381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard insert->ref++; 672481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->ref--; 672581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(insert); 672681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 672781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if ((insert->exp_left == left) && 672881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (insert->exp_right == right)) { 672981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard insert->ref++; 673081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard left->ref--; 673181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard right->ref--; 673281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(insert); 673381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 673481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 673581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 673681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 673781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 673881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry = xmlExpNewNode(ctxt, type); 673981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (entry == NULL) 674081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 674181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->key = kbase; 674281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (type == XML_EXP_ATOM) { 674381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->exp_str = name; 674481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = 1; 674581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (type == XML_EXP_COUNT) { 674681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->exp_min = min; 674781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->exp_max = max; 674881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->exp_left = left; 674981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((min == 0) || (IS_NILLABLE(left))) 675081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->info |= XML_EXP_NILABLE; 675181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (max < 0) 675281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = -1; 675381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 675481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = max * entry->exp_left->c_max; 675581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 675681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->exp_left = left; 675781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->exp_right = right; 675881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (type == XML_EXP_OR) { 675981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((IS_NILLABLE(left)) || (IS_NILLABLE(right))) 676081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->info |= XML_EXP_NILABLE; 676181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((entry->exp_left->c_max == -1) || 676281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (entry->exp_right->c_max == -1)) 676381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = -1; 676481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else if (entry->exp_left->c_max > entry->exp_right->c_max) 676581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = entry->exp_left->c_max; 676681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 676781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = entry->exp_right->c_max; 676881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 676981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((IS_NILLABLE(left)) && (IS_NILLABLE(right))) 677081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->info |= XML_EXP_NILABLE; 677181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((entry->exp_left->c_max == -1) || 677281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (entry->exp_right->c_max == -1)) 677381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = -1; 677481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 677581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->c_max = entry->exp_left->c_max + entry->exp_right->c_max; 677681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 677781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 677881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->ref = 1; 677981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt->table[key] != NULL) 678081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard entry->next = ctxt->table[key]; 678181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 678281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->table[key] = entry; 678381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->nbElems++; 678481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 678581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(entry); 678681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 678781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 678881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 678981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpFree: 679081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expression context 679181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the expression 679281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 679381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Dereference the expression 679481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 679581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardvoid 679681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpFree(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp) { 679781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((exp == NULL) || (exp == forbiddenExp) || (exp == emptyExp)) 679881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return; 679981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->ref--; 680081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->ref == 0) { 680181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard unsigned short key; 680281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 680381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Unlink it first from the hash table */ 680481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard key = exp->key % ctxt->size; 680581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt->table[key] == exp) { 680681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->table[key] = exp->next; 680781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 680881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 680981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 681081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = ctxt->table[key]; 681181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard while (tmp != NULL) { 681281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp->next == exp) { 681381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp->next = exp->next; 681481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard break; 681581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 681681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = tmp->next; 681781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 681881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 681981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 682081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((exp->type == XML_EXP_SEQ) || (exp->type == XML_EXP_OR)) { 682181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, exp->exp_left); 682281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, exp->exp_right); 682381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (exp->type == XML_EXP_COUNT) { 682481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, exp->exp_left); 682581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 682681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlFree(exp); 682781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->nb_nodes--; 682881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 682981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 683081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 683181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 683281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpRef: 683381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the expression 683481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 683581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Increase the reference count of the expression 683681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 683781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardvoid 683881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpRef(xmlExpNodePtr exp) { 683981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp != NULL) 684081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->ref++; 684181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 684281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 6843ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard/** 6844ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * xmlExpNewAtom: 6845ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @ctxt: the expression context 6846ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @name: the atom name 6847fb27e2cd204ddb2cb0163b4b6418cc494889d279Michael Wood * @len: the atom name length in byte (or -1); 6848ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6849ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Get the atom associated to this name from that context 6850ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6851ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Returns the node or NULL in case of error 6852ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard */ 6853ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNodePtr 6854ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNewAtom(xmlExpCtxtPtr ctxt, const xmlChar *name, int len) { 6855ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard if ((ctxt == NULL) || (name == NULL)) 6856ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(NULL); 6857ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard name = xmlDictLookup(ctxt->dict, name, len); 6858ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard if (name == NULL) 6859ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(NULL); 6860ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_ATOM, NULL, NULL, name, 0, 0)); 6861ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard} 6862ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard 6863ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard/** 6864ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * xmlExpNewOr: 6865ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @ctxt: the expression context 6866ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @left: left expression 6867ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @right: right expression 6868ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6869ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Get the atom associated to the choice @left | @right 6870ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Note that @left and @right are consumed in the operation, to keep 6871ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * an handle on them use xmlExpRef() and use xmlExpFree() to release them, 6872ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * this is true even in case of failure (unless ctxt == NULL). 6873ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6874ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Returns the node or NULL in case of error 6875ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard */ 6876ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNodePtr 6877ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNewOr(xmlExpCtxtPtr ctxt, xmlExpNodePtr left, xmlExpNodePtr right) { 687811ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (ctxt == NULL) 687911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard return(NULL); 688011ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if ((left == NULL) || (right == NULL)) { 6881ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard xmlExpFree(ctxt, left); 6882ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard xmlExpFree(ctxt, right); 6883ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(NULL); 6884ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard } 6885ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, left, right, NULL, 0, 0)); 6886ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard} 6887ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard 6888ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard/** 6889ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * xmlExpNewSeq: 6890ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @ctxt: the expression context 6891ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @left: left expression 6892ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @right: right expression 6893ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6894ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Get the atom associated to the sequence @left , @right 6895ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Note that @left and @right are consumed in the operation, to keep 6896ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * an handle on them use xmlExpRef() and use xmlExpFree() to release them, 6897ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * this is true even in case of failure (unless ctxt == NULL). 6898ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6899ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Returns the node or NULL in case of error 6900ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard */ 6901ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNodePtr 6902ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNewSeq(xmlExpCtxtPtr ctxt, xmlExpNodePtr left, xmlExpNodePtr right) { 690311ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (ctxt == NULL) 690411ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard return(NULL); 690511ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if ((left == NULL) || (right == NULL)) { 6906ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard xmlExpFree(ctxt, left); 6907ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard xmlExpFree(ctxt, right); 6908ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(NULL); 6909ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard } 6910ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, left, right, NULL, 0, 0)); 6911ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard} 6912ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard 6913ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard/** 6914ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * xmlExpNewRange: 6915ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @ctxt: the expression context 6916ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @subset: the expression to be repeated 6917ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @min: the lower bound for the repetition 6918ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * @max: the upper bound for the repetition, -1 means infinite 6919ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6920ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Get the atom associated to the range (@subset){@min, @max} 6921ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Note that @subset is consumed in the operation, to keep 6922ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * an handle on it use xmlExpRef() and use xmlExpFree() to release it, 6923ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * this is true even in case of failure (unless ctxt == NULL). 6924ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * 6925ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard * Returns the node or NULL in case of error 6926ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard */ 6927ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNodePtr 6928ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel VeillardxmlExpNewRange(xmlExpCtxtPtr ctxt, xmlExpNodePtr subset, int min, int max) { 692911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (ctxt == NULL) 693011ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard return(NULL); 693111ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if ((subset == NULL) || (min < 0) || (max < -1) || 6932ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard ((max >= 0) && (min > max))) { 6933ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard xmlExpFree(ctxt, subset); 6934ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(NULL); 6935ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard } 6936ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, subset, 6937ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard NULL, NULL, min, max)); 6938ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard} 6939ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard 694081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/************************************************************************ 694181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 694281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Public API for operations on expressions * 694381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * * 694481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ************************************************************************/ 694581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 694681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic int 6947f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel VeillardxmlExpGetLanguageInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 694881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar**list, int len, int nb) { 694981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int tmp, tmp2; 695081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardtail: 695181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard switch (exp->type) { 695281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_EMPTY: 695381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 695481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_ATOM: 695581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard for (tmp = 0;tmp < nb;tmp++) 695681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (list[tmp] == exp->exp_str) 695781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 695881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (nb >= len) 695981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-2); 696013cee4e37ba9f2a401f976e069539514ebfce7bcDaniel Veillard list[nb] = exp->exp_str; 696181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(1); 696281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_COUNT: 696381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp = exp->exp_left; 696481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard goto tail; 696581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_SEQ: 696681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_OR: 696781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpGetLanguageInt(ctxt, exp->exp_left, list, len, nb); 696881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp < 0) 696981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 697081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpGetLanguageInt(ctxt, exp->exp_right, list, len, 697181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard nb + tmp); 697281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 < 0) 697381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp2); 697481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp + tmp2); 697581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 697681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 697781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 697881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 697981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 698081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpGetLanguage: 698181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expression context 698281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the expression 69837802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard * @langList: where to store the tokens 6984fb27e2cd204ddb2cb0163b4b6418cc494889d279Michael Wood * @len: the allocated length of @list 698581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 698681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Find all the strings used in @exp and store them in @list 698781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 698881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the number of unique strings found, -1 in case of errors and 698981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * -2 if there is more than @len strings 699081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 699181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardint 6992f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel VeillardxmlExpGetLanguage(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 69937802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard const xmlChar**langList, int len) { 69947802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard if ((ctxt == NULL) || (exp == NULL) || (langList == NULL) || (len <= 0)) 699581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 69967802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard return(xmlExpGetLanguageInt(ctxt, exp, langList, len, 0)); 699781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 699881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 699981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic int 7000f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel VeillardxmlExpGetStartInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 700181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar**list, int len, int nb) { 700281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int tmp, tmp2; 700381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardtail: 700481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard switch (exp->type) { 700581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_FORBID: 700681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 700781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_EMPTY: 700881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 700981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_ATOM: 701081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard for (tmp = 0;tmp < nb;tmp++) 701181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (list[tmp] == exp->exp_str) 701281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 701381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (nb >= len) 701481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-2); 701513cee4e37ba9f2a401f976e069539514ebfce7bcDaniel Veillard list[nb] = exp->exp_str; 701681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(1); 701781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_COUNT: 701881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp = exp->exp_left; 701981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard goto tail; 702081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_SEQ: 702181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpGetStartInt(ctxt, exp->exp_left, list, len, nb); 702281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp < 0) 702381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 702481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (IS_NILLABLE(exp->exp_left)) { 702581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpGetStartInt(ctxt, exp->exp_right, list, len, 702681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard nb + tmp); 702781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 < 0) 702881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp2); 702981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp += tmp2; 703081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 703181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 703281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_OR: 703381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpGetStartInt(ctxt, exp->exp_left, list, len, nb); 703481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp < 0) 703581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 703681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpGetStartInt(ctxt, exp->exp_right, list, len, 703781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard nb + tmp); 703881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 < 0) 703981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp2); 704081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp + tmp2); 704181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 704281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 704381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 704481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 704581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 704681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpGetStart: 704781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expression context 704881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the expression 70497802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard * @tokList: where to store the tokens 7050fb27e2cd204ddb2cb0163b4b6418cc494889d279Michael Wood * @len: the allocated length of @list 705181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 705281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Find all the strings that appears at the start of the languages 705381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * accepted by @exp and store them in @list. E.g. for (a, b) | c 705481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * it will return the list [a, c] 705581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 705681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the number of unique strings found, -1 in case of errors and 705781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * -2 if there is more than @len strings 705881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 705981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardint 7060f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel VeillardxmlExpGetStart(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 70617802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard const xmlChar**tokList, int len) { 70627802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard if ((ctxt == NULL) || (exp == NULL) || (tokList == NULL) || (len <= 0)) 706381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 70647802ba56ff32eb503ac34885e1ce61b60a01d701Daniel Veillard return(xmlExpGetStartInt(ctxt, exp, tokList, len, 0)); 706581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 706681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 706781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 706881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpIsNillable: 706981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the expression 707081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 707181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Finds if the expression is nillable, i.e. if it accepts the empty sequqnce 707281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 707381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns 1 if nillable, 0 if not and -1 in case of error 707481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 707581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardint 707681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpIsNillable(xmlExpNodePtr exp) { 707781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp == NULL) 707881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 707981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(IS_NILLABLE(exp) != 0); 708081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 708181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 708281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNodePtr 708381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpStringDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, const xmlChar *str) 708481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard{ 708581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr ret; 708681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 708781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard switch (exp->type) { 708881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_EMPTY: 708981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 709081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_FORBID: 709181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 709281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_ATOM: 709381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_str == str) { 709481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 709581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv atom: equal => Empty\n"); 709681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 709781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = emptyExp; 709881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 709981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 710081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv atom: mismatch => forbid\n"); 710181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 710281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* TODO wildcards here */ 710381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = forbiddenExp; 710481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 710581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 710681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_OR: { 710781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 710881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 710981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 711081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv or: => or(derivs)\n"); 711181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 711281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpStringDeriveInt(ctxt, exp->exp_left, str); 711381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) { 711481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 711581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 711681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpStringDeriveInt(ctxt, exp->exp_right, str); 711781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) { 711881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 711981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 712081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 712181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, tmp, ret, 712281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0); 712381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 712481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 712581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_SEQ: 712681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 712781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv seq: starting with left\n"); 712881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 712981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpStringDeriveInt(ctxt, exp->exp_left, str); 713081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) { 713181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 713281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (ret == forbiddenExp) { 713381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (IS_NILLABLE(exp->exp_left)) { 713481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 713581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv seq: left failed but nillable\n"); 713681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 713781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpStringDeriveInt(ctxt, exp->exp_right, str); 713881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 713981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 714081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 714181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv seq: left match => sequence\n"); 714281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 714381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_right->ref++; 714481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, exp->exp_right, 714581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0); 714681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 714781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 714881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_COUNT: { 714981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int min, max; 715081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 715181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 715281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max == 0) 715381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 715481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpStringDeriveInt(ctxt, exp->exp_left, str); 715581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) 715681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 715781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == forbiddenExp) { 715881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 715981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv count: pattern mismatch => forbid\n"); 716081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 716181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 716281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 716381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max == 1) 716481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 716581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max < 0) /* unbounded */ 716681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 716781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 716881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = exp->exp_max - 1; 716981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_min > 0) 717081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - 1; 717181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 717281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 717381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_left->ref++; 717481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left, NULL, 717581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, min, max); 717681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == emptyExp) { 717781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 717881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv count: match to empty => new count\n"); 717981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 718081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 718181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 718281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 718381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("deriv count: match => sequence with new count\n"); 718481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 718581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, tmp, 718681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0)); 718781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 718881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 718981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 719081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 719181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 719281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 719381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpStringDerive: 719481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expression context 719581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the expression 719681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @str: the string 719781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @len: the string len in bytes if available 719881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 719981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Do one step of Brzozowski derivation of the expression @exp with 720081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * respect to the input string 720181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 720281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the resulting expression or NULL in case of internal error 720381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 720481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpNodePtr 720581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpStringDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 720681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar *str, int len) { 720781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar *input; 720881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 720981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((exp == NULL) || (ctxt == NULL) || (str == NULL)) { 721081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 721181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 721281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 7213bb654feb9a64db7fd8b5fefdbb79792883dc7795Jan Pokorný * check the string is in the dictionary, if yes use an interned 721481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * copy, otherwise we know it's not an acceptable input 721581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 721681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard input = xmlDictExists(ctxt->dict, str, len); 721781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (input == NULL) { 721881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 721981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 722081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(xmlExpStringDeriveInt(ctxt, exp, input)); 722181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 722281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 722381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic int 722481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpCheckCard(xmlExpNodePtr exp, xmlExpNodePtr sub) { 722581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int ret = 1; 722681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 722781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->c_max == -1) { 722881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->c_max != -1) 722981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = 0; 723081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if ((exp->c_max >= 0) && (exp->c_max < sub->c_max)) { 723181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = 0; 723281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 723381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#if 0 723481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((IS_NILLABLE(sub)) && (!IS_NILLABLE(exp))) 723581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = 0; 723681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 723781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 723881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 723981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 724081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNodePtr xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 724181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr sub); 724281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 724381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpDivide: 724481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expressions context 724581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the englobing expression 724681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @sub: the subexpression 724781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @mult: the multiple expression 724881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @remain: the remain from the derivation of the multiple 724981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 725081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Check if exp is a multiple of sub, i.e. if there is a finite number n 725181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * so that sub{n} subsume exp 725281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 725381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the multiple value if successful, 0 if it is not a multiple 725481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * and -1 in case of internel error. 725581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 725681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 725781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic int 725881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpDivide(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub, 725981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr *mult, xmlExpNodePtr *remain) { 726081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int i; 726181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp, tmp2; 726281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 726381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (mult != NULL) *mult = NULL; 726481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (remain != NULL) *remain = NULL; 726581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->c_max == -1) return(0); 726681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (IS_NILLABLE(exp) && (!IS_NILLABLE(sub))) return(0); 726781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 726881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard for (i = 1;i <= exp->c_max;i++) { 726981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard sub->ref++; 727081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, 727181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard sub, NULL, NULL, i, i); 727281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) { 727381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 727481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 727581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (!xmlExpCheckCard(tmp, exp)) { 727681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 727781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard continue; 727881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 727981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpExpDeriveInt(ctxt, tmp, exp); 728081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 == NULL) { 728181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 728281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 728381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 728481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((tmp2 != forbiddenExp) && (IS_NILLABLE(tmp2))) { 728581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (remain != NULL) 728681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard *remain = tmp2; 728781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 728881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp2); 728981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (mult != NULL) 729081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard *mult = tmp; 729181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 729281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 729381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 729481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Divide succeeded %d\n", i); 729581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 729681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(i); 729781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 729881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 729981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp2); 730081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 730181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 730281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Divide failed\n"); 730381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 730481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 730581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 730681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 730781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 730881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpExpDeriveInt: 730981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expressions context 731081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the englobing expression 731181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @sub: the subexpression 731281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 731381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Try to do a step of Brzozowski derivation but at a higher level 731481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * the input being a subexpression. 731581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 731681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns the resulting expression or NULL in case of internal error 731781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 731881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardstatic xmlExpNodePtr 731981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) { 732081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr ret, tmp, tmp2, tmp3; 732181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar **tab; 732281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int len, i; 732381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 732481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 732581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * In case of equality and if the expression can only consume a finite 732681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * amount, then the derivation is empty 732781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 732881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((exp == sub) && (exp->c_max >= 0)) { 732981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 733081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Equal(exp, sub) and finite -> Empty\n"); 733181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 733281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(emptyExp); 733381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 733481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 733581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * decompose sub sequence first 733681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 733781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->type == XML_EXP_EMPTY) { 733881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 733981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Empty(sub) -> Empty\n"); 734081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 734181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->ref++; 734281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(exp); 734381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 734481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->type == XML_EXP_SEQ) { 734581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 734681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Seq(sub) -> decompose\n"); 734781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 734881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpExpDeriveInt(ctxt, exp, sub->exp_left); 734981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) 735081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 735181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == forbiddenExp) 735281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 735381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpExpDeriveInt(ctxt, tmp, sub->exp_right); 735481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 735581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 735681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 735781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->type == XML_EXP_OR) { 735881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 735981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Or(sub) -> decompose\n"); 736081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 736181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpExpDeriveInt(ctxt, exp, sub->exp_left); 736281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == forbiddenExp) 736381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 736481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) 736581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 736681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpExpDeriveInt(ctxt, exp, sub->exp_right); 736781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((ret == NULL) || (ret == forbiddenExp)) { 736881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 736981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 737081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 737181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, tmp, ret, NULL, 0, 0)); 737281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 737381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (!xmlExpCheckCard(exp, sub)) { 737481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 737581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("CheckCard(exp, sub) failed -> Forbid\n"); 737681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 737781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 737881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 737981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard switch (exp->type) { 738081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_EMPTY: 738181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub == emptyExp) 738281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(emptyExp); 738381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 738481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Empty(exp) -> Forbid\n"); 738581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 738681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 738781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_FORBID: 738881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 738981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Forbid(exp) -> Forbid\n"); 739081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 739181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 739281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_ATOM: 739381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->type == XML_EXP_ATOM) { 739481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* TODO: handle wildcards */ 739581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_str == sub->exp_str) { 739681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 739781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Atom match -> Empty\n"); 739881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 739981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(emptyExp); 740081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 740181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 740281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Atom mismatch -> Forbid\n"); 740381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 740481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 740581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 740681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((sub->type == XML_EXP_COUNT) && 740781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (sub->exp_max == 1) && 740881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard (sub->exp_left->type == XML_EXP_ATOM)) { 740981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* TODO: handle wildcards */ 741081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_str == sub->exp_left->exp_str) { 741181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 741281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Atom match -> Empty\n"); 741381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 741481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(emptyExp); 741581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 741681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 741781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Atom mismatch -> Forbid\n"); 741881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 741981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 742081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 742181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 742281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Compex exp vs Atom -> Forbid\n"); 742381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 742481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 742581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_SEQ: 742681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* try to get the sequence consumed only if possible */ 742781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (xmlExpCheckCard(exp->exp_left, sub)) { 742881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* See if the sequence can be consumed directly */ 742981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 743081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Seq trying left only\n"); 743181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 743281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub); 743381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((ret != forbiddenExp) && (ret != NULL)) { 743481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 743581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Seq trying left only worked\n"); 743681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 743781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 743881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * TODO: assumption here that we are determinist 743981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * i.e. we won't get to a nillable exp left 744081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * subset which could be matched by the right 744181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * part too. 744281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * e.g.: (a | b)+,(a | c) and 'a+,a' 744381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 744481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_right->ref++; 744581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, 744681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_right, NULL, 0, 0)); 744781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 744881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 744981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 745081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Seq: left too short\n"); 745181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 745281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 745381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* Try instead to decompose */ 745481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->type == XML_EXP_COUNT) { 745581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int min, max; 745681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 745781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 745881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Seq: sub is a count\n"); 745981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 746081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub->exp_left); 746181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) 746281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 746381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret != forbiddenExp) { 746481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 746581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Seq , Count match on left\n"); 746681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 746781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->exp_max < 0) 746881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 746981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 747081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = sub->exp_max -1; 747181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->exp_min > 0) 747281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = sub->exp_min -1; 747381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 747481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 747581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_right->ref++; 747681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, 747781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_right, NULL, 0, 0); 747881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) 747981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 748081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 748181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard sub->exp_left->ref++; 748281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, 748381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard sub->exp_left, NULL, NULL, min, max); 748481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 == NULL) { 748581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 748681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 748781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 748881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpExpDeriveInt(ctxt, tmp, tmp2); 748981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 749081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp2); 749181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 749281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 749381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 749481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* we made no progress on structured operations */ 749581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard break; 749681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_OR: 749781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 749881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Or , trying both side\n"); 749981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 750081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub); 750181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) 750281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 750381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpExpDeriveInt(ctxt, exp->exp_right, sub); 750481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) { 750581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, ret); 750681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 750781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 750881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, tmp, NULL, 0, 0)); 750981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard case XML_EXP_COUNT: { 751081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int min, max; 751181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 751281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->type == XML_EXP_COUNT) { 751381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 751481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Try to see if the loop is completely subsumed 751581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 751681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub->exp_left); 751781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) 751881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 751981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == forbiddenExp) { 752081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard int mult; 752181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 752281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 752381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Count, Count inner don't subsume\n"); 752481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 752581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard mult = xmlExpDivide(ctxt, sub->exp_left, exp->exp_left, 752681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, &tmp); 752781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (mult <= 0) { 752881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 752981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Count, Count not multiple => forbidden\n"); 753081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 753181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 753281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 753381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->exp_max == -1) { 753481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 753581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max == -1) { 753681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_min <= sub->exp_min * mult) 753781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 753881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 753981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - sub->exp_min * mult; 754081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 754181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 754281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Count, Count finite can't subsume infinite\n"); 754381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 754481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 754581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 754681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 754781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 754881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max == -1) { 754981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 755081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Infinite loop consume mult finite loop\n"); 755181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 755281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_min > sub->exp_min * mult) { 755381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 755481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - sub->exp_min * mult; 755581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 755681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 755781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 755881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 755981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 756081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max < sub->exp_max * mult) { 756181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 756281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("loops max mult mismatch => forbidden\n"); 756381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 756481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 756581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 756681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 756781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->exp_max * mult > exp->exp_min) 756881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 756981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 757081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - sub->exp_max * mult; 757181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = exp->exp_max - sub->exp_max * mult; 757281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 757381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 757481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (!IS_NILLABLE(tmp)) { 757581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 757681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * TODO: loop here to try to grow if working on finite 757781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * blocks. 757881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 757981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 758081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Count, Count remain not nillable => forbidden\n"); 758181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 758281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 758381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 758481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (sub->exp_max == -1) { 758581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max == -1) { 758681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_min <= sub->exp_min) { 758781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 758881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Infinite loops Okay => COUNT(0,Inf)\n"); 758981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 759081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 759181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 759281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 759381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 759481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Infinite loops min => Count(X,Inf)\n"); 759581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 759681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 759781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - sub->exp_min; 759881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 759981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else if (exp->exp_min > sub->exp_min) { 760081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 760181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("loops min mismatch 1 => forbidden ???\n"); 760281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 760381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 760481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 760581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 760681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 760781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 760881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 760981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 761081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max == -1) { 761181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 761281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Infinite loop consume finite loop\n"); 761381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 761481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_min > sub->exp_min) { 761581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 761681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - sub->exp_min; 761781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 761881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 761981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 762081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 762181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } else { 762281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max < sub->exp_max) { 762381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 762481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("loops max mismatch => forbidden\n"); 762581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 762681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 762781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 762881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 762981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (sub->exp_max > exp->exp_min) 763081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 763181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 763281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - sub->exp_max; 763381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = exp->exp_max - sub->exp_max; 763481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 763581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 763681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 763781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("loops match => SEQ(COUNT())\n"); 763881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 763981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_left->ref++; 764081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left, 764181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, NULL, min, max); 764281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 == NULL) { 764381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 764481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 764581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, tmp, tmp2, 764681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0); 764781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 764881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 764981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub); 765081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) 765181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 765281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == forbiddenExp) { 765381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 765481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("loop mismatch => forbidden\n"); 765581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 765681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(forbiddenExp); 765781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 765881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_min > 0) 765981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = exp->exp_min - 1; 766081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 766181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard min = 0; 766281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (exp->exp_max < 0) 766381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = -1; 766481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else 766581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard max = exp->exp_max - 1; 766681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 766781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 766881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("loop match => SEQ(COUNT())\n"); 766981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 767081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard exp->exp_left->ref++; 767181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left, 767281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, NULL, min, max); 767381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp2 == NULL) 767481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 767581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, tmp, tmp2, 767681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard NULL, 0, 0); 767781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 767881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 767981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 768081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 7681ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard#ifdef DEBUG_DERIV 7682ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard printf("Fallback to derivative\n"); 7683ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard#endif 7684ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard if (IS_NILLABLE(sub)) { 7685ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard if (!(IS_NILLABLE(exp))) 7686ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard return(forbiddenExp); 7687ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard else 7688ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard ret = emptyExp; 7689ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard } else 7690ccb4d41c13bea3c81cf074ed43b84bd686c7d124Daniel Veillard ret = NULL; 769181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 769281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * here the structured derivation made no progress so 769381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * we use the default token based derivation to force one more step 769481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 769581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ctxt->tabSize == 0) 769681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->tabSize = 40; 769781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 769881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tab = (const xmlChar **) xmlMalloc(ctxt->tabSize * 769981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard sizeof(const xmlChar *)); 770081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tab == NULL) { 770181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 770281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 770381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 770481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 770581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * collect all the strings accepted by the subexpression on input 770681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 770781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0); 770881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard while (len < 0) { 770981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard const xmlChar **temp; 771054a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards temp = (const xmlChar **) xmlRealloc((xmlChar **) tab, ctxt->tabSize * 2 * 771181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard sizeof(const xmlChar *)); 771281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (temp == NULL) { 771354a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards xmlFree((xmlChar **) tab); 771481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 771581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 771681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tab = temp; 771781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ctxt->tabSize *= 2; 771881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0); 771981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 772081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard for (i = 0;i < len;i++) { 772181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpStringDeriveInt(ctxt, exp, tab[i]); 772281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((tmp == NULL) || (tmp == forbiddenExp)) { 772381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, ret); 772454a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards xmlFree((xmlChar **) tab); 772581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 772681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 772781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp2 = xmlExpStringDeriveInt(ctxt, sub, tab[i]); 772881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((tmp2 == NULL) || (tmp2 == forbiddenExp)) { 772981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 773081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, ret); 773154a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards xmlFree((xmlChar **) tab); 773281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp); 773381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 773481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp3 = xmlExpExpDeriveInt(ctxt, tmp, tmp2); 773581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 773681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp2); 773781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 773881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((tmp3 == NULL) || (tmp3 == forbiddenExp)) { 773981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, ret); 774054a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards xmlFree((xmlChar **) tab); 774181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(tmp3); 774281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 774381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 774481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) 774581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = tmp3; 774681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard else { 774781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, tmp3, NULL, 0, 0); 774881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (ret == NULL) { 774954a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards xmlFree((xmlChar **) tab); 775081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(NULL); 775181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 775281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 775381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 775454a8f67c0504bb1bc17a2e5f139f3128953915d1Rob Richards xmlFree((xmlChar **) tab); 775581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(ret); 775681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 7757f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 775881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard/** 77590090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * xmlExpExpDerive: 77600090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * @ctxt: the expressions context 77610090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * @exp: the englobing expression 77620090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * @sub: the subexpression 77630090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * 77640090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * Evaluates the expression resulting from @exp consuming a sub expression @sub 77650090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * Based on algebraic derivation and sometimes direct Brzozowski derivation 77660090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * it usually tatkes less than linear time and can handle expressions generating 77670090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * infinite languages. 77680090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * 77690090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * Returns the resulting expression or NULL in case of internal error, the 77700090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * result must be freed 77710090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard */ 77720090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel VeillardxmlExpNodePtr 77730090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel VeillardxmlExpExpDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) { 77740090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard if ((exp == NULL) || (ctxt == NULL) || (sub == NULL)) 77750090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard return(NULL); 77760090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard 77770090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard /* 77780090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard * O(1) speedups 77790090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard */ 77800090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard if (IS_NILLABLE(sub) && (!IS_NILLABLE(exp))) { 77810090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard#ifdef DEBUG_DERIV 77820090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard printf("Sub nillable and not exp : can't subsume\n"); 77830090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard#endif 77840090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard return(forbiddenExp); 77850090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard } 77860090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard if (xmlExpCheckCard(exp, sub) == 0) { 77870090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard#ifdef DEBUG_DERIV 77880090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard printf("sub generate longuer sequances than exp : can't subsume\n"); 77890090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard#endif 77900090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard return(forbiddenExp); 77910090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard } 77920090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard return(xmlExpExpDeriveInt(ctxt, exp, sub)); 77930090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard} 77940090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard 77950090bd524f6dee77bc4bbcad8e2158c5783f35a1Daniel Veillard/** 779681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * xmlExpSubsume: 779781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @ctxt: the expressions context 779881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @exp: the englobing expression 779981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * @sub: the subexpression 780081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 780181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Check whether @exp accepts all the languages accexpted by @sub 780281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * the input being a subexpression. 780381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * 780481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * Returns 1 if true 0 if false and -1 in case of failure. 780581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 780681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillardint 780781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel VeillardxmlExpSubsume(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) { 780881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpNodePtr tmp; 7809f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 781081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((exp == NULL) || (ctxt == NULL) || (sub == NULL)) 781181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 781281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard 781381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 781481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * TODO: speedup by checking the language of sub is a subset of the 781581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * language of exp 781681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 781781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard /* 781881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard * O(1) speedups 781981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard */ 782081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (IS_NILLABLE(sub) && (!IS_NILLABLE(exp))) { 782181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 782281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Sub nillable and not exp : can't subsume\n"); 782381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 782481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 782581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 782681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (xmlExpCheckCard(exp, sub) == 0) { 782781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 782881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("sub generate longuer sequances than exp : can't subsume\n"); 782981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 783081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 783181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 783281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard tmp = xmlExpExpDeriveInt(ctxt, exp, sub); 783381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#ifdef DEBUG_DERIV 783481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard printf("Result derivation :\n"); 783581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard PRINT_EXP(tmp); 783681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif 783781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == NULL) 783881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(-1); 783981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == forbiddenExp) 784081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 784181a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if (tmp == emptyExp) 784281a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(1); 784381a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard if ((tmp != NULL) && (IS_NILLABLE(tmp))) { 784481a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 784581a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(1); 784681a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard } 784781a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard xmlExpFree(ctxt, tmp); 784881a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard return(0); 784981a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard} 7850465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7851465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/************************************************************************ 7852465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * * 7853f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Parsing expression * 7854465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * * 7855465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ************************************************************************/ 7856465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7857465a000b1080427bd62d89a925409b7db78616acDaniel Veillardstatic xmlExpNodePtr xmlExpParseExpr(xmlExpCtxtPtr ctxt); 7858465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7859465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#undef CUR 7860465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#define CUR (*ctxt->cur) 7861465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#undef NEXT 7862465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#define NEXT ctxt->cur++; 7863465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#undef IS_BLANK 7864465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#define IS_BLANK(c) ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t')) 7865465a000b1080427bd62d89a925409b7db78616acDaniel Veillard#define SKIP_BLANKS while (IS_BLANK(*ctxt->cur)) ctxt->cur++; 7866465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7867465a000b1080427bd62d89a925409b7db78616acDaniel Veillardstatic int 7868465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpParseNumber(xmlExpCtxtPtr ctxt) { 7869465a000b1080427bd62d89a925409b7db78616acDaniel Veillard int ret = 0; 7870465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7871465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7872465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (CUR == '*') { 7873465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7874465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(-1); 7875465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7876465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((CUR < '0') || (CUR > '9')) 7877465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(-1); 7878465a000b1080427bd62d89a925409b7db78616acDaniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 7879465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = ret * 10 + (CUR - '0'); 7880465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7881465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7882465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(ret); 7883465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 7884465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7885465a000b1080427bd62d89a925409b7db78616acDaniel Veillardstatic xmlExpNodePtr 7886465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpParseOr(xmlExpCtxtPtr ctxt) { 7887465a000b1080427bd62d89a925409b7db78616acDaniel Veillard const char *base; 7888465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpNodePtr ret; 7889465a000b1080427bd62d89a925409b7db78616acDaniel Veillard const xmlChar *val; 7890465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7891465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7892465a000b1080427bd62d89a925409b7db78616acDaniel Veillard base = ctxt->cur; 7893465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (*ctxt->cur == '(') { 7894465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7895465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpParseExpr(ctxt); 7896465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7897465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (*ctxt->cur != ')') { 7898465a000b1080427bd62d89a925409b7db78616acDaniel Veillard fprintf(stderr, "unbalanced '(' : %s\n", base); 7899465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpFree(ctxt, ret); 7900465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7901465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7902465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT; 7903465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7904465a000b1080427bd62d89a925409b7db78616acDaniel Veillard goto parse_quantifier; 7905465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7906465a000b1080427bd62d89a925409b7db78616acDaniel Veillard while ((CUR != 0) && (!(IS_BLANK(CUR))) && (CUR != '(') && 7907465a000b1080427bd62d89a925409b7db78616acDaniel Veillard (CUR != ')') && (CUR != '|') && (CUR != ',') && (CUR != '{') && 7908465a000b1080427bd62d89a925409b7db78616acDaniel Veillard (CUR != '*') && (CUR != '+') && (CUR != '?') && (CUR != '}')) 7909465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT; 7910465a000b1080427bd62d89a925409b7db78616acDaniel Veillard val = xmlDictLookup(ctxt->dict, BAD_CAST base, ctxt->cur - base); 7911465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (val == NULL) 7912465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7913465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_ATOM, NULL, NULL, val, 0, 0); 7914465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (ret == NULL) 7915465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7916465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7917465a000b1080427bd62d89a925409b7db78616acDaniel Veillardparse_quantifier: 7918465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (CUR == '{') { 7919465a000b1080427bd62d89a925409b7db78616acDaniel Veillard int min, max; 7920465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7921465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7922465a000b1080427bd62d89a925409b7db78616acDaniel Veillard min = xmlExpParseNumber(ctxt); 7923465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (min < 0) { 7924465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpFree(ctxt, ret); 7925465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7926465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7927465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7928465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (CUR == ',') { 7929465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7930465a000b1080427bd62d89a925409b7db78616acDaniel Veillard max = xmlExpParseNumber(ctxt); 7931465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7932465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else 7933465a000b1080427bd62d89a925409b7db78616acDaniel Veillard max = min; 7934465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (CUR != '}') { 7935465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpFree(ctxt, ret); 7936465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7937465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7938465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7939465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL, 7940465a000b1080427bd62d89a925409b7db78616acDaniel Veillard min, max); 7941465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7942465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if (CUR == '?') { 7943465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7944465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL, 7945465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 0, 1); 7946465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7947465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if (CUR == '+') { 7948465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7949465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL, 7950465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 1, -1); 7951465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7952465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if (CUR == '*') { 7953465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7954465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL, 7955465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 0, -1); 7956465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7957f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 7958465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(ret); 7959465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 7960465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7961465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7962465a000b1080427bd62d89a925409b7db78616acDaniel Veillardstatic xmlExpNodePtr 7963465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpParseSeq(xmlExpCtxtPtr ctxt) { 7964465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpNodePtr ret, right; 7965465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7966465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpParseOr(ctxt); 7967465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7968465a000b1080427bd62d89a925409b7db78616acDaniel Veillard while (CUR == '|') { 7969465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7970465a000b1080427bd62d89a925409b7db78616acDaniel Veillard right = xmlExpParseOr(ctxt); 7971465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (right == NULL) { 7972465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpFree(ctxt, ret); 7973465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7974465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7975465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, 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 Veillardstatic xmlExpNodePtr 7983465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpParseExpr(xmlExpCtxtPtr ctxt) { 7984465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpNodePtr ret, right; 7985465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 7986465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpParseSeq(ctxt); 7987465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 7988465a000b1080427bd62d89a925409b7db78616acDaniel Veillard while (CUR == ',') { 7989465a000b1080427bd62d89a925409b7db78616acDaniel Veillard NEXT 7990465a000b1080427bd62d89a925409b7db78616acDaniel Veillard right = xmlExpParseSeq(ctxt); 7991465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (right == NULL) { 7992465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpFree(ctxt, ret); 7993465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7994465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7995465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, right, NULL, 0, 0); 7996465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (ret == NULL) 7997465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 7998465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 7999465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(ret); 8000465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 8001465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8002465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/** 8003465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * xmlExpParse: 8004465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @ctxt: the expressions context 8005465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @expr: the 0 terminated string 8006465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8007465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Minimal parser for regexps, it understand the following constructs 8008465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - string terminals 8009465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - choice operator | 8010465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - sequence operator , 8011465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - subexpressions (...) 8012465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - usual cardinality operators + * and ? 8013465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - finite sequences { min, max } 8014465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * - infinite sequences { min, * } 8015465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * There is minimal checkings made especially no checking on strings values 8016465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8017465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Returns a new expression or NULL in case of failure 8018465a000b1080427bd62d89a925409b7db78616acDaniel Veillard */ 8019465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpNodePtr 8020465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpParse(xmlExpCtxtPtr ctxt, const char *expr) { 8021465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpNodePtr ret; 8022465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8023465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ctxt->expr = expr; 8024465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ctxt->cur = expr; 8025465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8026465a000b1080427bd62d89a925409b7db78616acDaniel Veillard ret = xmlExpParseExpr(ctxt); 8027465a000b1080427bd62d89a925409b7db78616acDaniel Veillard SKIP_BLANKS 8028465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (*ctxt->cur != 0) { 8029465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpFree(ctxt, ret); 8030465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(NULL); 8031465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 8032465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(ret); 8033465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 8034465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8035465a000b1080427bd62d89a925409b7db78616acDaniel Veillardstatic void 8036465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpDumpInt(xmlBufferPtr buf, xmlExpNodePtr expr, int glob) { 8037465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpNodePtr c; 8038465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8039465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (expr == NULL) return; 8040465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (glob) xmlBufferWriteChar(buf, "("); 8041465a000b1080427bd62d89a925409b7db78616acDaniel Veillard switch (expr->type) { 8042465a000b1080427bd62d89a925409b7db78616acDaniel Veillard case XML_EXP_EMPTY: 8043465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteChar(buf, "empty"); 8044465a000b1080427bd62d89a925409b7db78616acDaniel Veillard break; 8045465a000b1080427bd62d89a925409b7db78616acDaniel Veillard case XML_EXP_FORBID: 8046465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteChar(buf, "forbidden"); 8047465a000b1080427bd62d89a925409b7db78616acDaniel Veillard break; 8048465a000b1080427bd62d89a925409b7db78616acDaniel Veillard case XML_EXP_ATOM: 8049465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteCHAR(buf, expr->exp_str); 8050465a000b1080427bd62d89a925409b7db78616acDaniel Veillard break; 8051465a000b1080427bd62d89a925409b7db78616acDaniel Veillard case XML_EXP_SEQ: 8052465a000b1080427bd62d89a925409b7db78616acDaniel Veillard c = expr->exp_left; 8053465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 8054465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 1); 8055465a000b1080427bd62d89a925409b7db78616acDaniel Veillard else 8056465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 0); 8057465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteChar(buf, " , "); 8058465a000b1080427bd62d89a925409b7db78616acDaniel Veillard c = expr->exp_right; 8059465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 8060465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 1); 8061465a000b1080427bd62d89a925409b7db78616acDaniel Veillard else 8062465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 0); 8063465a000b1080427bd62d89a925409b7db78616acDaniel Veillard break; 8064465a000b1080427bd62d89a925409b7db78616acDaniel Veillard case XML_EXP_OR: 8065465a000b1080427bd62d89a925409b7db78616acDaniel Veillard c = expr->exp_left; 8066465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 8067465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 1); 8068465a000b1080427bd62d89a925409b7db78616acDaniel Veillard else 8069465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 0); 8070465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteChar(buf, " | "); 8071465a000b1080427bd62d89a925409b7db78616acDaniel Veillard c = expr->exp_right; 8072465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 8073465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 1); 8074465a000b1080427bd62d89a925409b7db78616acDaniel Veillard else 8075465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 0); 8076465a000b1080427bd62d89a925409b7db78616acDaniel Veillard break; 8077465a000b1080427bd62d89a925409b7db78616acDaniel Veillard case XML_EXP_COUNT: { 8078465a000b1080427bd62d89a925409b7db78616acDaniel Veillard char rep[40]; 8079f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 8080465a000b1080427bd62d89a925409b7db78616acDaniel Veillard c = expr->exp_left; 8081465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 8082465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 1); 8083465a000b1080427bd62d89a925409b7db78616acDaniel Veillard else 8084465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlExpDumpInt(buf, c, 0); 8085465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if ((expr->exp_min == 0) && (expr->exp_max == 1)) { 8086465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[0] = '?'; 8087465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[1] = 0; 8088465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if ((expr->exp_min == 0) && (expr->exp_max == -1)) { 8089465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[0] = '*'; 8090465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[1] = 0; 8091465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if ((expr->exp_min == 1) && (expr->exp_max == -1)) { 8092465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[0] = '+'; 8093465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[1] = 0; 8094465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if (expr->exp_max == expr->exp_min) { 8095465a000b1080427bd62d89a925409b7db78616acDaniel Veillard snprintf(rep, 39, "{%d}", expr->exp_min); 8096465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else if (expr->exp_max < 0) { 8097465a000b1080427bd62d89a925409b7db78616acDaniel Veillard snprintf(rep, 39, "{%d,inf}", expr->exp_min); 8098465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } else { 8099465a000b1080427bd62d89a925409b7db78616acDaniel Veillard snprintf(rep, 39, "{%d,%d}", expr->exp_min, expr->exp_max); 8100465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 8101465a000b1080427bd62d89a925409b7db78616acDaniel Veillard rep[39] = 0; 8102465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteChar(buf, rep); 8103465a000b1080427bd62d89a925409b7db78616acDaniel Veillard break; 8104465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 8105465a000b1080427bd62d89a925409b7db78616acDaniel Veillard default: 8106465a000b1080427bd62d89a925409b7db78616acDaniel Veillard fprintf(stderr, "Error in tree\n"); 8107465a000b1080427bd62d89a925409b7db78616acDaniel Veillard } 8108465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (glob) 8109465a000b1080427bd62d89a925409b7db78616acDaniel Veillard xmlBufferWriteChar(buf, ")"); 8110465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 8111465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/** 8112465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * xmlExpDump: 8113465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @buf: a buffer to receive the output 8114465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @expr: the compiled expression 8115465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8116465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Serialize the expression as compiled to the buffer 8117465a000b1080427bd62d89a925409b7db78616acDaniel Veillard */ 8118465a000b1080427bd62d89a925409b7db78616acDaniel Veillardvoid 81195eee767ca9b30a8e8c54808c82060ceb41630d6aDaniel VeillardxmlExpDump(xmlBufferPtr buf, xmlExpNodePtr expr) { 81205eee767ca9b30a8e8c54808c82060ceb41630d6aDaniel Veillard if ((buf == NULL) || (expr == NULL)) 8121465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return; 81225eee767ca9b30a8e8c54808c82060ceb41630d6aDaniel Veillard xmlExpDumpInt(buf, expr, 0); 8123465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 8124465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8125465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/** 8126465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * xmlExpMaxToken: 8127465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @expr: a compiled expression 8128465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8129465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Indicate the maximum number of input a expression can accept 8130465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8131465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Returns the maximum length or -1 in case of error 8132465a000b1080427bd62d89a925409b7db78616acDaniel Veillard */ 8133465a000b1080427bd62d89a925409b7db78616acDaniel Veillardint 8134465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpMaxToken(xmlExpNodePtr expr) { 8135465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (expr == NULL) 8136465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(-1); 8137465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(expr->c_max); 8138465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 8139465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8140465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/** 8141465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * xmlExpCtxtNbNodes: 8142465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @ctxt: an expression context 8143465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8144465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Debugging facility provides the number of allocated nodes at a that point 8145465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8146465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Returns the number of nodes in use or -1 in case of error 8147465a000b1080427bd62d89a925409b7db78616acDaniel Veillard */ 8148465a000b1080427bd62d89a925409b7db78616acDaniel Veillardint 8149465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpCtxtNbNodes(xmlExpCtxtPtr ctxt) { 8150465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (ctxt == NULL) 8151465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(-1); 8152465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(ctxt->nb_nodes); 8153465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 8154465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 8155465a000b1080427bd62d89a925409b7db78616acDaniel Veillard/** 8156465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * xmlExpCtxtNbCons: 8157465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * @ctxt: an expression context 8158465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8159465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Debugging facility provides the number of allocated nodes over lifetime 8160465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * 8161465a000b1080427bd62d89a925409b7db78616acDaniel Veillard * Returns the number of nodes ever allocated or -1 in case of error 8162465a000b1080427bd62d89a925409b7db78616acDaniel Veillard */ 8163465a000b1080427bd62d89a925409b7db78616acDaniel Veillardint 8164465a000b1080427bd62d89a925409b7db78616acDaniel VeillardxmlExpCtxtNbCons(xmlExpCtxtPtr ctxt) { 8165465a000b1080427bd62d89a925409b7db78616acDaniel Veillard if (ctxt == NULL) 8166465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(-1); 8167465a000b1080427bd62d89a925409b7db78616acDaniel Veillard return(ctxt->nb_cons); 8168465a000b1080427bd62d89a925409b7db78616acDaniel Veillard} 8169465a000b1080427bd62d89a925409b7db78616acDaniel Veillard 817081a8ec6b1315a9c14ce648de9c3a949ea62e48cfDaniel Veillard#endif /* LIBXML_EXPR_ENABLED */ 81715d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_xmlregexp 81725d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h" 81734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif /* LIBXML_REGEXP_ENABLED */ 8174