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