15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * regexp.c: generic and extensible Regular Expression engine 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Basically designed with the purpose of compiling regexps for 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the variety of validation/shemas mechanisms now available in 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * XML related specifications these include: 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - XML-1.0 DTD validation 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - XML Schemas structure part 1 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - XML Schemas Datatypes part 2 especially Appendix F 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - RELAX-NG/TREX i.e. the counter proposal 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See Copyright for the status of this software. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Daniel Veillard <veillard@redhat.com> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IN_LIBXML 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxml.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_REGEXP_ENABLED 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_ERR */ 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_LIMITS_H 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits.h> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/tree.h> 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/parserInternals.h> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlregexp.h> 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlautomata.h> 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlunicode.h> 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef INT_MAX 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INT_MAX 123456789 /* easy to flag and big enough for our needs */ 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_REGEXP_GRAPH */ 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_REGEXP_EXEC */ 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_PUSH */ 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_COMPACTION */ 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX_PUSH 10000000 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ERROR(str) \ 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XML_REGEXP_COMPILE_ERROR; \ 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrCompile(ctxt, str); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEXT ctxt->cur++ 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CUR (*(ctxt->cur)) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NXT(index) (ctxt->cur[index]) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEXTL(l) ctxt->cur += l; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_REG_STRING_SEPARATOR '|' 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Need PREV to check on a '-' within a Character Group. May only be used 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * when it's guaranteed that cur is not at the beginning of ctxt->string! 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PREV (ctxt->cur[-1]) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * macro to flag unimplemented blocks 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TODO \ 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, \ 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Unimplemented block at %s:%d\n", \ 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __FILE__, __LINE__); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Datatypes and structures * 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note: the order of the enums below is significant, do not shuffle 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_EPSILON = 1, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_CHARVAL, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_RANGES, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SUBREG, /* used for () sub regexps */ 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_STRING, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_ANYCHAR, /* . */ 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_ANYSPACE, /* \s */ 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_NOTSPACE, /* \S */ 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_INITNAME, /* \l */ 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_NOTINITNAME, /* \L */ 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_NAMECHAR, /* \c */ 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_NOTNAMECHAR, /* \C */ 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_DECIMAL, /* \d */ 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_NOTDECIMAL, /* \D */ 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_REALCHAR, /* \w */ 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_NOTREALCHAR, /* \W */ 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_LETTER = 100, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_LETTER_UPPERCASE, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_LETTER_LOWERCASE, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_LETTER_TITLECASE, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_LETTER_MODIFIER, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_LETTER_OTHERS, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_MARK, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_MARK_NONSPACING, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_MARK_SPACECOMBINING, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_MARK_ENCLOSING, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_NUMBER, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_NUMBER_DECIMAL, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_NUMBER_LETTER, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_NUMBER_OTHERS, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_PUNCT, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_PUNCT_CONNECTOR, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_PUNCT_DASH, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_PUNCT_OPEN, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_PUNCT_CLOSE, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_PUNCT_INITQUOTE, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_PUNCT_FINQUOTE, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_PUNCT_OTHERS, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SEPAR, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SEPAR_SPACE, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SEPAR_LINE, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SEPAR_PARA, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SYMBOL, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SYMBOL_MATH, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SYMBOL_CURRENCY, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SYMBOL_MODIFIER, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SYMBOL_OTHERS, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_OTHER, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_OTHER_CONTROL, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_OTHER_FORMAT, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_OTHER_PRIVATE, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_OTHER_NA, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_BLOCK_NAME 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xmlRegAtomType; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_QUANT_EPSILON = 1, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_QUANT_ONCE, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_QUANT_OPT, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_QUANT_MULT, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_QUANT_PLUS, 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_QUANT_ONCEONLY, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_QUANT_ALL, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_QUANT_RANGE 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xmlRegQuantType; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_START_STATE = 1, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_FINAL_STATE, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_TRANS_STATE, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SINK_STATE, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_UNREACH_STATE 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xmlRegStateType; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_MARK_NORMAL = 0, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_MARK_START, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_MARK_VISITED 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xmlRegMarkedType; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlRegRange xmlRegRange; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegRange *xmlRegRangePtr; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegRange { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int neg; /* 0 normal, 1 not, 2 exclude */ 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomType type; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int end; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *blockName; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlRegAtom xmlRegAtom; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegAtom *xmlRegAtomPtr; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlAutomataState xmlRegState; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegState *xmlRegStatePtr; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegAtom { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int no; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomType type; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegQuantType quant; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *valuep; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *valuep2; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int neg; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int codepoint; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr start; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr start0; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr stop; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxRanges; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbRanges; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegRangePtr *ranges; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *data; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlRegCounter xmlRegCounter; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegCounter *xmlRegCounterPtr; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegCounter { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlRegTrans xmlRegTrans; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegTrans *xmlRegTransPtr; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegTrans { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int to; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int counter; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nd; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlAutomataState { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateType type; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegMarkedType mark; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegMarkedType reached; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int no; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxTrans; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbTrans; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegTrans *trans; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* knowing states ponting to us can speed things up */ 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxTransTo; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbTransTo; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *transTo; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlAutomata xmlRegParserCtxt; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegParserCtxt *xmlRegParserCtxtPtr; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AM_AUTOMATA_RNG 1 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlAutomata { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *string; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *cur; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int neg; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr start; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr end; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr state; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxAtoms; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbAtoms; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr *atoms; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxStates; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbStates; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr *states; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxCounters; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbCounters; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegCounter *counters; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int determinist; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int negs; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegexp { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *string; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbStates; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr *states; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbAtoms; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr *atoms; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbCounters; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegCounter *counters; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int determinist; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * That's the compact form for determinists automatas 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbstates; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *compact; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void **transdata; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbstrings; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar **stringMap; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlRegExecRollback xmlRegExecRollback; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegExecRollback *xmlRegExecRollbackPtr; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegExecRollback { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr state;/* the current state */ 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index; /* the index in the input stack */ 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nextbranch; /* the next transition to explore in that state */ 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *counts; /* save the automata state if it has some */ 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlRegInputToken xmlRegInputToken; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlRegInputToken *xmlRegInputTokenPtr; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegInputToken { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *value; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *data; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlRegExecCtxt { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int status; /* execution status != 0 indicate an error */ 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int determinist; /* did we find an indeterministic behaviour */ 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpPtr comp; /* the compiled regexp */ 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegExecCallbacks callback; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *data; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr state;/* the current state */ 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int transno; /* the current transition on that state */ 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int transcount; /* the number of chars in char counted transitions */ 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A stack of rollback states 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxRollbacks; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbRollbacks; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegExecRollback *rollbacks; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The state of the automata if any 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *counts; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The input stack 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int inputStackMax; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int inputStackNr; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *charStack; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *inputString; /* when operating on characters */ 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegInputTokenPtr inputStack;/* when operating on strings */ 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * error handling 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int errStateNo; /* the error state number */ 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr errState; /* the error state */ 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *errString; /* the string raising the error */ 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *errCounts; /* counters at the error state */ 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbPush; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define REGEXP_ALL_COUNTER 0x123456 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define REGEXP_ALL_LAX_COUNTER 0x123457 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void xmlRegFreeState(xmlRegStatePtr state); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void xmlRegFreeAtom(xmlRegAtomPtr atom); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int xmlRegStrEqualWildcard(const xmlChar *expStr, const xmlChar *valStr); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int xmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int neg, int start, int end, const xmlChar *blockName); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void xmlAutomataSetFlags(xmlAutomataPtr am, int flags); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Regexp memory error handler * 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegexpErrMemory: 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @extra: extra information 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handle an out of memory condition 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpErrMemory(xmlRegParserCtxtPtr ctxt, const char *extra) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *regexp = NULL; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt != NULL) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regexp = (const char *) ctxt->string; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XML_ERR_NO_MEMORY; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_REGEXP, 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra, 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regexp, NULL, 0, 0, 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Memory allocation failed : %s\n", extra); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegexpErrCompile: 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @extra: extra information 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handle a compilation failure 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpErrCompile(xmlRegParserCtxtPtr ctxt, const char *extra) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *regexp = NULL; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idx = 0; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt != NULL) { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regexp = (const char *) ctxt->string; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idx = ctxt->cur - ctxt->string; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XML_REGEXP_COMPILE_ERROR; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_REGEXP, 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_COMPILE_ERROR, XML_ERR_FATAL, NULL, 0, extra, 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regexp, NULL, idx, 0, 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "failed to compile: %s\n", extra); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocation/Deallocation * 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegEpxFromParse: 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the parser context used to build it 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate a new regexp and fill it with the result from the parser 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new regexp or NULL in case of error 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegexpPtr 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpPtr ret; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlRegexpPtr) xmlMalloc(sizeof(xmlRegexp)); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "compiling regexp"); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlRegexp)); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->string = ctxt->string; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nbStates = ctxt->nbStates; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->states = ctxt->states; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nbAtoms = ctxt->nbAtoms; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->atoms = ctxt->atoms; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nbCounters = ctxt->nbCounters; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->counters = ctxt->counters; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->determinist = ctxt->determinist; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->flags = ctxt->flags; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->determinist == -1) { 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpIsDeterminist(ret); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret->determinist != 0) && 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ret->nbCounters == 0) && 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ctxt->negs == 0) && 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ret->atoms != NULL) && 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ret->atoms[0] != NULL) && 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ret->atoms[0]->type == XML_REGEXP_STRING)) { 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j, nbstates = 0, nbatoms = 0; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *stateRemap; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *stringRemap; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *transitions; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void **transdata; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar **stringMap; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *value; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Switch to a compact representation 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1/ counting the effective number of states left 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2/ counting the unique number of atoms, and check that 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * they are all of the string type 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3/ build a table state x atom for the transitions 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stateRemap = xmlMalloc(ret->nbStates * sizeof(int)); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stateRemap == NULL) { 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "compiling regexp"); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ret); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < ret->nbStates;i++) { 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->states[i] != NULL) { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stateRemap[i] = nbstates; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbstates++; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stateRemap[i] = -1; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_COMPACTION 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Final: %d states\n", nbstates); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringMap = xmlMalloc(ret->nbAtoms * sizeof(char *)); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stringMap == NULL) { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "compiling regexp"); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stateRemap); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ret); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringRemap = xmlMalloc(ret->nbAtoms * sizeof(int)); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stringRemap == NULL) { 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "compiling regexp"); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stringMap); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stateRemap); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ret); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < ret->nbAtoms;i++) { 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret->atoms[i]->type == XML_REGEXP_STRING) && 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ret->atoms[i]->quant == XML_REGEXP_QUANT_ONCE)) { 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = ret->atoms[i]->valuep; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0;j < nbatoms;j++) { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(stringMap[j], value)) { 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringRemap[i] = j; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (j >= nbatoms) { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringRemap[i] = nbatoms; 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringMap[nbatoms] = xmlStrdup(value); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stringMap[nbatoms] == NULL) { 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < nbatoms;i++) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stringMap[i]); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stringRemap); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stringMap); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stateRemap); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ret); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbatoms++; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stateRemap); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stringRemap); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < nbatoms;i++) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stringMap[i]); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stringMap); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ret); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_COMPACTION 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Final: %d atoms\n", nbatoms); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transitions = (int *) xmlMalloc((nbstates + 1) * 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (nbatoms + 1) * sizeof(int)); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transitions == NULL) { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stateRemap); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stringRemap); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stringMap); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ret); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(transitions, 0, (nbstates + 1) * (nbatoms + 1) * sizeof(int)); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate the transition table. The first entry for each 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * state corresponds to the state type. 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transdata = NULL; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < ret->nbStates;i++) { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int stateno, atomno, targetno, prev; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr state; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegTransPtr trans; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stateno = stateRemap[i]; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stateno == -1) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = ret->states[i]; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transitions[stateno * (nbatoms + 1)] = state->type; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0;j < state->nbTrans;j++) { 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans = &(state->trans[j]); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((trans->to == -1) || (trans->atom == NULL)) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atomno = stringRemap[trans->atom->no]; 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((trans->atom->data != NULL) && (transdata == NULL)) { 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transdata = (void **) xmlMalloc(nbstates * nbatoms * 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(void *)); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transdata != NULL) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(transdata, 0, 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbstates * nbatoms * sizeof(void *)); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "compiling regexp"); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) targetno = stateRemap[trans->to]; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if the same atom can generate transitions to 2 different 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * states then it means the automata is not determinist and 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the compact form can't be used ! 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev = transitions[stateno * (nbatoms + 1) + atomno + 1]; 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prev != 0) { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prev != targetno + 1) { 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->determinist = 0; 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_COMPACTION 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Indet: state %d trans %d, atom %d to %d : %d to %d\n", 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i, j, trans->atom->no, trans->to, atomno, targetno); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(" previous to is %d\n", prev); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transdata != NULL) 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(transdata); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(transitions); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stateRemap); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stringRemap); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < nbatoms;i++) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stringMap[i]); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stringMap); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto not_determ; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("State %d trans %d: atom %d to %d : %d to %d\n", 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i, j, trans->atom->no, trans->to, atomno, targetno); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transitions[stateno * (nbatoms + 1) + atomno + 1] = 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) targetno + 1; /* to avoid 0 */ 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transdata != NULL) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transdata[stateno * nbatoms + atomno] = 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans->atom->data; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->determinist = 1; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_COMPACTION 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Debug 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < nbstates;i++) { 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0;j < nbatoms + 1;j++) { 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("%02d ", transitions[i * (nbatoms + 1) + j]); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("\n"); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("\n"); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Cleanup of the old data 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->states != NULL) { 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < ret->nbStates;i++) 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeState(ret->states[i]); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ret->states); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->states = NULL; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nbStates = 0; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->atoms != NULL) { 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < ret->nbAtoms;i++) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeAtom(ret->atoms[i]); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ret->atoms); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->atoms = NULL; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nbAtoms = 0; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->compact = transitions; 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->transdata = transdata; 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->stringMap = stringMap; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nbstrings = nbatoms; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nbstates = nbstates; 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stateRemap); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(stringRemap); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)not_determ: 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->string = NULL; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nbStates = 0; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->states = NULL; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nbAtoms = 0; 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atoms = NULL; 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nbCounters = 0; 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->counters = NULL; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegNewParserCtxt: 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @string: the string to parse 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate a new regexp parser context 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new context or NULL in case of error 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegParserCtxtPtr 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegNewParserCtxt(const xmlChar *string) { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegParserCtxtPtr ret; 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlRegParserCtxtPtr) xmlMalloc(sizeof(xmlRegParserCtxt)); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlRegParserCtxt)); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (string != NULL) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->string = xmlStrdup(string); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->cur = ret->string; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->neg = 0; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->negs = 0; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->error = 0; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->determinist = -1; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegNewRange: 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the regexp parser context 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @neg: is that negative 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type: the type of range 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @start: the start codepoint 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @end: the end codepoint 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate a new regexp range 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new range or NULL in case of error 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegRangePtr 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegNewRange(xmlRegParserCtxtPtr ctxt, 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int neg, xmlRegAtomType type, int start, int end) { 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegRangePtr ret; 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlRegRangePtr) xmlMalloc(sizeof(xmlRegRange)); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "allocating range"); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->neg = neg; 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->type = type; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->start = start; 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->end = end; 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegFreeRange: 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @range: the regexp range 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free a regexp range 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegFreeRange(xmlRegRangePtr range) { 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range == NULL) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range->blockName != NULL) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(range->blockName); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(range); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegCopyRange: 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @range: the regexp range 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copy a regexp range 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new copy or NULL in case of error. 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegRangePtr 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegCopyRange(xmlRegParserCtxtPtr ctxt, xmlRegRangePtr range) { 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegRangePtr ret; 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range == NULL) 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegNewRange(ctxt, range->neg, range->type, range->start, 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range->end); 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range->blockName != NULL) { 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->blockName = xmlStrdup(range->blockName); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->blockName == NULL) { 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "allocating range"); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeRange(ret); 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegNewAtom: 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the regexp parser context 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type: the type of atom 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate a new atom 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new atom or NULL in case of error 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegAtomPtr 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegNewAtom(xmlRegParserCtxtPtr ctxt, xmlRegAtomType type) { 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr ret; 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlRegAtomPtr) xmlMalloc(sizeof(xmlRegAtom)); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "allocating atom"); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlRegAtom)); 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->type = type; 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->quant = XML_REGEXP_QUANT_ONCE; 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->min = 0; 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->max = 0; 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegFreeAtom: 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom: the regexp atom 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free a regexp atom 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegFreeAtom(xmlRegAtomPtr atom) { 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom == NULL) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < atom->nbRanges;i++) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeRange(atom->ranges[i]); 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->ranges != NULL) 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(atom->ranges); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((atom->type == XML_REGEXP_STRING) && (atom->valuep != NULL)) 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(atom->valuep); 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((atom->type == XML_REGEXP_STRING) && (atom->valuep2 != NULL)) 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(atom->valuep2); 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((atom->type == XML_REGEXP_BLOCK_NAME) && (atom->valuep != NULL)) 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(atom->valuep); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(atom); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegCopyAtom: 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the regexp parser context 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom: the oiginal atom 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate a new regexp range 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new atom or NULL in case of error 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegAtomPtr 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegCopyAtom(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) { 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr ret; 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlRegAtomPtr) xmlMalloc(sizeof(xmlRegAtom)); 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "copying atom"); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlRegAtom)); 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->type = atom->type; 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->quant = atom->quant; 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->min = atom->min; 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->max = atom->max; 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->nbRanges > 0) { 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->ranges = (xmlRegRangePtr *) xmlMalloc(sizeof(xmlRegRangePtr) * 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->nbRanges); 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->ranges == NULL) { 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "copying atom"); 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < atom->nbRanges;i++) { 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->ranges[i] = xmlRegCopyRange(ctxt, atom->ranges[i]); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->ranges[i] == NULL) 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nbRanges = i + 1; 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error: 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeAtom(ret); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRegStatePtr 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegNewState(xmlRegParserCtxtPtr ctxt) { 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr ret; 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlRegStatePtr) xmlMalloc(sizeof(xmlRegState)); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "allocating state"); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlRegState)); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->type = XML_REGEXP_TRANS_STATE; 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->mark = XML_REGEXP_MARK_NORMAL; 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegFreeState: 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @state: the regexp state 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free a regexp state 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegFreeState(xmlRegStatePtr state) { 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == NULL) 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->trans != NULL) 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(state->trans); 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->transTo != NULL) 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(state->transTo); 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(state); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegFreeParserCtxt: 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the regexp parser context 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free a regexp parser context 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegFreeParserCtxt(xmlRegParserCtxtPtr ctxt) { 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->string != NULL) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->string); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->states != NULL) { 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < ctxt->nbStates;i++) 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeState(ctxt->states[i]); 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->states); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atoms != NULL) { 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < ctxt->nbAtoms;i++) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeAtom(ctxt->atoms[i]); 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->atoms); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->counters != NULL) 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->counters); 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Display of Data structures * 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintAtomType(FILE *output, xmlRegAtomType type) { 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_EPSILON: 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "epsilon "); break; 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_CHARVAL: 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "charval "); break; 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_RANGES: 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "ranges "); break; 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SUBREG: 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "subexpr "); break; 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_STRING: 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "string "); break; 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_ANYCHAR: 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "anychar "); break; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_ANYSPACE: 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "anyspace "); break; 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTSPACE: 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "notspace "); break; 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_INITNAME: 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "initname "); break; 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTINITNAME: 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "notinitname "); break; 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NAMECHAR: 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "namechar "); break; 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTNAMECHAR: 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "notnamechar "); break; 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_DECIMAL: 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "decimal "); break; 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTDECIMAL: 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "notdecimal "); break; 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_REALCHAR: 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "realchar "); break; 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTREALCHAR: 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "notrealchar "); break; 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER: 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "LETTER "); break; 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_UPPERCASE: 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "LETTER_UPPERCASE "); break; 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_LOWERCASE: 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "LETTER_LOWERCASE "); break; 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_TITLECASE: 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "LETTER_TITLECASE "); break; 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_MODIFIER: 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "LETTER_MODIFIER "); break; 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_OTHERS: 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "LETTER_OTHERS "); break; 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK: 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "MARK "); break; 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK_NONSPACING: 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "MARK_NONSPACING "); break; 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK_SPACECOMBINING: 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "MARK_SPACECOMBINING "); break; 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK_ENCLOSING: 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "MARK_ENCLOSING "); break; 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER: 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "NUMBER "); break; 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER_DECIMAL: 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "NUMBER_DECIMAL "); break; 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER_LETTER: 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "NUMBER_LETTER "); break; 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER_OTHERS: 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "NUMBER_OTHERS "); break; 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT: 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "PUNCT "); break; 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_CONNECTOR: 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "PUNCT_CONNECTOR "); break; 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_DASH: 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "PUNCT_DASH "); break; 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_OPEN: 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "PUNCT_OPEN "); break; 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_CLOSE: 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "PUNCT_CLOSE "); break; 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_INITQUOTE: 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "PUNCT_INITQUOTE "); break; 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_FINQUOTE: 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "PUNCT_FINQUOTE "); break; 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_OTHERS: 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "PUNCT_OTHERS "); break; 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR: 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "SEPAR "); break; 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR_SPACE: 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "SEPAR_SPACE "); break; 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR_LINE: 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "SEPAR_LINE "); break; 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR_PARA: 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "SEPAR_PARA "); break; 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL: 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "SYMBOL "); break; 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_MATH: 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "SYMBOL_MATH "); break; 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_CURRENCY: 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "SYMBOL_CURRENCY "); break; 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_MODIFIER: 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "SYMBOL_MODIFIER "); break; 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_OTHERS: 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "SYMBOL_OTHERS "); break; 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER: 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "OTHER "); break; 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_CONTROL: 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "OTHER_CONTROL "); break; 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_FORMAT: 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "OTHER_FORMAT "); break; 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_PRIVATE: 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "OTHER_PRIVATE "); break; 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_NA: 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "OTHER_NA "); break; 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_BLOCK_NAME: 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "BLOCK "); break; 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintQuantType(FILE *output, xmlRegQuantType type) { 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_EPSILON: 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "epsilon "); break; 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_ONCE: 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "once "); break; 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_OPT: 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "? "); break; 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_MULT: 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "* "); break; 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_PLUS: 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "+ "); break; 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_RANGE: 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "range "); break; 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_ONCEONLY: 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "onceonly "); break; 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_ALL: 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "all "); break; 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintRange(FILE *output, xmlRegRangePtr range) { 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, " range: "); 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range->neg) 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "negative "); 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegPrintAtomType(output, range->type); 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "%c - %c\n", range->start, range->end); 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintAtom(FILE *output, xmlRegAtomPtr atom) { 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, " atom: "); 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom == NULL) { 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "NULL\n"); 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->neg) 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "not "); 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegPrintAtomType(output, atom->type); 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegPrintQuantType(output, atom->quant); 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->quant == XML_REGEXP_QUANT_RANGE) 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "%d-%d ", atom->min, atom->max); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->type == XML_REGEXP_STRING) 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "'%s' ", (char *) atom->valuep); 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->type == XML_REGEXP_CHARVAL) 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "char %c\n", atom->codepoint); 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (atom->type == XML_REGEXP_RANGES) { 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "%d entries\n", atom->nbRanges); 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < atom->nbRanges;i++) 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegPrintRange(output, atom->ranges[i]); 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (atom->type == XML_REGEXP_SUBREG) { 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "start %d end %d\n", atom->start->no, atom->stop->no); 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "\n"); 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintTrans(FILE *output, xmlRegTransPtr trans) { 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, " trans: "); 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans == NULL) { 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "NULL\n"); 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->to < 0) { 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "removed\n"); 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->nd != 0) { 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->nd == 2) 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "last not determinist, "); 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "not determinist, "); 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->counter >= 0) { 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "counted %d, ", trans->counter); 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->count == REGEXP_ALL_COUNTER) { 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "all transition, "); 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (trans->count >= 0) { 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "count based %d, ", trans->count); 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->atom == NULL) { 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "epsilon to %d\n", trans->to); 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->atom->type == XML_REGEXP_CHARVAL) 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "char %c ", trans->atom->codepoint); 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "atom %d, to %d\n", trans->atom->no, trans->to); 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintState(FILE *output, xmlRegStatePtr state) { 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, " state: "); 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == NULL) { 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "NULL\n"); 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->type == XML_REGEXP_START_STATE) 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "START "); 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->type == XML_REGEXP_FINAL_STATE) 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "FINAL "); 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "%d, %d transitions:\n", state->no, state->nbTrans); 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < state->nbTrans; i++) { 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegPrintTrans(output, &(state->trans[i])); 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegPrintCtxt(FILE *output, xmlRegParserCtxtPtr ctxt) { 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, " ctxt: "); 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) { 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "NULL\n"); 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "'%s' ", ctxt->string); 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->error) 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "error "); 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->neg) 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "neg "); 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "\n"); 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "%d atoms:\n", ctxt->nbAtoms); 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < ctxt->nbAtoms; i++) { 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, " %02d ", i); 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegPrintAtom(output, ctxt->atoms[i]); 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atom != NULL) { 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "current atom:\n"); 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegPrintAtom(output, ctxt->atom); 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "%d states:", ctxt->nbStates); 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->start != NULL) 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, " start: %d", ctxt->start->no); 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->end != NULL) 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, " end: %d", ctxt->end->no); 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "\n"); 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < ctxt->nbStates; i++) { 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegPrintState(output, ctxt->states[i]); 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "%d counters:\n", ctxt->nbCounters); 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < ctxt->nbCounters; i++) { 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, " %d: min %d max %d\n", i, ctxt->counters[i].min, 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->counters[i].max); 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Finite Automata structures manipulations * 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom, 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int neg, xmlRegAtomType type, int start, int end, 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *blockName) { 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegRangePtr range; 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom == NULL) { 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("add range: atom is NULL"); 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->type != XML_REGEXP_RANGES) { 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("add range: atom is not ranges"); 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->maxRanges == 0) { 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->maxRanges = 4; 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->ranges = (xmlRegRangePtr *) xmlMalloc(atom->maxRanges * 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(xmlRegRangePtr)); 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->ranges == NULL) { 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "adding ranges"); 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->maxRanges = 0; 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (atom->nbRanges >= atom->maxRanges) { 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegRangePtr *tmp; 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->maxRanges *= 2; 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = (xmlRegRangePtr *) xmlRealloc(atom->ranges, atom->maxRanges * 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(xmlRegRangePtr)); 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "adding ranges"); 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->maxRanges /= 2; 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->ranges = tmp; 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range = xmlRegNewRange(ctxt, neg, type, start, end); 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range == NULL) 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range->blockName = blockName; 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->ranges[atom->nbRanges++] = range; 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegGetCounter(xmlRegParserCtxtPtr ctxt) { 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->maxCounters == 0) { 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxCounters = 4; 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->counters = (xmlRegCounter *) xmlMalloc(ctxt->maxCounters * 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(xmlRegCounter)); 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->counters == NULL) { 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "allocating counter"); 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxCounters = 0; 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ctxt->nbCounters >= ctxt->maxCounters) { 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegCounter *tmp; 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxCounters *= 2; 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = (xmlRegCounter *) xmlRealloc(ctxt->counters, ctxt->maxCounters * 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(xmlRegCounter)); 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "allocating counter"); 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxCounters /= 2; 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->counters = tmp; 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->counters[ctxt->nbCounters].min = -1; 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->counters[ctxt->nbCounters].max = -1; 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ctxt->nbCounters++); 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegAtomPush(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) { 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom == NULL) { 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("atom push: atom is NULL"); 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->maxAtoms == 0) { 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxAtoms = 4; 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atoms = (xmlRegAtomPtr *) xmlMalloc(ctxt->maxAtoms * 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(xmlRegAtomPtr)); 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atoms == NULL) { 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "pushing atom"); 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxAtoms = 0; 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ctxt->nbAtoms >= ctxt->maxAtoms) { 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr *tmp; 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxAtoms *= 2; 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = (xmlRegAtomPtr *) xmlRealloc(ctxt->atoms, ctxt->maxAtoms * 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(xmlRegAtomPtr)); 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "allocating counter"); 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxAtoms /= 2; 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atoms = tmp; 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->no = ctxt->nbAtoms; 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atoms[ctxt->nbAtoms++] = atom; 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegStateAddTransTo(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr target, 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int from) { 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target->maxTransTo == 0) { 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target->maxTransTo = 8; 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target->transTo = (int *) xmlMalloc(target->maxTransTo * 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(int)); 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target->transTo == NULL) { 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "adding transition"); 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target->maxTransTo = 0; 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (target->nbTransTo >= target->maxTransTo) { 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *tmp; 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target->maxTransTo *= 2; 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = (int *) xmlRealloc(target->transTo, target->maxTransTo * 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(int)); 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "adding transition"); 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target->maxTransTo /= 2; 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target->transTo = tmp; 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target->transTo[target->nbTransTo] = from; 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target->nbTransTo++; 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state, 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom, xmlRegStatePtr target, 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int counter, int count) { 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nrtrans; 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == NULL) { 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("add state: state is NULL"); 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target == NULL) { 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("add state: target is NULL"); 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Other routines follow the philosophy 'When in doubt, add a transition' 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * so we check here whether such a transition is already present and, if 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * so, silently ignore this request. 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (nrtrans = state->nbTrans - 1; nrtrans >= 0; nrtrans--) { 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegTransPtr trans = &(state->trans[nrtrans]); 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((trans->atom == atom) && 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (trans->to == target->no) && 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (trans->counter == counter) && 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (trans->count == count)) { 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Ignoring duplicate transition from %d to %d\n", 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->no, target->no); 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->maxTrans == 0) { 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->maxTrans = 8; 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->trans = (xmlRegTrans *) xmlMalloc(state->maxTrans * 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(xmlRegTrans)); 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->trans == NULL) { 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "adding transition"); 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->maxTrans = 0; 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (state->nbTrans >= state->maxTrans) { 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegTrans *tmp; 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->maxTrans *= 2; 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = (xmlRegTrans *) xmlRealloc(state->trans, state->maxTrans * 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(xmlRegTrans)); 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "adding transition"); 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->maxTrans /= 2; 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->trans = tmp; 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Add trans from %d to %d ", state->no, target->no); 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (count == REGEXP_ALL_COUNTER) 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("all transition\n"); 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (count >= 0) 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("count based %d\n", count); 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (counter >= 0) 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("counted %d\n", counter); 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (atom == NULL) 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("epsilon transition\n"); 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (atom != NULL) 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegPrintAtom(stdout, atom); 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->trans[state->nbTrans].atom = atom; 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->trans[state->nbTrans].to = target->no; 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->trans[state->nbTrans].counter = counter; 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->trans[state->nbTrans].count = count; 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->trans[state->nbTrans].nd = 0; 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->nbTrans++; 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTransTo(ctxt, target, state->no); 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegStatePush(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state) { 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == NULL) return(-1); 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->maxStates == 0) { 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxStates = 4; 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->states = (xmlRegStatePtr *) xmlMalloc(ctxt->maxStates * 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(xmlRegStatePtr)); 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->states == NULL) { 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "adding state"); 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxStates = 0; 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ctxt->nbStates >= ctxt->maxStates) { 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr *tmp; 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxStates *= 2; 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = (xmlRegStatePtr *) xmlRealloc(ctxt->states, ctxt->maxStates * 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(xmlRegStatePtr)); 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(ctxt, "adding state"); 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxStates /= 2; 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->states = tmp; 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->no = ctxt->nbStates; 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->states[ctxt->nbStates++] = state; 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAGenerateAllTransition: 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the from state 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target state or NULL for building a new one 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @lax: 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAGenerateAllTransition(xmlRegParserCtxtPtr ctxt, 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr from, xmlRegStatePtr to, 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lax) { 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) { 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = xmlRegNewState(ctxt); 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(ctxt, to); 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = to; 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lax) 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_LAX_COUNTER); 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_COUNTER); 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAGenerateEpsilonTransition: 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the from state 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target state or NULL for building a new one 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAGenerateEpsilonTransition(xmlRegParserCtxtPtr ctxt, 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr from, xmlRegStatePtr to) { 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) { 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = xmlRegNewState(ctxt); 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(ctxt, to); 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = to; 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(ctxt, from, NULL, to, -1, -1); 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAGenerateCountedEpsilonTransition: 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the from state 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target state or NULL for building a new one 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * counter: the counter for that transition 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAGenerateCountedEpsilonTransition(xmlRegParserCtxtPtr ctxt, 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr from, xmlRegStatePtr to, int counter) { 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) { 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = xmlRegNewState(ctxt); 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(ctxt, to); 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = to; 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(ctxt, from, NULL, to, counter, -1); 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAGenerateCountedTransition: 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the from state 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target state or NULL for building a new one 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * counter: the counter for that transition 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAGenerateCountedTransition(xmlRegParserCtxtPtr ctxt, 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr from, xmlRegStatePtr to, int counter) { 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) { 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = xmlRegNewState(ctxt); 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(ctxt, to); 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = to; 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(ctxt, from, NULL, to, -1, counter); 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAGenerateTransitions: 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the from state 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target state or NULL for building a new one 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom: the atom generating the transition 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 0 if success and -1 in case of error. 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr to, xmlRegAtomPtr atom) { 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr end; 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom == NULL) { 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("genrate transition: atom == NULL"); 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->type == XML_REGEXP_SUBREG) { 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is a subexpression handling one should not need to 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * create a new node except for XML_REGEXP_QUANT_RANGE. 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlRegAtomPush(ctxt, atom) < 0) { 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((to != NULL) && (atom->stop != to) && 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (atom->quant != XML_REGEXP_QUANT_RANGE)) { 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Generate an epsilon transition to link to the target 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to); 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DV 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((to == NULL) && (atom->quant != XML_REGEXP_QUANT_RANGE) && 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (atom->quant != XML_REGEXP_QUANT_ONCE)) { 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = xmlRegNewState(ctxt); 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(ctxt, to); 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = to; 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to); 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (atom->quant) { 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_OPT: 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->quant = XML_REGEXP_QUANT_ONCE; 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * transition done to the state after end of atom. 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1. set transition from atom start to new state 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2. set transition from atom end to this state. 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) { 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, atom->start, 0); 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, atom->stop, 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state); 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, atom->start, to); 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_MULT: 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->quant = XML_REGEXP_QUANT_ONCE; 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, atom->start, atom->stop); 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start); 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_PLUS: 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->quant = XML_REGEXP_QUANT_ONCE; 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start); 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_RANGE: { 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int counter; 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr inter, newstate; 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * create the final state now if needed 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to != NULL) { 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newstate = to; 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newstate = xmlRegNewState(ctxt); 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(ctxt, newstate); 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The principle here is to use counted transition 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to avoid explosion in the number of states in the 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * graph. This is clearly more complex but should not 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * be exploitable at runtime. 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((atom->min == 0) && (atom->start0 == NULL)) { 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr copy; 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * duplicate a transition based on atom to count next 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * occurences after 1. We cannot loop to atom->start 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * directly because we need an epsilon transition to 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * newstate. 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ???? For some reason it seems we never reach that 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case, I suppose this got optimized out before when 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) building the automata */ 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) copy = xmlRegCopyAtom(ctxt, atom); 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (copy == NULL) 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) copy->quant = XML_REGEXP_QUANT_ONCE; 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) copy->min = 0; 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) copy->max = 0; 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlFAGenerateTransitions(ctxt, atom->start, NULL, copy) 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) < 0) 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inter = ctxt->state; 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = xmlRegGetCounter(ctxt); 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->counters[counter].min = atom->min - 1; 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->counters[counter].max = atom->max - 1; 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* count the number of times we see it again */ 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateCountedEpsilonTransition(ctxt, inter, 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->stop, counter); 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* allow a way out based on the count */ 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateCountedTransition(ctxt, inter, 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newstate, counter); 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* and also allow a direct exit for 0 */ 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, atom->start, 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newstate); 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * either we need the atom at least once or there 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is an atom->start0 allowing to easilly plug the 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * epsilon transition. 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = xmlRegGetCounter(ctxt); 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->counters[counter].min = atom->min - 1; 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->counters[counter].max = atom->max - 1; 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* count the number of times we see it again */ 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateCountedEpsilonTransition(ctxt, atom->stop, 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->start, counter); 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* allow a way out based on the count */ 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateCountedTransition(ctxt, atom->stop, 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newstate, counter); 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* and if needed allow a direct exit for 0 */ 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->min == 0) 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, atom->start0, 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newstate); 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->min = 0; 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->max = 0; 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->quant = XML_REGEXP_QUANT_ONCE; 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = newstate; 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((atom->min == 0) && (atom->max == 0) && 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (atom->quant == XML_REGEXP_QUANT_RANGE)) { 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we can discard the atom and generate an epsilon transition instead 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) { 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = xmlRegNewState(ctxt); 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to != NULL) 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(ctxt, to); 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, from, to); 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = to; 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeAtom(atom); 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) { 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = xmlRegNewState(ctxt); 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to != NULL) 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(ctxt, to); 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = to; 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((atom->quant == XML_REGEXP_QUANT_MULT) || 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (atom->quant == XML_REGEXP_QUANT_PLUS)) { 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Do not pollute the target state by adding transitions from 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it as it is likely to be the shared target of multiple branches. 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * So isolate with an epsilon transition. 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr tmp; 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlRegNewState(ctxt); 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp != NULL) 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(ctxt, tmp); 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, tmp, to); 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = tmp; 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlRegAtomPush(ctxt, atom) < 0) { 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(ctxt, from, atom, to, -1, -1); 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = end; 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (atom->quant) { 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_OPT: 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->quant = XML_REGEXP_QUANT_ONCE; 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, from, to); 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_MULT: 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->quant = XML_REGEXP_QUANT_ONCE; 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, from, to); 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1); 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_PLUS: 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->quant = XML_REGEXP_QUANT_ONCE; 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1); 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_QUANT_RANGE: 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if DV_test 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->min == 0) { 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, from, to); 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAReduceEpsilonTransitions: 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @fromnr: the from state 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @tonr: the to state 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @counter: should that transition be associated to a counted 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int fromnr, 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tonr, int counter) { 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int transnr; 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr from; 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr to; 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("xmlFAReduceEpsilonTransitions(%d, %d)\n", fromnr, tonr); 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) from = ctxt->states[fromnr]; 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (from == NULL) 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = ctxt->states[tonr]; 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((to->mark == XML_REGEXP_MARK_START) || 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (to->mark == XML_REGEXP_MARK_VISITED)) 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to->mark = XML_REGEXP_MARK_VISITED; 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to->type == XML_REGEXP_FINAL_STATE) { 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("State %d is final, so %d becomes final\n", tonr, fromnr); 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) from->type = XML_REGEXP_FINAL_STATE; 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (transnr = 0;transnr < to->nbTrans;transnr++) { 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to->trans[transnr].to < 0) 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to->trans[transnr].atom == NULL) { 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Don't remove counted transitions 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Don't loop either 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to->trans[transnr].to != fromnr) { 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to->trans[transnr].count >= 0) { 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int newto = to->trans[transnr].to; 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(ctxt, from, NULL, 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->states[newto], 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -1, to->trans[transnr].count); 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Found epsilon trans %d from %d to %d\n", 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transnr, tonr, to->trans[transnr].to); 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to->trans[transnr].counter >= 0) { 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAReduceEpsilonTransitions(ctxt, fromnr, 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to->trans[transnr].to, 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to->trans[transnr].counter); 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAReduceEpsilonTransitions(ctxt, fromnr, 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to->trans[transnr].to, 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter); 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int newto = to->trans[transnr].to; 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to->trans[transnr].counter >= 0) { 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom, 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->states[newto], 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to->trans[transnr].counter, -1); 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom, 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->states[newto], counter, -1); 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to->mark = XML_REGEXP_MARK_NORMAL; 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAEliminateSimpleEpsilonTransitions: 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Eliminating general epsilon transitions can get costly in the general 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * algorithm due to the large amount of generated new transitions and 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * associated comparisons. However for simple epsilon transition used just 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to separate building blocks when generating the automata this can be 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reduced to state elimination: 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - if there exists an epsilon from X to Y 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - if there is no other transition from X 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * then X and Y are semantically equivalent and X can be eliminated 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If X is the start state then make Y the start state, else replace the 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * target of all transitions to X by transitions to Y. 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) { 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int statenr, i, j, newto; 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr state, tmp; 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = ctxt->states[statenr]; 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == NULL) 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->nbTrans != 1) 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->type == XML_REGEXP_UNREACH_STATE) 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* is the only transition out a basic transition */ 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((state->trans[0].atom == NULL) && 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (state->trans[0].to >= 0) && 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (state->trans[0].to != statenr) && 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (state->trans[0].counter < 0) && 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (state->trans[0].count < 0)) { 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newto = state->trans[0].to; 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->type == XML_REGEXP_START_STATE) { 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Found simple epsilon trans from start %d to %d\n", 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statenr, newto); 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Found simple epsilon trans from %d to %d\n", 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statenr, newto); 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < state->nbTransTo;i++) { 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = ctxt->states[state->transTo[i]]; 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0;j < tmp->nbTrans;j++) { 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp->trans[j].to == statenr) { 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Changed transition %d on %d to go to %d\n", 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j, tmp->no, newto); 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp->trans[j].to = -1; 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(ctxt, tmp, tmp->trans[j].atom, 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->states[newto], 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp->trans[j].counter, 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp->trans[j].count); 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->type == XML_REGEXP_FINAL_STATE) 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->states[newto]->type = XML_REGEXP_FINAL_STATE; 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* eliminate the transition completely */ 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->nbTrans = 0; 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->type = XML_REGEXP_UNREACH_STATE; 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAEliminateEpsilonTransitions: 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAEliminateEpsilonTransitions(xmlRegParserCtxtPtr ctxt) { 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int statenr, transnr; 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr state; 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int has_epsilon; 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->states == NULL) return; 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Eliminate simple epsilon transition and the associated unreachable 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * states. 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAEliminateSimpleEpsilonTransitions(ctxt); 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = ctxt->states[statenr]; 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((state != NULL) && (state->type == XML_REGEXP_UNREACH_STATE)) { 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Removed unreachable state %d\n", statenr); 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeState(state); 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->states[statenr] = NULL; 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_epsilon = 0; 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Build the completed transitions bypassing the epsilons 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use a marking algorithm to avoid loops 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Mark sink states too. 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Process from the latests states backward to the start when 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * there is long cascading epsilon chains this minimize the 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * recursions and transition compares when adding the new ones 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (statenr = ctxt->nbStates - 1;statenr >= 0;statenr--) { 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = ctxt->states[statenr]; 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == NULL) 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((state->nbTrans == 0) && 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (state->type != XML_REGEXP_FINAL_STATE)) { 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->type = XML_REGEXP_SINK_STATE; 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (transnr = 0;transnr < state->nbTrans;transnr++) { 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((state->trans[transnr].atom == NULL) && 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (state->trans[transnr].to >= 0)) { 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->trans[transnr].to == statenr) { 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->trans[transnr].to = -1; 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Removed loopback epsilon trans %d on %d\n", 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transnr, statenr); 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (state->trans[transnr].count < 0) { 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int newto = state->trans[transnr].to; 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Found epsilon trans %d from %d to %d\n", 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transnr, statenr, newto); 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_epsilon = 1; 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->trans[transnr].to = -2; 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->mark = XML_REGEXP_MARK_START; 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAReduceEpsilonTransitions(ctxt, statenr, 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newto, state->trans[transnr].counter); 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->mark = XML_REGEXP_MARK_NORMAL; 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Found counted transition %d on %d\n", 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transnr, statenr); 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Eliminate the epsilon transitions 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_epsilon) { 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = ctxt->states[statenr]; 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == NULL) 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (transnr = 0;transnr < state->nbTrans;transnr++) { 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegTransPtr trans = &(state->trans[transnr]); 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((trans->atom == NULL) && 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (trans->count < 0) && 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (trans->to >= 0)) { 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans->to = -1; 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use this pass to detect unreachable states too 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = ctxt->states[statenr]; 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state != NULL) 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->reached = XML_REGEXP_MARK_NORMAL; 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = ctxt->states[0]; 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state != NULL) 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->reached = XML_REGEXP_MARK_START; 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (state != NULL) { 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr target = NULL; 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->reached = XML_REGEXP_MARK_VISITED; 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Mark all states reachable from the current reachable state 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (transnr = 0;transnr < state->nbTrans;transnr++) { 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((state->trans[transnr].to >= 0) && 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((state->trans[transnr].atom != NULL) || 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (state->trans[transnr].count >= 0))) { 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int newto = state->trans[transnr].to; 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->states[newto] == NULL) 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->states[newto]->reached == XML_REGEXP_MARK_NORMAL) { 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->states[newto]->reached = XML_REGEXP_MARK_START; 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target = ctxt->states[newto]; 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * find the next accessible state not explored 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target == NULL) { 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (statenr = 1;statenr < ctxt->nbStates;statenr++) { 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = ctxt->states[statenr]; 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((state != NULL) && (state->reached == 20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_MARK_START)) { 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target = state; 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = target; 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = ctxt->states[statenr]; 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((state != NULL) && (state->reached == XML_REGEXP_MARK_NORMAL)) { 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Removed unreachable state %d\n", statenr); 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeState(state); 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->states[statenr] = NULL; 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFACompareRanges(xmlRegRangePtr range1, xmlRegRangePtr range2) { 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 0; 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((range1->type == XML_REGEXP_RANGES) || 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_RANGES) || 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_SUBREG) || 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range1->type == XML_REGEXP_SUBREG) || 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range1->type == XML_REGEXP_STRING) || 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_STRING)) 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* put them in order */ 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range1->type > range2->type) { 20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegRangePtr tmp; 20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = range1; 20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range1 = range2; 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range2 = tmp; 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((range1->type == XML_REGEXP_ANYCHAR) || 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_ANYCHAR)) { 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((range1->type == XML_REGEXP_EPSILON) || 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_EPSILON)) { 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (range1->type == range2->type) { 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range1->type != XML_REGEXP_CHARVAL) 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if ((range1->end < range2->start) || 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->end < range1->start)) 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (range1->type == XML_REGEXP_CHARVAL) { 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int codepoint; 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int neg = 0; 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * just check all codepoints in the range for acceptance, 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is usually way cheaper since done only once at 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * compilation than testing over and over at runtime or 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pushing too many states when evaluating. 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((range1->neg == 0) && (range2->neg != 0)) || 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((range1->neg != 0) && (range2->neg == 0))) 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) neg = 1; 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (codepoint = range1->start;codepoint <= range1->end ;codepoint++) { 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegCheckCharacterRange(range2->type, codepoint, 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, range2->start, range2->end, 21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range2->blockName); 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret < 0) 21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((neg == 1) && (ret == 0)) || 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((neg == 0) && (ret == 1))) 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((range1->type == XML_REGEXP_BLOCK_NAME) || 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_BLOCK_NAME)) { 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range1->type == range2->type) { 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlStrEqual(range1->blockName, range2->blockName); 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * comparing a block range with anything else is way 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * too costly, and maintining the table is like too much 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * memory too, so let's force the automata to save state 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * here. 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((range1->type < XML_REGEXP_LETTER) || 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type < XML_REGEXP_LETTER)) { 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((range1->type == XML_REGEXP_ANYSPACE) && 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_NOTSPACE)) 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if ((range1->type == XML_REGEXP_INITNAME) && 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_NOTINITNAME)) 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if ((range1->type == XML_REGEXP_NAMECHAR) && 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_NOTNAMECHAR)) 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if ((range1->type == XML_REGEXP_DECIMAL) && 21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_NOTDECIMAL)) 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if ((range1->type == XML_REGEXP_REALCHAR) && 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_NOTREALCHAR)) 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* same thing to limit complexity */ 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* range1->type < range2->type here */ 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (range1->type) { 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER: 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* all disjoint except in the subgroups */ 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((range2->type == XML_REGEXP_LETTER_UPPERCASE) || 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_LETTER_LOWERCASE) || 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_LETTER_TITLECASE) || 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_LETTER_MODIFIER) || 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_LETTER_OTHERS)) 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK: 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((range2->type == XML_REGEXP_MARK_NONSPACING) || 21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_MARK_SPACECOMBINING) || 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_MARK_ENCLOSING)) 21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER: 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((range2->type == XML_REGEXP_NUMBER_DECIMAL) || 21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_NUMBER_LETTER) || 21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_NUMBER_OTHERS)) 21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT: 21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((range2->type == XML_REGEXP_PUNCT_CONNECTOR) || 21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_PUNCT_DASH) || 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_PUNCT_OPEN) || 21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_PUNCT_CLOSE) || 21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_PUNCT_INITQUOTE) || 21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_PUNCT_FINQUOTE) || 21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_PUNCT_OTHERS)) 21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR: 22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((range2->type == XML_REGEXP_SEPAR_SPACE) || 22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_SEPAR_LINE) || 22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_SEPAR_PARA)) 22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL: 22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((range2->type == XML_REGEXP_SYMBOL_MATH) || 22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_SYMBOL_CURRENCY) || 22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_SYMBOL_MODIFIER) || 22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_SYMBOL_OTHERS)) 22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER: 22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((range2->type == XML_REGEXP_OTHER_CONTROL) || 22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_OTHER_FORMAT) || 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type == XML_REGEXP_OTHER_PRIVATE)) 22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((range2->type >= XML_REGEXP_LETTER) && 22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (range2->type < XML_REGEXP_BLOCK_NAME)) 22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* safety net ! */ 22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((range1->neg == 0) && (range2->neg != 0)) || 22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((range1->neg != 0) && (range2->neg == 0))) 22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = !ret; 22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFACompareAtomTypes: 22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type1: an atom type 22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type2: an atom type 22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compares two atoms type to check whether they intersect in some ways, 22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is used by xmlFACompareAtoms only 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if they may intersect and 0 otherwise 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFACompareAtomTypes(xmlRegAtomType type1, xmlRegAtomType type2) { 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((type1 == XML_REGEXP_EPSILON) || 22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type1 == XML_REGEXP_CHARVAL) || 22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type1 == XML_REGEXP_RANGES) || 22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type1 == XML_REGEXP_SUBREG) || 22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type1 == XML_REGEXP_STRING) || 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type1 == XML_REGEXP_ANYCHAR)) 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((type2 == XML_REGEXP_EPSILON) || 22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 == XML_REGEXP_CHARVAL) || 22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 == XML_REGEXP_RANGES) || 22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 == XML_REGEXP_SUBREG) || 22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 == XML_REGEXP_STRING) || 22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 == XML_REGEXP_ANYCHAR)) 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type1 == type2) return(1); 22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* simplify subsequent compares by making sure type1 < type2 */ 22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type1 > type2) { 22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomType tmp = type1; 22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type1 = type2; 22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type2 = tmp; 22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type1) { 22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_ANYSPACE: /* \s */ 22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* can't be a letter, number, mark, pontuation, symbol */ 22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((type2 == XML_REGEXP_NOTSPACE) || 22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_LETTER) && 22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_LETTER_OTHERS)) || 22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_NUMBER) && 22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_NUMBER_OTHERS)) || 22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_MARK) && 22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_PUNCT) && 22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_SYMBOL) && 22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_SYMBOL_OTHERS)) 22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) return(0); 22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTSPACE: /* \S */ 22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_INITNAME: /* \l */ 22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* can't be a number, mark, separator, pontuation, symbol or other */ 22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((type2 == XML_REGEXP_NOTINITNAME) || 22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_NUMBER) && 22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_NUMBER_OTHERS)) || 22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_MARK) && 22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_SEPAR) && 22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_SEPAR_PARA)) || 22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_PUNCT) && 22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_SYMBOL) && 22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_SYMBOL_OTHERS)) || 23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_OTHER) && 23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_OTHER_NA)) 23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) return(0); 23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTINITNAME: /* \L */ 23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NAMECHAR: /* \c */ 23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* can't be a mark, separator, pontuation, symbol or other */ 23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((type2 == XML_REGEXP_NOTNAMECHAR) || 23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_MARK) && 23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_PUNCT) && 23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_SEPAR) && 23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_SEPAR_PARA)) || 23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_SYMBOL) && 23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_SYMBOL_OTHERS)) || 23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_OTHER) && 23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_OTHER_NA)) 23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) return(0); 23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTNAMECHAR: /* \C */ 23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_DECIMAL: /* \d */ 23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* can't be a letter, mark, separator, pontuation, symbol or other */ 23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((type2 == XML_REGEXP_NOTDECIMAL) || 23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 == XML_REGEXP_REALCHAR) || 23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_LETTER) && 23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_LETTER_OTHERS)) || 23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_MARK) && 23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_PUNCT) && 23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_SEPAR) && 23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_SEPAR_PARA)) || 23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_SYMBOL) && 23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_SYMBOL_OTHERS)) || 23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_OTHER) && 23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_OTHER_NA)) 23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) )return(0); 23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTDECIMAL: /* \D */ 23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_REALCHAR: /* \w */ 23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* can't be a mark, separator, pontuation, symbol or other */ 23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((type2 == XML_REGEXP_NOTDECIMAL) || 23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_MARK) && 23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_MARK_ENCLOSING)) || 23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_PUNCT) && 23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_PUNCT_OTHERS)) || 23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_SEPAR) && 23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_SEPAR_PARA)) || 23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_SYMBOL) && 23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_SYMBOL_OTHERS)) || 23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((type2 >= XML_REGEXP_OTHER) && 23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (type2 <= XML_REGEXP_OTHER_NA)) 23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) )return(0); 23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTREALCHAR: /* \W */ 23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * at that point we know both type 1 and type2 are from 23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * character categories are ordered and are different, 23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it becomes simple because this is a partition 23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER: 23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type2 <= XML_REGEXP_LETTER_OTHERS) 23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_UPPERCASE: 23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_LOWERCASE: 23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_TITLECASE: 23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_MODIFIER: 23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_OTHERS: 23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK: 23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type2 <= XML_REGEXP_MARK_ENCLOSING) 23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK_NONSPACING: 23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK_SPACECOMBINING: 23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK_ENCLOSING: 23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER: 23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type2 <= XML_REGEXP_NUMBER_OTHERS) 23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER_DECIMAL: 23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER_LETTER: 23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER_OTHERS: 23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT: 23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type2 <= XML_REGEXP_PUNCT_OTHERS) 23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_CONNECTOR: 23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_DASH: 23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_OPEN: 23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_CLOSE: 23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_INITQUOTE: 24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_FINQUOTE: 24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_OTHERS: 24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR: 24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type2 <= XML_REGEXP_SEPAR_PARA) 24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR_SPACE: 24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR_LINE: 24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR_PARA: 24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL: 24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type2 <= XML_REGEXP_SYMBOL_OTHERS) 24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_MATH: 24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_CURRENCY: 24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_MODIFIER: 24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_OTHERS: 24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER: 24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type2 <= XML_REGEXP_OTHER_NA) 24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_CONTROL: 24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_FORMAT: 24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_PRIVATE: 24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_NA: 24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAEqualAtoms: 24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom1: an atom 24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom2: an atom 24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @deep: if not set only compare string pointers 24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compares two atoms to check whether they are the same exactly 24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is used to remove equivalent transitions 24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if same and 0 otherwise 24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAEqualAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) { 24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 0; 24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom1 == atom2) 24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((atom1 == NULL) || (atom2 == NULL)) 24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom1->type != atom2->type) 24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (atom1->type) { 24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_EPSILON: 24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_STRING: 24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!deep) 24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (atom1->valuep == atom2->valuep); 24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlStrEqual((xmlChar *)atom1->valuep, 24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlChar *)atom2->valuep); 24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_CHARVAL: 24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (atom1->codepoint == atom2->codepoint); 24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_RANGES: 24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* too hard to do in the general case */ 24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFACompareAtoms: 24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom1: an atom 24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @atom2: an atom 24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @deep: if not set only compare string pointers 24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compares two atoms to check whether they intersect in some ways, 24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is used by xmlFAComputesDeterminism and xmlFARecurseDeterminism only 24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if yes and 0 otherwise 24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFACompareAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) { 24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 1; 24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom1 == atom2) 24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((atom1 == NULL) || (atom2 == NULL)) 24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((atom1->type == XML_REGEXP_ANYCHAR) || 25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (atom2->type == XML_REGEXP_ANYCHAR)) 25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom1->type > atom2->type) { 25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr tmp; 25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = atom1; 25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom1 = atom2; 25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom2 = tmp; 25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom1->type != atom2->type) { 25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlFACompareAtomTypes(atom1->type, atom2->type); 25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if they can't intersect at the type level break now */ 25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 0) 25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (atom1->type) { 25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_STRING: 25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!deep) 25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (atom1->valuep != atom2->valuep); 25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegStrEqualWildcard((xmlChar *)atom1->valuep, 25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlChar *)atom2->valuep); 25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_EPSILON: 25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto not_determinist; 25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_CHARVAL: 25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom2->type == XML_REGEXP_CHARVAL) { 25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (atom1->codepoint == atom2->codepoint); 25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegCheckCharacter(atom2, atom1->codepoint); 25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret < 0) 25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_RANGES: 25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom2->type == XML_REGEXP_RANGES) { 25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j, res; 25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegRangePtr r1, r2; 25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * need to check that none of the ranges eventually matches 25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < atom1->nbRanges;i++) { 25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0;j < atom2->nbRanges;j++) { 25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r1 = atom1->ranges[i]; 25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r2 = atom2->ranges[j]; 25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = xmlFACompareRanges(r1, r2); 25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res == 1) { 25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto done; 25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto not_determinist; 25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)done: 25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom1->neg != atom2->neg) { 25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = !ret; 25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 0) 25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)not_determinist: 25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFARecurseDeterminism: 25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check whether the associated regexp is determinist, 25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * should be called after xmlFAEliminateEpsilonTransitions() 25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state, 25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int to, xmlRegAtomPtr atom) { 25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 1; 25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int res; 25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int transnr, nbTrans; 25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegTransPtr t1; 25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int deep = 1; 25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == NULL) 25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->flags & AM_AUTOMATA_RNG) 25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deep = 0; 25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * don't recurse on transitions potentially added in the course of 25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the elimination. 25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbTrans = state->nbTrans; 25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (transnr = 0;transnr < nbTrans;transnr++) { 25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t1 = &(state->trans[transnr]); 26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * check transitions conflicting with the one looked at 26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t1->atom == NULL) { 26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t1->to < 0) 26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to], 26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to, atom); 26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res == 0) { 26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* t1->nd = 1; */ 26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t1->to != to) 26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlFACompareAtoms(t1->atom, atom, deep)) { 26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* mark the transition as non-deterministic */ 26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t1->nd = 1; 26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAComputesDeterminism: 26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check whether the associated regexp is determinist, 26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * should be called after xmlFAEliminateEpsilonTransitions() 26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) { 26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int statenr, transnr; 26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr state; 26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegTransPtr t1, t2, last; 26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 1; 26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int deep = 1; 26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("xmlFAComputesDeterminism\n"); 26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegPrintCtxt(stdout, ctxt); 26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->determinist != -1) 26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ctxt->determinist); 26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->flags & AM_AUTOMATA_RNG) 26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deep = 0; 26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * First cleanup the automata removing cancelled transitions 26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = ctxt->states[statenr]; 26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == NULL) 26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->nbTrans < 2) 26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (transnr = 0;transnr < state->nbTrans;transnr++) { 26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t1 = &(state->trans[transnr]); 26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Determinism checks in case of counted or all transitions 26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * will have to be handled separately 26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t1->atom == NULL) { 26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* t1->nd = 1; */ 26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t1->to == -1) /* eliminated */ 26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < transnr;i++) { 26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t2 = &(state->trans[i]); 26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t2->to == -1) /* eliminated */ 26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t2->atom != NULL) { 26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t1->to == t2->to) { 26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Here we use deep because we want to keep the 26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * transitions which indicate a conflict 26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlFAEqualAtoms(t1->atom, t2->atom, deep) && 26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (t1->counter == t2->counter) && 26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (t1->count == t2->count)) 26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t2->to = -1; /* eliminated */ 26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check for all states that there aren't 2 transitions 26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * with the same atom and a different target. 26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (statenr = 0;statenr < ctxt->nbStates;statenr++) { 26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = ctxt->states[statenr]; 26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == NULL) 27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state->nbTrans < 2) 27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last = NULL; 27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (transnr = 0;transnr < state->nbTrans;transnr++) { 27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t1 = &(state->trans[transnr]); 27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Determinism checks in case of counted or all transitions 27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * will have to be handled separately 27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t1->atom == NULL) { 27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t1->to == -1) /* eliminated */ 27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < transnr;i++) { 27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t2 = &(state->trans[i]); 27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t2->to == -1) /* eliminated */ 27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t2->atom != NULL) { 27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * But here we don't use deep because we want to 27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * find transitions which indicate a conflict 27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlFACompareAtoms(t1->atom, t2->atom, 1)) { 27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* mark the transitions as non-deterministic ones */ 27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t1->nd = 1; 27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t2->nd = 1; 27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last = t1; 27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (t1->to != -1) { 27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * do the closure in case of remaining specific 27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * epsilon transitions like choices or all 27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to], 27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t2->to, t2->atom); 27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* don't shortcut the computation so all non deterministic 27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transition get marked down 27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 0) 27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 0) { 27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t1->nd = 1; 27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* t2->nd = 1; */ 27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last = t1; 27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* don't shortcut the computation so all non deterministic 27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transition get marked down 27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 0) 27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; */ 27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * mark specifically the last non-deterministic transition 27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from a state since there is no need to set-up rollback 27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from it 27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last != NULL) { 27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last->nd = 2; 27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* don't shortcut the computation so all non deterministic 27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transition get marked down 27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 0) 27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; */ 27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->determinist = ret; 27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Routines to check input against transition atoms * 27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, int neg, 27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start, int end, const xmlChar *blockName) { 27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 0; 27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_STRING: 27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SUBREG: 27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_RANGES: 27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_EPSILON: 27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_ANYCHAR: 27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = ((codepoint != '\n') && (codepoint != '\r')); 27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_CHARVAL: 27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = ((codepoint >= start) && (codepoint <= end)); 27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTSPACE: 27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) neg = !neg; 28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_ANYSPACE: 28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = ((codepoint == '\n') || (codepoint == '\r') || 28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (codepoint == '\t') || (codepoint == ' ')); 28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTINITNAME: 28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) neg = !neg; 28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_INITNAME: 28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (IS_LETTER(codepoint) || 28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (codepoint == '_') || (codepoint == ':')); 28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTNAMECHAR: 28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) neg = !neg; 28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NAMECHAR: 28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (IS_LETTER(codepoint) || IS_DIGIT(codepoint) || 28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (codepoint == '.') || (codepoint == '-') || 28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (codepoint == '_') || (codepoint == ':') || 28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IS_COMBINING(codepoint) || IS_EXTENDER(codepoint)); 28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTDECIMAL: 28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) neg = !neg; 28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_DECIMAL: 28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatNd(codepoint); 28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_REALCHAR: 28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) neg = !neg; 28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTREALCHAR: 28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatP(codepoint); 28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 0) 28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatZ(codepoint); 28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 0) 28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatC(codepoint); 28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER: 28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatL(codepoint); 28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_UPPERCASE: 28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatLu(codepoint); 28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_LOWERCASE: 28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatLl(codepoint); 28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_TITLECASE: 28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatLt(codepoint); 28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_MODIFIER: 28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatLm(codepoint); 28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_OTHERS: 28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatLo(codepoint); 28495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK: 28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatM(codepoint); 28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK_NONSPACING: 28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatMn(codepoint); 28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK_SPACECOMBINING: 28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatMc(codepoint); 28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK_ENCLOSING: 28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatMe(codepoint); 28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER: 28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatN(codepoint); 28645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER_DECIMAL: 28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatNd(codepoint); 28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER_LETTER: 28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatNl(codepoint); 28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER_OTHERS: 28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatNo(codepoint); 28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT: 28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatP(codepoint); 28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_CONNECTOR: 28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatPc(codepoint); 28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_DASH: 28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatPd(codepoint); 28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_OPEN: 28845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatPs(codepoint); 28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_CLOSE: 28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatPe(codepoint); 28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_INITQUOTE: 28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatPi(codepoint); 28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_FINQUOTE: 28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatPf(codepoint); 28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_OTHERS: 28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatPo(codepoint); 28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR: 28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatZ(codepoint); 29005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR_SPACE: 29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatZs(codepoint); 29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR_LINE: 29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatZl(codepoint); 29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR_PARA: 29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatZp(codepoint); 29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL: 29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatS(codepoint); 29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_MATH: 29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatSm(codepoint); 29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_CURRENCY: 29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatSc(codepoint); 29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_MODIFIER: 29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatSk(codepoint); 29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_OTHERS: 29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatSo(codepoint); 29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER: 29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatC(codepoint); 29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_CONTROL: 29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatCc(codepoint); 29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_FORMAT: 29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatCf(codepoint); 29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_PRIVATE: 29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsCatCo(codepoint); 29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_NA: 29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ret = xmlUCSIsCatCn(codepoint); */ 29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Seems it doesn't exist anymore in recent Unicode releases */ 29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_BLOCK_NAME: 29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlUCSIsBlock(codepoint, (const char *) blockName); 29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (neg) 29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(!ret); 29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint) { 29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, ret = 0; 29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegRangePtr range; 29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((atom == NULL) || (!IS_CHAR(codepoint))) 29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (atom->type) { 29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SUBREG: 29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_EPSILON: 29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_CHARVAL: 29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(codepoint == atom->codepoint); 29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_RANGES: { 29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int accept = 0; 29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < atom->nbRanges;i++) { 29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range = atom->ranges[i]; 29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range->neg == 2) { 29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegCheckCharacterRange(range->type, codepoint, 29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, range->start, range->end, 29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range->blockName); 29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret != 0) 29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); /* excluded char */ 29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (range->neg) { 29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegCheckCharacterRange(range->type, codepoint, 29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, range->start, range->end, 29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range->blockName); 29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 0) 29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept = 1; 29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegCheckCharacterRange(range->type, codepoint, 29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, range->start, range->end, 29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range->blockName); 29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret != 0) 29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept = 1; /* might still be excluded */ 29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(accept); 29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_STRING: 29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("TODO: XML_REGEXP_STRING\n"); 29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_ANYCHAR: 29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_ANYSPACE: 29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTSPACE: 30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_INITNAME: 30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTINITNAME: 30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NAMECHAR: 30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTNAMECHAR: 30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_DECIMAL: 30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTDECIMAL: 30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_REALCHAR: 30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NOTREALCHAR: 30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER: 30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_UPPERCASE: 30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_LOWERCASE: 30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_TITLECASE: 30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_MODIFIER: 30135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_LETTER_OTHERS: 30145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK: 30155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK_NONSPACING: 30165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK_SPACECOMBINING: 30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_MARK_ENCLOSING: 30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER: 30195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER_DECIMAL: 30205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER_LETTER: 30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_NUMBER_OTHERS: 30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT: 30235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_CONNECTOR: 30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_DASH: 30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_OPEN: 30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_CLOSE: 30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_INITQUOTE: 30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_FINQUOTE: 30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_PUNCT_OTHERS: 30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR: 30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR_SPACE: 30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR_LINE: 30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SEPAR_PARA: 30345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL: 30355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_MATH: 30365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_CURRENCY: 30375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_MODIFIER: 30385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_SYMBOL_OTHERS: 30395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER: 30405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_CONTROL: 30415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_FORMAT: 30425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_PRIVATE: 30435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_OTHER_NA: 30445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_REGEXP_BLOCK_NAME: 30455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegCheckCharacterRange(atom->type, codepoint, 0, 0, 0, 30465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (const xmlChar *)atom->valuep); 30475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->neg) 30485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = !ret; 30495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 30505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 30525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 30535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 30555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 30565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Saving and restoring state of an execution context * 30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 30585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 30615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFARegDebugExec(xmlRegExecCtxtPtr exec) { 30635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("state: %d:%d:idx %d", exec->state->no, exec->transno, exec->index); 30645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->inputStack != NULL) { 30655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 30665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(": "); 30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;(i < 3) && (i < exec->inputStackNr);i++) 30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("%s ", (const char *) 30695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStack[exec->inputStackNr - (i + 1)].value); 30705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 30715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf(": %s", &(exec->inputString[exec->index])); 30725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("\n"); 30745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 30755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 30765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 30785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFARegExecSave(xmlRegExecCtxtPtr exec) { 30795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 30805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("saving "); 30815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno++; 30825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegDebugExec(exec); 30835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno--; 30845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 30855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef MAX_PUSH 30865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->nbPush > MAX_PUSH) { 30875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 30885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->nbPush++; 30905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 30915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->maxRollbacks == 0) { 30935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->maxRollbacks = 4; 30945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->rollbacks = (xmlRegExecRollback *) xmlMalloc(exec->maxRollbacks * 30955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(xmlRegExecRollback)); 30965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->rollbacks == NULL) { 30975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(NULL, "saving regexp"); 30985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->maxRollbacks = 0; 30995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 31005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(exec->rollbacks, 0, 31025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->maxRollbacks * sizeof(xmlRegExecRollback)); 31035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (exec->nbRollbacks >= exec->maxRollbacks) { 31045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegExecRollback *tmp; 31055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len = exec->maxRollbacks; 31065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->maxRollbacks *= 2; 31085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = (xmlRegExecRollback *) xmlRealloc(exec->rollbacks, 31095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->maxRollbacks * sizeof(xmlRegExecRollback)); 31105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(NULL, "saving regexp"); 31125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->maxRollbacks /= 2; 31135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->rollbacks = tmp; 31165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = &exec->rollbacks[len]; 31175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(tmp, 0, (exec->maxRollbacks - len) * sizeof(xmlRegExecRollback)); 31185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->rollbacks[exec->nbRollbacks].state = exec->state; 31205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->rollbacks[exec->nbRollbacks].index = exec->index; 31215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->rollbacks[exec->nbRollbacks].nextbranch = exec->transno + 1; 31225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->comp->nbCounters > 0) { 31235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->rollbacks[exec->nbRollbacks].counts == NULL) { 31245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->rollbacks[exec->nbRollbacks].counts = (int *) 31255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlMalloc(exec->comp->nbCounters * sizeof(int)); 31265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->rollbacks[exec->nbRollbacks].counts == NULL) { 31275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(NULL, "saving regexp"); 31285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -5; 31295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 31305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(exec->rollbacks[exec->nbRollbacks].counts, exec->counts, 31335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->comp->nbCounters * sizeof(int)); 31345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->nbRollbacks++; 31365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 31375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 31395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFARegExecRollBack(xmlRegExecCtxtPtr exec) { 31405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->nbRollbacks <= 0) { 31415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -1; 31425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 31435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("rollback failed on empty stack\n"); 31445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 31455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 31465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->nbRollbacks--; 31485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->state = exec->rollbacks[exec->nbRollbacks].state; 31495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->index = exec->rollbacks[exec->nbRollbacks].index; 31505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno = exec->rollbacks[exec->nbRollbacks].nextbranch; 31515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->comp->nbCounters > 0) { 31525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->rollbacks[exec->nbRollbacks].counts == NULL) { 31535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "exec save: allocation failed"); 31545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -6; 31555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 31565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(exec->counts, exec->rollbacks[exec->nbRollbacks].counts, 31585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->comp->nbCounters * sizeof(int)); 31595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 31625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("restored "); 31635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegDebugExec(exec); 31645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 31655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 31665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 31685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 31695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Verifier, running an input against a compiled regexp * 31705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 31715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 31725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 31745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) { 31755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegExecCtxt execval; 31765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegExecCtxtPtr exec = &execval; 31775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret, codepoint = 0, len, deter; 31785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputString = content; 31805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->index = 0; 31815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->nbPush = 0; 31825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->determinist = 1; 31835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->maxRollbacks = 0; 31845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->nbRollbacks = 0; 31855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->rollbacks = NULL; 31865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = 0; 31875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->comp = comp; 31885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->state = comp->states[0]; 31895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno = 0; 31905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transcount = 0; 31915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStack = NULL; 31925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStackMax = 0; 31935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->nbCounters > 0) { 31945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int)); 31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->counts == NULL) { 31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(NULL, "running regexp"); 31975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 31985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(exec->counts, 0, comp->nbCounters * sizeof(int)); 32005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 32015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->counts = NULL; 32025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((exec->status == 0) && 32035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((exec->inputString[exec->index] != 0) || 32045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((exec->state != NULL) && 32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (exec->state->type != XML_REGEXP_FINAL_STATE)))) { 32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegTransPtr trans; 32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom; 32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If end of input on non-terminal state, rollback, however we may 32115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * still have epsilon like transition for counted transitions 32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on counters, in that case don't break too early. Additionally, 32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if we are working on a range like "AB{0,2}", where B is not present, 32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we don't want to break. 32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = 1; 32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL)) { 32185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if there is a transition, we must check if 32205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * atom allows minOccurs of 0 32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 32225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->transno < exec->state->nbTrans) { 32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans = &exec->state->trans[exec->transno]; 32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->to >=0) { 32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom = trans->atom; 32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!((atom->min == 0) && (atom->max > 0))) 32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transcount = 0; 32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (;exec->transno < exec->state->nbTrans;exec->transno++) { 32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans = &exec->state->trans[exec->transno]; 32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->to < 0) 32375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 32385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom = trans->atom; 32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deter = 1; 32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->count >= 0) { 32425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count; 32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegCounterPtr counter; 32445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->counts == NULL) { 32465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -1; 32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A counted transition. 32515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 32525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count = exec->counts[trans->count]; 32545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = &exec->comp->counters[trans->count]; 32555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("testing count %d: val %d, min %d, max %d\n", 32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans->count, count, counter->min, counter->max); 32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 32595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = ((count >= counter->min) && (count <= counter->max)); 32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret) && (counter->min != counter->max)) 32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deter = 0; 32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (atom == NULL) { 32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "epsilon transition left at runtime\n"); 32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -2; 32655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (exec->inputString[exec->index] != 0) { 32675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len); 32685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegCheckCharacter(atom, codepoint); 32695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret == 1) && (atom->min >= 0) && (atom->max > 0)) { 32705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr to = comp->states[trans->to]; 32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 32735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is a multiple input sequence 32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If there is a counter associated increment it now. 32755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * before potentially saving and rollback 32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * do not increment if the counter is already over the 32775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * maximum limit in which case get to next transition 32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 32795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->counter >= 0) { 32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegCounterPtr counter; 32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec->counts == NULL) || 32835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (exec->comp == NULL) || 32845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (exec->comp->counters == NULL)) { 32855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -1; 32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 32875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = &exec->comp->counters[trans->counter]; 32895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->counts[trans->counter] >= counter->max) 32905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; /* for loop on transitions */ 32915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 32935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Increasing count %d\n", trans->counter); 32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->counts[trans->counter]++; 32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->state->nbTrans > exec->transno + 1) { 32985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecSave(exec); 32995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transcount = 1; 33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 33025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Try to progress as much as possible on the input 33045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 33055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->transcount == atom->max) { 33065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 33075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->index += len; 33095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 33105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * End of input: stop here 33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 33125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->inputString[exec->index] == 0) { 33135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->index -= len; 33145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 33155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->transcount >= atom->min) { 33175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int transno = exec->transno; 33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr state = exec->state; 33195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 33215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The transition is acceptable save it 33225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 33235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno = -1; /* trick */ 33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->state = to; 33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecSave(exec); 33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno = transno; 33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->state = state; 33285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), 33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len); 33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegCheckCharacter(atom, codepoint); 33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transcount++; 33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (ret == 1); 33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->transcount < atom->min) 33355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 33365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 33385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the last check failed but one transition was found 33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * possible, rollback 33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret < 0) 33425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 0) { 33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 33455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->counter >= 0) { 33475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->counts == NULL) { 33485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -1; 33495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 33505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 33525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Decreasing count %d\n", trans->counter); 33535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 33545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->counts[trans->counter]--; 33555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((ret == 0) && (atom->min == 0) && (atom->max > 0)) { 33575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 33585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we don't match on the codepoint, but minOccurs of 0 33595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * says that's ok. Setting len to 0 inhibits stepping 33605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * over the codepoint. 33615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 33625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transcount = 1; 33635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = 0; 33645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 33655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((atom->min == 0) && (atom->max > 0)) { 33675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* another spot to match when minOccurs is 0 */ 33685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transcount = 1; 33695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = 0; 33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 33715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 1) { 33735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((trans->nd == 1) || 33745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((trans->count >= 0) && (deter == 0) && 33755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (exec->state->nbTrans > exec->transno + 1))) { 33765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 33775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->nd == 1) 33785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Saving on nd transition atom %d for %c at %d\n", 33795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans->atom->no, codepoint, exec->index); 33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Saving on counted transition count %d for %c at %d\n", 33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans->count, codepoint, exec->index); 33835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecSave(exec); 33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->counter >= 0) { 33875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegCounterPtr counter; 33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* make sure we don't go over the counter maximum value */ 33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec->counts == NULL) || 33915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (exec->comp == NULL) || 33925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (exec->comp->counters == NULL)) { 33935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -1; 33945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = &exec->comp->counters[trans->counter]; 33975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->counts[trans->counter] >= counter->max) 33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; /* for loop on transitions */ 33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Increasing count %d\n", trans->counter); 34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->counts[trans->counter]++; 34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((trans->count >= 0) && 34055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (trans->count < REGEXP_ALL_COUNTER)) { 34065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->counts == NULL) { 34075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -1; 34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 34095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("resetting count %d on transition\n", 34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans->count); 34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->counts[trans->count] = 0; 34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("entering state %d\n", trans->to); 34185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 34195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->state = comp->states[trans->to]; 34205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno = 0; 34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->atom != NULL) { 34225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->index += len; 34235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto progress; 34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ret < 0) { 34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -4; 34275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec->transno != 0) || (exec->state->nbTrans == 0)) { 34315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)rollback: 34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 34335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Failed to find a way out 34345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 34355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->determinist = 0; 34365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 34375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("rollback from state %d on %d:%c\n", exec->state->no, 34385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codepoint,codepoint); 34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 34405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecRollBack(exec); 34415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)progress: 34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 34445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error: 34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->rollbacks != NULL) { 34475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->counts != NULL) { 34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < exec->maxRollbacks;i++) 34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->rollbacks[i].counts != NULL) 34525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec->rollbacks[i].counts); 34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec->rollbacks); 34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->counts != NULL) 34575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec->counts); 34585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->status == 0) 34595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 34605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->status == -1) { 34615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->nbPush > MAX_PUSH) 34625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 34635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(exec->status); 34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Progressive interface to the verifier one atom at a time * 34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_ERR 34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void testerr(xmlRegExecCtxtPtr exec); 34755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 34785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegNewExecCtxt: 34795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: a precompiled regular expression 34805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @callback: a callback function used for handling progresses in the 34815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * automata matching phase 34825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: the context data associated to the callback in this context 34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Build a context used for progressive evaluation of a regexp. 34855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 34865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new context 34875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 34885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecCtxtPtr 34895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegNewExecCtxt(xmlRegexpPtr comp, xmlRegExecCallbacks callback, void *data) { 34905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegExecCtxtPtr exec; 34915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp == NULL) 34935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 34945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((comp->compact == NULL) && (comp->states == NULL)) 34955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 34965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec = (xmlRegExecCtxtPtr) xmlMalloc(sizeof(xmlRegExecCtxt)); 34975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec == NULL) { 34985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(NULL, "creating execution context"); 34995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 35005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(exec, 0, sizeof(xmlRegExecCtxt)); 35025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputString = NULL; 35035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->index = 0; 35045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->determinist = 1; 35055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->maxRollbacks = 0; 35065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->nbRollbacks = 0; 35075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->rollbacks = NULL; 35085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = 0; 35095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->comp = comp; 35105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->compact == NULL) 35115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->state = comp->states[0]; 35125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno = 0; 35135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transcount = 0; 35145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->callback = callback; 35155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->data = data; 35165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->nbCounters > 0) { 35175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 35185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For error handling, exec->counts is allocated twice the size 35195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the second half is used to store the data in case of rollback 35205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 35215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int) 35225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2); 35235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->counts == NULL) { 35245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(NULL, "creating execution context"); 35255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec); 35265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 35275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(exec->counts, 0, comp->nbCounters * sizeof(int) * 2); 35295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->errCounts = &exec->counts[comp->nbCounters]; 35305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 35315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->counts = NULL; 35325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->errCounts = NULL; 35335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStackMax = 0; 35355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStackNr = 0; 35365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStack = NULL; 35375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->errStateNo = -1; 35385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->errString = NULL; 35395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->nbPush = 0; 35405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(exec); 35415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 35425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 35445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegFreeExecCtxt: 35455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regular expression evaulation context 35465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 35475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free the structures associated to a regular expression evaulation context. 35485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 35495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 35505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegFreeExecCtxt(xmlRegExecCtxtPtr exec) { 35515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec == NULL) 35525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 35535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->rollbacks != NULL) { 35555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->counts != NULL) { 35565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 35575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < exec->maxRollbacks;i++) 35595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->rollbacks[i].counts != NULL) 35605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec->rollbacks[i].counts); 35615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec->rollbacks); 35635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->counts != NULL) 35655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec->counts); 35665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->inputStack != NULL) { 35675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 35685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < exec->inputStackNr;i++) { 35705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->inputStack[i].value != NULL) 35715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec->inputStack[i].value); 35725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec->inputStack); 35745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->errString != NULL) 35765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec->errString); 35775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec); 35785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 35795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFARegExecSaveInputString(xmlRegExecCtxtPtr exec, const xmlChar *value, 35825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *data) { 35835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 35845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("saving value: %d:%s\n", exec->inputStackNr, value); 35855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 35865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->inputStackMax == 0) { 35875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStackMax = 4; 35885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStack = (xmlRegInputTokenPtr) 35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlMalloc(exec->inputStackMax * sizeof(xmlRegInputToken)); 35905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->inputStack == NULL) { 35915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(NULL, "pushing input string"); 35925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStackMax = 0; 35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 35945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (exec->inputStackNr + 1 >= exec->inputStackMax) { 35965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegInputTokenPtr tmp; 35975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStackMax *= 2; 35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = (xmlRegInputTokenPtr) xmlRealloc(exec->inputStack, 36005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStackMax * sizeof(xmlRegInputToken)); 36015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 36025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpErrMemory(NULL, "pushing input string"); 36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStackMax /= 2; 36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStack = tmp; 36075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStack[exec->inputStackNr].value = xmlStrdup(value); 36095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStack[exec->inputStackNr].data = data; 36105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStackNr++; 36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStack[exec->inputStackNr].value = NULL; 36125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->inputStack[exec->inputStackNr].data = NULL; 36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 36145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 36165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegStrEqualWildcard: 36175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @expStr: the string to be evaluated 36185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @valStr: the validation string 36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Checks if both strings are equal or have the same content. "*" 36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * can be used as a wildcard in @valStr; "|" is used as a seperator of 36225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * substrings in both @expStr and @valStr. 36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 36245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if the comparison is satisfied and the number of substrings 36255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is equal, 0 otherwise. 36265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 36275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 36295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegStrEqualWildcard(const xmlChar *expStr, const xmlChar *valStr) { 36305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (expStr == valStr) return(1); 36315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (expStr == NULL) return(0); 36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (valStr == NULL) return(0); 36335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Eval if we have a wildcard for the current item. 36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*expStr != *valStr) { 36385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if one of them starts with a wildcard make valStr be it */ 36395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*valStr == '*') { 36405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *tmp; 36415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = valStr; 36435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valStr = expStr; 36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expStr = tmp; 36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*valStr != 0) && (*expStr != 0) && (*expStr++ == '*')) { 36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 36485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*valStr == XML_REG_STRING_SEPARATOR) 36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 36505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valStr++; 36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (*valStr != 0); 36525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 36535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expStr++; 36575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valStr++; 36585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (*valStr != 0); 36595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*expStr != 0) 36605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 36615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 36625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (1); 36635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 36645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegCompactPushString: 36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context 36685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: the precompiled exec with a compact table 36695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value: a string token input 36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data associated to the token to reuse in callbacks 36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 36725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Push one input token in the execution context 36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 1 if the regexp reached a final state, 0 if non-final, and 36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a negative value in case of error. 36765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 36775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 36785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegCompactPushString(xmlRegExecCtxtPtr exec, 36795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpPtr comp, 36805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *value, 36815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *data) { 36825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int state = exec->index; 36835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, target; 36845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((comp == NULL) || (comp->compact == NULL) || (comp->stringMap == NULL)) 36865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value == NULL) { 36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * are we at a final state ? 36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 36925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->compact[state * (comp->nbstrings + 1)] == 36935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_FINAL_STATE) 36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("value pushed: %s\n", value); 37005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 37015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Examine all outside transitions from current state 37045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 37055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < comp->nbstrings;i++) { 37065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target = comp->compact[state * (comp->nbstrings + 1) + i + 1]; 37075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((target > 0) && (target <= comp->nbstates)) { 37085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target--; /* to avoid 0 */ 37095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlRegStrEqualWildcard(comp->stringMap[i], value)) { 37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->index = target; 37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec->callback != NULL) && (comp->transdata != NULL)) { 37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->callback(exec->data, value, 37135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->transdata[state * comp->nbstrings + i], data); 37145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("entering state %d\n", target); 37175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 37185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->compact[target * (comp->nbstrings + 1)] == 37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SINK_STATE) 37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->compact[target * (comp->nbstrings + 1)] == 37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_FINAL_STATE) 37245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 37255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 37265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 37305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Failed to find an exit transition out from current state for the 37315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * current token 37325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 37335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 37345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("failed to find a transition for %s on state %d\n", value, state); 37355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 37365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error: 37375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->errString != NULL) 37385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec->errString); 37395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->errString = xmlStrdup(value); 37405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->errStateNo = state; 37415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -1; 37425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_ERR 37435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testerr(exec); 37445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 37455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 37465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 37475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 37495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegExecPushStringInternal: 37505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context or NULL to indicate the end 37515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value: a string token input 37525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data associated to the token to reuse in callbacks 37535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @compound: value was assembled from 2 strings 37545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 37555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Push one input token in the execution context 37565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 37575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 1 if the regexp reached a final state, 0 if non-final, and 37585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a negative value in case of error. 37595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 37605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 37615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value, 37625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *data, int compound) { 37635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegTransPtr trans; 37645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom; 37655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret; 37665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int final = 0; 37675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int progress = 1; 37685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec == NULL) 37705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 37715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->comp == NULL) 37725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 37735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->status != 0) 37745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(exec->status); 37755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->comp->compact != NULL) 37775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlRegCompactPushString(exec, exec->comp, value, data)); 37785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value == NULL) { 37805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->state->type == XML_REGEXP_FINAL_STATE) 37815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 37825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final = 1; 37835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 37865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("value pushed: %s\n", value); 37875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 37885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 37895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If we have an active rollback stack push the new value there 37905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and get back to where we were left 37915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 37925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((value != NULL) && (exec->inputStackNr > 0)) { 37935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecSaveInputString(exec, value, data); 37945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = exec->inputStack[exec->index].value; 37955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = exec->inputStack[exec->index].data; 37965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 37975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("value loaded: %s\n", value); 37985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 37995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((exec->status == 0) && 38025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((value != NULL) || 38035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((final == 1) && 38045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (exec->state->type != XML_REGEXP_FINAL_STATE)))) { 38055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 38075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * End of input on non-terminal state, rollback, however we may 38085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * still have epsilon like transition for counted transitions 38095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on counters, in that case don't break too early. 38105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 38115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((value == NULL) && (exec->counts == NULL)) 38125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 38135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transcount = 0; 38155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (;exec->transno < exec->state->nbTrans;exec->transno++) { 38165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans = &exec->state->trans[exec->transno]; 38175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->to < 0) 38185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 38195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom = trans->atom; 38205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 38215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->count == REGEXP_ALL_LAX_COUNTER) { 38225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 38235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count; 38245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegTransPtr t; 38255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegCounterPtr counter; 38265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 38285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 38305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("testing all lax %d\n", trans->count); 38315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 38325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 38335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check all counted transitions from the current state 38345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 38355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((value == NULL) && (final)) { 38365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 38375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (value != NULL) { 38385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < exec->state->nbTrans;i++) { 38395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = &exec->state->trans[i]; 38405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((t->counter < 0) || (t == trans)) 38415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 38425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = &exec->comp->counters[t->counter]; 38435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count = exec->counts[t->counter]; 38445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((count < counter->max) && 38455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (t->atom != NULL) && 38465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(value, t->atom->valuep))) { 38475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 38485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 38495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((count >= counter->min) && 38515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (count < counter->max) && 38525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (t->atom != NULL) && 38535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(value, t->atom->valuep))) { 38545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 38555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 38565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (trans->count == REGEXP_ALL_COUNTER) { 38605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 38615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count; 38625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegTransPtr t; 38635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegCounterPtr counter; 38645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 1; 38665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 38685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("testing all %d\n", trans->count); 38695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 38705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 38715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check all counted transitions from the current state 38725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 38735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < exec->state->nbTrans;i++) { 38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = &exec->state->trans[i]; 38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((t->counter < 0) || (t == trans)) 38765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = &exec->comp->counters[t->counter]; 38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count = exec->counts[t->counter]; 38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((count < counter->min) || (count > counter->max)) { 38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 38815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 38825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (trans->count >= 0) { 38855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count; 38865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegCounterPtr counter; 38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A counted transition. 38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 38915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count = exec->counts[trans->count]; 38935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = &exec->comp->counters[trans->count]; 38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("testing count %d: val %d, min %d, max %d\n", 38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans->count, count, counter->min, counter->max); 38975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 38985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = ((count >= counter->min) && (count <= counter->max)); 38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (atom == NULL) { 39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "epsilon transition left at runtime\n"); 39015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -2; 39025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 39035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (value != NULL) { 39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegStrEqualWildcard(atom->valuep, value); 39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->neg) { 39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = !ret; 39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!compound) 39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret == 1) && (trans->counter >= 0)) { 39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegCounterPtr counter; 39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count; 39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count = exec->counts[trans->counter]; 39155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = &exec->comp->counters[trans->counter]; 39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (count >= counter->max) 39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 39185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) { 39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr to = exec->comp->states[trans->to]; 39225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 39245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is a multiple input sequence 39255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->state->nbTrans > exec->transno + 1) { 39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->inputStackNr <= 0) { 39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecSaveInputString(exec, value, data); 39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecSave(exec); 39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transcount = 1; 39335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 39345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Try to progress as much as possible on the input 39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 39375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->transcount == atom->max) { 39385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 39395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->index++; 39415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = exec->inputStack[exec->index].value; 39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = exec->inputStack[exec->index].data; 39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("value loaded: %s\n", value); 39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * End of input: stop here 39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 39505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value == NULL) { 39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->index --; 39525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->transcount >= atom->min) { 39555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int transno = exec->transno; 39565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr state = exec->state; 39575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The transition is acceptable save it 39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno = -1; /* trick */ 39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->state = to; 39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->inputStackNr <= 0) { 39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecSaveInputString(exec, value, data); 39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecSave(exec); 39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno = transno; 39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->state = state; 39695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlStrEqual(value, atom->valuep); 39715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transcount++; 39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (ret == 1); 39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->transcount < atom->min) 39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 39775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the last check failed but one transition was found 39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * possible, rollback 39795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 39805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret < 0) 39815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 39825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 0) { 39835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 1) { 39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec->callback != NULL) && (atom != NULL) && 39895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (data != NULL)) { 39905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->callback(exec->data, atom->valuep, 39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->data, data); 39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->state->nbTrans > exec->transno + 1) { 39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->inputStackNr <= 0) { 39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecSaveInputString(exec, value, data); 39965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecSave(exec); 39985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->counter >= 0) { 40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Increasing count %d\n", trans->counter); 40025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 40035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->counts[trans->counter]++; 40045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((trans->count >= 0) && 40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (trans->count < REGEXP_ALL_COUNTER)) { 40075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 40085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("resetting count %d on transition\n", 40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans->count); 40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->counts[trans->count] = 0; 40125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("entering state %d\n", trans->to); 40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 40165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec->comp->states[trans->to] != NULL) && 40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (exec->comp->states[trans->to]->type == 40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SINK_STATE)) { 40195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 40205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * entering a sink state, save the current state as error 40215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * state. 40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->errString != NULL) 40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec->errString); 40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->errString = xmlStrdup(value); 40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->errState = exec->state; 40275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(exec->errCounts, exec->counts, 40285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->comp->nbCounters * sizeof(int)); 40295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->state = exec->comp->states[trans->to]; 40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno = 0; 40325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->atom != NULL) { 40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->inputStack != NULL) { 40345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->index++; 40355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->index < exec->inputStackNr) { 40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = exec->inputStack[exec->index].value; 40375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = exec->inputStack[exec->index].data; 40385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 40395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("value loaded: %s\n", value); 40405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 40415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 40425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = NULL; 40435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = NULL; 40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 40455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("end of input\n"); 40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 40475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = NULL; 40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = NULL; 40515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("end of input\n"); 40535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto progress; 40575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ret < 0) { 40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -4; 40595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec->transno != 0) || (exec->state->nbTrans == 0)) { 40635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)rollback: 40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 40655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if we didn't yet rollback on the current input 40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * store the current state as the error state. 40675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((progress) && (exec->state != NULL) && 40695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (exec->state->type != XML_REGEXP_SINK_STATE)) { 40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress = 0; 40715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->errString != NULL) 40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exec->errString); 40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->errString = xmlStrdup(value); 40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->errState = exec->state; 40755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(exec->errCounts, exec->counts, 40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->comp->nbCounters * sizeof(int)); 40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Failed to find a way out 40815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 40825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->determinist = 0; 40835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecRollBack(exec); 40845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->status == 0) { 40855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = exec->inputStack[exec->index].value; 40865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = exec->inputStack[exec->index].data; 40875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_PUSH 40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("value loaded: %s\n", value); 40895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 40935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)progress: 40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) progress = 1; 40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->status == 0) { 40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(exec->state->type == XML_REGEXP_FINAL_STATE); 40995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_ERR 41015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->status < 0) { 41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testerr(exec); 41035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 41055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(exec->status); 41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 41075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 41095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegExecPushString: 41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context or NULL to indicate the end 41115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value: a string token input 41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data associated to the token to reuse in callbacks 41135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Push one input token in the execution context 41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 1 if the regexp reached a final state, 0 if non-final, and 41175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a negative value in case of error. 41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecPushString(xmlRegExecCtxtPtr exec, const xmlChar *value, 41215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *data) { 41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlRegExecPushStringInternal(exec, value, data, 0)); 41235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 41265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegExecPushString2: 41275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context or NULL to indicate the end 41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value: the first string token input 41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value2: the second string token input 41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data associated to the token to reuse in callbacks 41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Push one input token in the execution context 41335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 1 if the regexp reached a final state, 0 if non-final, and 41355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a negative value in case of error. 41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 41375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 41385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecPushString2(xmlRegExecCtxtPtr exec, const xmlChar *value, 41395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *value2, void *data) { 41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar buf[150]; 41415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lenn, lenp, ret; 41425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *str; 41435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec == NULL) 41455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 41465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->comp == NULL) 41475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 41485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->status != 0) 41495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(exec->status); 41505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value2 == NULL) 41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlRegExecPushString(exec, value, data)); 41535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lenn = strlen((char *) value2); 41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lenp = strlen((char *) value); 41565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (150 < lenn + lenp + 2) { 41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str == NULL) { 41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -1; 41615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 41625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 41645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str = buf; 41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&str[0], value, lenp); 41675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[lenp] = XML_REG_STRING_SEPARATOR; 41685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&str[lenp + 1], value2, lenn); 41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[lenn + lenp + 1] = 0; 41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->comp->compact != NULL) 41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegCompactPushString(exec, exec->comp, str, data); 41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegExecPushStringInternal(exec, str, data, 1); 41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str != buf) 41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(str); 41785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 41805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 41825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegExecGetValues: 41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context 41845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @err: error extraction or normal one 41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nbval: pointer to the number of accepted values IN/OUT 41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nbneg: return number of negative transitions 41875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @values: pointer to the array of acceptable values 41885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @terminal: return value if this was a terminal state 41895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extract informations from the regexp execution, internal routine to 41915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * implement xmlRegExecNextValues() and xmlRegExecErrInfo() 41925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 0 in case of success or -1 in case of error. 41945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 41955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 41965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecGetValues(xmlRegExecCtxtPtr exec, int err, 41975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *nbval, int *nbneg, 41985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar **values, int *terminal) { 41995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxval; 42005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nb = 0; 42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec == NULL) || (nbval == NULL) || (nbneg == NULL) || 42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (values == NULL) || (*nbval <= 0)) 42045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 42055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxval = *nbval; 42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *nbval = 0; 42085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *nbneg = 0; 42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec->comp != NULL) && (exec->comp->compact != NULL)) { 42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpPtr comp; 42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int target, i, state; 42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp = exec->comp; 42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err) { 42165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->errStateNo == -1) return(-1); 42175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = exec->errStateNo; 42185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = exec->index; 42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (terminal != NULL) { 42225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->compact[state * (comp->nbstrings + 1)] == 42235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_FINAL_STATE) 42245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *terminal = 1; 42255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 42265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *terminal = 0; 42275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;(i < comp->nbstrings) && (nb < maxval);i++) { 42295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target = comp->compact[state * (comp->nbstrings + 1) + i + 1]; 42305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((target > 0) && (target <= comp->nbstates) && 42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (comp->compact[(target - 1) * (comp->nbstrings + 1)] != 42325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SINK_STATE)) { 42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values[nb++] = comp->stringMap[i]; 42345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*nbval)++; 42355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;(i < comp->nbstrings) && (nb < maxval);i++) { 42385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target = comp->compact[state * (comp->nbstrings + 1) + i + 1]; 42395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((target > 0) && (target <= comp->nbstates) && 42405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (comp->compact[(target - 1) * (comp->nbstrings + 1)] == 42415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SINK_STATE)) { 42425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values[nb++] = comp->stringMap[i]; 42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*nbneg)++; 42445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 42475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int transno; 42485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegTransPtr trans; 42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom; 42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr state; 42515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (terminal != NULL) { 42535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->state->type == XML_REGEXP_FINAL_STATE) 42545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *terminal = 1; 42555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *terminal = 0; 42575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err) { 42605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->errState == NULL) return(-1); 42615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = exec->errState; 42625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 42635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->state == NULL) return(-1); 42645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = exec->state; 42655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (transno = 0; 42675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (transno < state->nbTrans) && (nb < maxval); 42685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transno++) { 42695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans = &state->trans[transno]; 42705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->to < 0) 42715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 42725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom = trans->atom; 42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((atom == NULL) || (atom->valuep == NULL)) 42745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 42755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->count == REGEXP_ALL_LAX_COUNTER) { 42765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* this should not be reached but ... */ 42775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TODO; 42785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (trans->count == REGEXP_ALL_COUNTER) { 42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* this should not be reached but ... */ 42805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TODO; 42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (trans->counter >= 0) { 42825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegCounterPtr counter = NULL; 42835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count; 42845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err) 42865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count = exec->errCounts[trans->counter]; 42875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 42885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count = exec->counts[trans->counter]; 42895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->comp != NULL) 42905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = &exec->comp->counters[trans->counter]; 42915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((counter == NULL) || (count < counter->max)) { 42925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->neg) 42935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values[nb++] = (xmlChar *) atom->valuep2; 42945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 42955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values[nb++] = (xmlChar *) atom->valuep; 42965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*nbval)++; 42975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 42995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec->comp->states[trans->to] != NULL) && 43005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (exec->comp->states[trans->to]->type != 43015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SINK_STATE)) { 43025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->neg) 43035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values[nb++] = (xmlChar *) atom->valuep2; 43045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 43055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values[nb++] = (xmlChar *) atom->valuep; 43065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*nbval)++; 43075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (transno = 0; 43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (transno < state->nbTrans) && (nb < maxval); 43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transno++) { 43135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans = &state->trans[transno]; 43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->to < 0) 43155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 43165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom = trans->atom; 43175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((atom == NULL) || (atom->valuep == NULL)) 43185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 43195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->count == REGEXP_ALL_LAX_COUNTER) { 43205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 43215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (trans->count == REGEXP_ALL_COUNTER) { 43225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 43235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (trans->counter >= 0) { 43245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 43255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 43265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec->comp->states[trans->to] != NULL) && 43275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (exec->comp->states[trans->to]->type == 43285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_SINK_STATE)) { 43295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom->neg) 43305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values[nb++] = (xmlChar *) atom->valuep2; 43315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 43325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values[nb++] = (xmlChar *) atom->valuep; 43335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*nbneg)++; 43345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 43395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 43405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 43425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegExecNextValues: 43435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context 43445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nbval: pointer to the number of accepted values IN/OUT 43455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nbneg: return number of negative transitions 43465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @values: pointer to the array of acceptable values 43475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @terminal: return value if this was a terminal state 43485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 43495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extract informations from the regexp execution, 43505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the parameter @values must point to an array of @nbval string pointers 43515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on return nbval will contain the number of possible strings in that 43525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * state and the @values array will be updated with them. The string values 43535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * returned will be freed with the @exec context and don't need to be 43545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * deallocated. 43555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 43565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 0 in case of success or -1 in case of error. 43575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 43585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 43595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecNextValues(xmlRegExecCtxtPtr exec, int *nbval, int *nbneg, 43605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar **values, int *terminal) { 43615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlRegExecGetValues(exec, 0, nbval, nbneg, values, terminal)); 43625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 43635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 43655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegExecErrInfo: 43665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exec: a regexp execution context generating an error 43675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @string: return value for the error string 43685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nbval: pointer to the number of accepted values IN/OUT 43695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nbneg: return number of negative transitions 43705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @values: pointer to the array of acceptable values 43715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @terminal: return value if this was a terminal state 43725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 43735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extract error informations from the regexp execution, the parameter 43745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @string will be updated with the value pushed and not accepted, 43755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the parameter @values must point to an array of @nbval string pointers 43765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on return nbval will contain the number of possible strings in that 43775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * state and the @values array will be updated with them. The string values 43785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * returned will be freed with the @exec context and don't need to be 43795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * deallocated. 43805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 43815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 0 in case of success or -1 in case of error. 43825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 43835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 43845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecErrInfo(xmlRegExecCtxtPtr exec, const xmlChar **string, 43855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *nbval, int *nbneg, xmlChar **values, int *terminal) { 43865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec == NULL) 43875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 43885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (string != NULL) { 43895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->status != 0) 43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *string = exec->errString; 43915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 43925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *string = NULL; 43935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlRegExecGetValues(exec, 1, nbval, nbneg, values, terminal)); 43955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 43965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_ERR 43985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void testerr(xmlRegExecCtxtPtr exec) { 43995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *string; 44005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *values[5]; 44015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nb = 5; 44025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbneg; 44035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int terminal; 44045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegExecErrInfo(exec, &string, &nb, &nbneg, &values[0], &terminal); 44055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 44065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 44075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 44095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegExecPushChar(xmlRegExecCtxtPtr exec, int UCS) { 44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegTransPtr trans; 44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom; 44135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret; 44145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int codepoint, len; 44155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec == NULL) 44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 44185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->status != 0) 44195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(exec->status); 44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((exec->status == 0) && 44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((exec->inputString[exec->index] != 0) || 44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (exec->state->type != XML_REGEXP_FINAL_STATE))) { 44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 44265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * End of input on non-terminal state, rollback, however we may 44275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * still have epsilon like transition for counted transitions 44285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on counters, in that case don't break too early. 44295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 44305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL)) 44315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 44325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transcount = 0; 44345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (;exec->transno < exec->state->nbTrans;exec->transno++) { 44355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans = &exec->state->trans[exec->transno]; 44365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->to < 0) 44375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 44385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom = trans->atom; 44395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 44405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->count >= 0) { 44415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count; 44425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegCounterPtr counter; 44435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 44455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A counted transition. 44465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 44475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count = exec->counts[trans->count]; 44495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = &exec->comp->counters[trans->count]; 44505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 44515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("testing count %d: val %d, min %d, max %d\n", 44525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans->count, count, counter->min, counter->max); 44535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 44545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = ((count >= counter->min) && (count <= counter->max)); 44555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (atom == NULL) { 44565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "epsilon transition left at runtime\n"); 44575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -2; 44585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 44595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (exec->inputString[exec->index] != 0) { 44605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len); 44615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegCheckCharacter(atom, codepoint); 44625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) { 44635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr to = exec->comp->states[trans->to]; 44645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 44665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is a multiple input sequence 44675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 44685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->state->nbTrans > exec->transno + 1) { 44695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecSave(exec); 44705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transcount = 1; 44725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 44735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 44745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Try to progress as much as possible on the input 44755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 44765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->transcount == atom->max) { 44775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 44785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->index += len; 44805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 44815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * End of input: stop here 44825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 44835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->inputString[exec->index] == 0) { 44845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->index -= len; 44855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 44865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->transcount >= atom->min) { 44885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int transno = exec->transno; 44895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr state = exec->state; 44905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 44925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The transition is acceptable save it 44935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 44945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno = -1; /* trick */ 44955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->state = to; 44965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecSave(exec); 44975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno = transno; 44985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->state = state; 44995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), 45015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len); 45025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegCheckCharacter(atom, codepoint); 45035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transcount++; 45045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (ret == 1); 45055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->transcount < atom->min) 45065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 45075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 45095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the last check failed but one transition was found 45105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * possible, rollback 45115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 45125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret < 0) 45135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 45145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 0) { 45155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 45165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 1) { 45205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec->state->nbTrans > exec->transno + 1) { 45215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecSave(exec); 45225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 45245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * restart count for expressions like this ((abc){2})* 45255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 45265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->count >= 0) { 45275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 45285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Reset count %d\n", trans->count); 45295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 45305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->counts[trans->count] = 0; 45315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->counter >= 0) { 45335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 45345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Increasing count %d\n", trans->counter); 45355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 45365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->counts[trans->counter]++; 45375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_EXEC 45395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("entering state %d\n", trans->to); 45405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 45415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->state = exec->comp->states[trans->to]; 45425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->transno = 0; 45435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans->atom != NULL) { 45445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->index += len; 45455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto progress; 45475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ret < 0) { 45485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->status = -4; 45495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 45505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exec->transno != 0) || (exec->state->nbTrans == 0)) { 45535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)rollback: 45545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 45555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Failed to find a way out 45565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 45575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec->determinist = 0; 45585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFARegExecRollBack(exec); 45595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)progress: 45615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 45625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 45645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 45655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 45665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 45675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parser for the Schemas Datatype Regular Expressions * 45685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#regexs * 45695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 45705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 45715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 45735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAIsChar: 45745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 45755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [10] Char ::= [^.\?*+()|#x5B#x5D] 45775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 45785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 45795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAIsChar(xmlRegParserCtxtPtr ctxt) { 45805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cur; 45815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 45825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR_SCHAR(ctxt->cur, len); 45845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((cur == '.') || (cur == '\\') || (cur == '?') || 45855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur == '*') || (cur == '+') || (cur == '(') || 45865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur == ')') || (cur == '|') || (cur == 0x5B) || 45875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur == 0x5D) || (cur == 0)) 45885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 45895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(cur); 45905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 45915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 45935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseCharProp: 45945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 45955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [27] charProp ::= IsCategory | IsBlock 45975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [28] IsCategory ::= Letters | Marks | Numbers | Punctuation | 45985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Separators | Symbols | Others 45995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [29] Letters ::= 'L' [ultmo]? 46005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [30] Marks ::= 'M' [nce]? 46015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [31] Numbers ::= 'N' [dlo]? 46025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [32] Punctuation ::= 'P' [cdseifo]? 46035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [33] Separators ::= 'Z' [slp]? 46045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [34] Symbols ::= 'S' [mcko]? 46055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [35] Others ::= 'C' [cfon]? 46065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [36] IsBlock ::= 'Is' [a-zA-Z0-9#x2D]+ 46075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 46085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 46095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) { 46105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cur; 46115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomType type = (xmlRegAtomType) 0; 46125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *blockName = NULL; 46135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 46155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == 'L') { 46165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 46185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == 'u') { 46195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_LETTER_UPPERCASE; 46215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'l') { 46225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_LETTER_LOWERCASE; 46245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 't') { 46255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_LETTER_TITLECASE; 46275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'm') { 46285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_LETTER_MODIFIER; 46305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'o') { 46315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_LETTER_OTHERS; 46335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 46345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_LETTER; 46355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'M') { 46375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 46395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == 'n') { 46405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* nonspacing */ 46425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_MARK_NONSPACING; 46435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'c') { 46445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* spacing combining */ 46465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_MARK_SPACECOMBINING; 46475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'e') { 46485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* enclosing */ 46505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_MARK_ENCLOSING; 46515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 46525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* all marks */ 46535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_MARK; 46545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'N') { 46565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 46585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == 'd') { 46595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* digital */ 46615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_NUMBER_DECIMAL; 46625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'l') { 46635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* letter */ 46655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_NUMBER_LETTER; 46665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'o') { 46675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* other */ 46695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_NUMBER_OTHERS; 46705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 46715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* all numbers */ 46725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_NUMBER; 46735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'P') { 46755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 46775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == 'c') { 46785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* connector */ 46805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_PUNCT_CONNECTOR; 46815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'd') { 46825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* dash */ 46845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_PUNCT_DASH; 46855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 's') { 46865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* open */ 46885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_PUNCT_OPEN; 46895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'e') { 46905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* close */ 46925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_PUNCT_CLOSE; 46935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'i') { 46945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* initial quote */ 46965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_PUNCT_INITQUOTE; 46975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'f') { 46985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 46995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* final quote */ 47005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_PUNCT_FINQUOTE; 47015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'o') { 47025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* other */ 47045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_PUNCT_OTHERS; 47055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 47065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* all punctuation */ 47075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_PUNCT; 47085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'Z') { 47105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 47125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == 's') { 47135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* space */ 47155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_SEPAR_SPACE; 47165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'l') { 47175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* line */ 47195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_SEPAR_LINE; 47205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'p') { 47215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* paragraph */ 47235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_SEPAR_PARA; 47245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 47255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* all separators */ 47265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_SEPAR; 47275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'S') { 47295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 47315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == 'm') { 47325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_SYMBOL_MATH; 47345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* math */ 47355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'c') { 47365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_SYMBOL_CURRENCY; 47385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* currency */ 47395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'k') { 47405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_SYMBOL_MODIFIER; 47425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* modifiers */ 47435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'o') { 47445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_SYMBOL_OTHERS; 47465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* other */ 47475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 47485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* all symbols */ 47495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_SYMBOL; 47505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'C') { 47525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 47545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == 'c') { 47555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* control */ 47575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_OTHER_CONTROL; 47585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'f') { 47595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* format */ 47615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_OTHER_FORMAT; 47625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'o') { 47635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* private use */ 47655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_OTHER_PRIVATE; 47665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'n') { 47675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* not assigned */ 47695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_OTHER_NA; 47705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 47715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* all others */ 47725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_OTHER; 47735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'I') { 47755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *start; 47765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 47785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur != 's') { 47795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("IsXXXX expected"); 47805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 47815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start = ctxt->cur; 47845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 47855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((cur >= 'a') && (cur <= 'z')) || 47865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((cur >= 'A') && (cur <= 'Z')) || 47875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((cur >= '0') && (cur <= '9')) || 47885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur == 0x2D)) { 47895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 47915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (((cur >= 'a') && (cur <= 'z')) || 47925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((cur >= 'A') && (cur <= 'Z')) || 47935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((cur >= '0') && (cur <= '9')) || 47945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur == 0x2D)) { 47955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 47965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 47975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_BLOCK_NAME; 48005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blockName = xmlStrndup(start, ctxt->cur - start); 48015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 48025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Unknown char property"); 48035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 48045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atom == NULL) { 48065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom = xmlRegNewAtom(ctxt, type); 48075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atom != NULL) 48085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->valuep = blockName; 48095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ctxt->atom->type == XML_REGEXP_RANGES) { 48105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 48115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 0, 0, blockName); 48125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 48145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 48165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseCharClassEsc: 48175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 48185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 48195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [23] charClassEsc ::= ( SingleCharEsc | MultiCharEsc | catEsc | complEsc ) 48205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [24] SingleCharEsc ::= '\' [nrt\|.?*+(){}#x2D#x5B#x5D#x5E] 48215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [25] catEsc ::= '\p{' charProp '}' 48225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [26] complEsc ::= '\P{' charProp '}' 48235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [37] MultiCharEsc ::= '.' | ('\' [sSiIcCdDwW]) 48245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 48255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 48265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseCharClassEsc(xmlRegParserCtxtPtr ctxt) { 48275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cur; 48285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '.') { 48305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atom == NULL) { 48315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_ANYCHAR); 48325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ctxt->atom->type == XML_REGEXP_RANGES) { 48335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 48345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_ANYCHAR, 0, 0, NULL); 48355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 48375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 48385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != '\\') { 48405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Escaped sequence: expecting \\"); 48415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 48425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 48445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 48455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == 'p') { 48465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 48475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != '{') { 48485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Expecting '{'"); 48495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 48505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 48525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParseCharProp(ctxt); 48535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != '}') { 48545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Expecting '}'"); 48555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 48565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 48585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cur == 'P') { 48595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 48605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != '{') { 48615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Expecting '{'"); 48625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 48635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 48655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParseCharProp(ctxt); 48665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->neg = 1; 48675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != '}') { 48685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Expecting '}'"); 48695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 48705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 48725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((cur == 'n') || (cur == 'r') || (cur == 't') || (cur == '\\') || 48735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur == '|') || (cur == '.') || (cur == '?') || (cur == '*') || 48745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur == '+') || (cur == '(') || (cur == ')') || (cur == '{') || 48755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur == '}') || (cur == 0x2D) || (cur == 0x5B) || (cur == 0x5D) || 48765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur == 0x5E)) { 48775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atom == NULL) { 48785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL); 48795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atom != NULL) { 48805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (cur) { 48815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'n': 48825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->codepoint = '\n'; 48835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 48845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'r': 48855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->codepoint = '\r'; 48865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 48875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 't': 48885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->codepoint = '\t'; 48895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 48905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 48915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->codepoint = cur; 48925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ctxt->atom->type == XML_REGEXP_RANGES) { 48955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (cur) { 48965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'n': 48975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = '\n'; 48985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 48995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'r': 49005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = '\r'; 49015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 't': 49035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = '\t'; 49045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 49075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_CHARVAL, cur, cur, NULL); 49085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 49105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((cur == 's') || (cur == 'S') || (cur == 'i') || (cur == 'I') || 49115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur == 'c') || (cur == 'C') || (cur == 'd') || (cur == 'D') || 49125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur == 'w') || (cur == 'W')) { 49135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomType type = XML_REGEXP_ANYSPACE; 49145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (cur) { 49165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 's': 49175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_ANYSPACE; 49185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'S': 49205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_NOTSPACE; 49215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'i': 49235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_INITNAME; 49245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'I': 49265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_NOTINITNAME; 49275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'c': 49295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_NAMECHAR; 49305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'C': 49325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_NOTNAMECHAR; 49335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'd': 49355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_DECIMAL; 49365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'D': 49385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_NOTDECIMAL; 49395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'w': 49415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_REALCHAR; 49425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'W': 49445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = XML_REGEXP_NOTREALCHAR; 49455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 49485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atom == NULL) { 49495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom = xmlRegNewAtom(ctxt, type); 49505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ctxt->atom->type == XML_REGEXP_RANGES) { 49515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 49525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 0, 0, NULL); 49535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 49555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Wrong escape sequence, misuse of character '\\'"); 49565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 49585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 49605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseCharRange: 49615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 49625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 49635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [17] charRange ::= seRange | XmlCharRef | XmlCharIncDash 49645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [18] seRange ::= charOrEsc '-' charOrEsc 49655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [20] charOrEsc ::= XmlChar | SingleCharEsc 49665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [21] XmlChar ::= [^\#x2D#x5B#x5D] 49675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [22] XmlCharIncDash ::= [^\#x5B#x5D] 49685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 49695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 49705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseCharRange(xmlRegParserCtxtPtr ctxt) { 49715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cur, len; 49725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start = -1; 49735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int end = -1; 49745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '\0') { 49765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Expecting ']'"); 49775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 49785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 49815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == '\\') { 49825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 49835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 49845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (cur) { 49855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'n': start = 0xA; break; 49865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'r': start = 0xD; break; 49875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 't': start = 0x9; break; 49885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '\\': case '|': case '.': case '-': case '^': case '?': 49895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '*': case '+': case '{': case '}': case '(': case ')': 49905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '[': case ']': 49915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start = cur; break; 49925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 49935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Invalid escape value"); 49945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 49955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = start; 49975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = 1; 49985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((cur != 0x5B) && (cur != 0x5D)) { 49995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = start = CUR_SCHAR(ctxt->cur, len); 50005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 50015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Expecting a char range"); 50025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 50035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 50045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 50055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Since we are "inside" a range, we can assume ctxt->cur is past 50065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the start of ctxt->string, and PREV should be safe 50075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 50085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((start == '-') && (NXT(1) != ']') && (PREV != '[') && (PREV != '^')) { 50095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXTL(len); 50105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 50115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 50125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXTL(len); 50135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 50145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((cur != '-') || (NXT(1) == ']')) { 50155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 50165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_CHARVAL, start, end, NULL); 50175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 50185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 50195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 50205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 50215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == '\\') { 50225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 50235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 50245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (cur) { 50255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'n': end = 0xA; break; 50265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 'r': end = 0xD; break; 50275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 't': end = 0x9; break; 50285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '\\': case '|': case '.': case '-': case '^': case '?': 50295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '*': case '+': case '{': case '}': case '(': case ')': 50305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '[': case ']': 50315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = cur; break; 50325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 50335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Invalid escape value"); 50345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 50355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 50365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = 1; 50375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((cur != 0x5B) && (cur != 0x5D)) { 50385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = CUR_SCHAR(ctxt->cur, len); 50395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 50405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Expecting the end of a char range"); 50415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 50425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 50435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXTL(len); 50445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO check that the values are acceptable character ranges for XML */ 50455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (end < start) { 50465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("End of range is before start of range"); 50475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 50485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, 50495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_REGEXP_CHARVAL, start, end, NULL); 50505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 50515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 50525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 50535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 50555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParsePosCharGroup: 50565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 50575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 50585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [14] posCharGroup ::= ( charRange | charClassEsc )+ 50595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 50605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 50615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParsePosCharGroup(xmlRegParserCtxtPtr ctxt) { 50625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 50635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '\\') { 50645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParseCharClassEsc(ctxt); 50655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 50665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParseCharRange(ctxt); 50675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 50685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while ((CUR != ']') && (CUR != '^') && (CUR != '-') && 50695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (CUR != 0) && (ctxt->error == 0)); 50705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 50715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 50735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseCharGroup: 50745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 50755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 50765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [13] charGroup ::= posCharGroup | negCharGroup | charClassSub 50775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [15] negCharGroup ::= '^' posCharGroup 50785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [16] charClassSub ::= ( posCharGroup | negCharGroup ) '-' charClassExpr 50795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [12] charClassExpr ::= '[' charGroup ']' 50805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 50815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 50825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseCharGroup(xmlRegParserCtxtPtr ctxt) { 50835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int n = ctxt->neg; 50845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((CUR != ']') && (ctxt->error == 0)) { 50855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '^') { 50865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int neg = ctxt->neg; 50875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 50895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->neg = !ctxt->neg; 50905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParsePosCharGroup(ctxt); 50915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->neg = neg; 50925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((CUR == '-') && (NXT(1) == '[')) { 50935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int neg = ctxt->neg; 50945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->neg = 2; 50955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; /* eat the '-' */ 50965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; /* eat the '[' */ 50975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParseCharGroup(ctxt); 50985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == ']') { 50995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 51005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 51015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("charClassExpr: ']' expected"); 51025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 51035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 51045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->neg = neg; 51055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 51065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR != ']') { 51075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParsePosCharGroup(ctxt); 51085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 51095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 51105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->neg = n; 51115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 51125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 51145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseCharClass: 51155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 51165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 51175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [11] charClass ::= charClassEsc | charClassExpr 51185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [12] charClassExpr ::= '[' charGroup ']' 51195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 51205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 51215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseCharClass(xmlRegParserCtxtPtr ctxt) { 51225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '[') { 51235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 51245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_RANGES); 51255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atom == NULL) 51265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 51275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParseCharGroup(ctxt); 51285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == ']') { 51295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 51305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 51315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("xmlFAParseCharClass: ']' expected"); 51325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 51335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 51345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParseCharClassEsc(ctxt); 51355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 51365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 51375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 51395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseQuantExact: 51405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 51415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 51425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [8] QuantExact ::= [0-9]+ 51435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 51445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 0 if success or -1 in case of error 51455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 51465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 51475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseQuantExact(xmlRegParserCtxtPtr ctxt) { 51485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 0; 51495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ok = 0; 51505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((CUR >= '0') && (CUR <= '9')) { 51525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = ret * 10 + (CUR - '0'); 51535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ok = 1; 51545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 51555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 51565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ok != 1) { 51575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 51585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 51595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 51605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 51615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 51635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseQuantifier: 51645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 51655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 51665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [4] quantifier ::= [?*+] | ( '{' quantity '}' ) 51675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [5] quantity ::= quantRange | quantMin | QuantExact 51685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [6] quantRange ::= QuantExact ',' QuantExact 51695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [7] quantMin ::= QuantExact ',' 51705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [8] QuantExact ::= [0-9]+ 51715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 51725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 51735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseQuantifier(xmlRegParserCtxtPtr ctxt) { 51745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cur; 51755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = CUR; 51775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((cur == '?') || (cur == '*') || (cur == '+')) { 51785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atom != NULL) { 51795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == '?') 51805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->quant = XML_REGEXP_QUANT_OPT; 51815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (cur == '*') 51825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->quant = XML_REGEXP_QUANT_MULT; 51835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (cur == '+') 51845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->quant = XML_REGEXP_QUANT_PLUS; 51855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 51865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 51875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 51885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 51895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == '{') { 51905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min = 0, max = 0; 51915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 51935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = xmlFAParseQuantExact(ctxt); 51945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur >= 0) 51955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = cur; 51965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == ',') { 51975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 51985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '}') 51995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = INT_MAX; 52005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 52015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = xmlFAParseQuantExact(ctxt); 52025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur >= 0) 52035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = cur; 52045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 52055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Improper quantifier"); 52065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 52075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 52085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 52095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '}') { 52105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 52115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 52125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("Unterminated quantifier"); 52135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 52145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (max == 0) 52155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = min; 52165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atom != NULL) { 52175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->quant = XML_REGEXP_QUANT_RANGE; 52185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->min = min; 52195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->max = max; 52205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 52215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 52225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 52235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 52245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 52255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 52275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseAtom: 52285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 52295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 52305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [9] atom ::= Char | charClass | ( '(' regExp ')' ) 52315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 52325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 52335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseAtom(xmlRegParserCtxtPtr ctxt) { 52345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int codepoint, len; 52355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codepoint = xmlFAIsChar(ctxt); 52375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (codepoint > 0) { 52385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL); 52395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atom == NULL) 52405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 52415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codepoint = CUR_SCHAR(ctxt->cur, len); 52425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->codepoint = codepoint; 52435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXTL(len); 52445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 52455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == '|') { 52465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 52475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == 0) { 52485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 52495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == ')') { 52505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 52515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == '(') { 52525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr start, oldend, start0; 52535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 52555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 52565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this extra Epsilon transition is needed if we count with 0 allowed 52575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * unfortunately this can't be known at that point 52585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 52595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, NULL); 52605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start0 = ctxt->state; 52615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, NULL); 52625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start = ctxt->state; 52635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldend = ctxt->end; 52645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->end = NULL; 52655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom = NULL; 52665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParseRegExp(ctxt, 0); 52675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == ')') { 52685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 52695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 52705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("xmlFAParseAtom: expecting ')'"); 52715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 52725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_SUBREG); 52735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atom == NULL) 52745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 52755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->start = start; 52765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->start0 = start0; 52775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom->stop = ctxt->state; 52785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->end = oldend; 52795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 52805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((CUR == '[') || (CUR == '\\') || (CUR == '.')) { 52815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParseCharClass(ctxt); 52825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 52835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 52845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 52855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 52865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 52885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParsePiece: 52895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 52905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 52915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [3] piece ::= atom quantifier? 52925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 52935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 52945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParsePiece(xmlRegParserCtxtPtr ctxt) { 52955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret; 52965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom = NULL; 52985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlFAParseAtom(ctxt); 52995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 0) 53005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 53015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->atom == NULL) { 53025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("internal: no atom generated"); 53035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 53045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParseQuantifier(ctxt); 53055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 53065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 53075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 53095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseBranch: 53105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 53115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: optional target to the end of the branch 53125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 53135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to is used to optimize by removing duplicate path in automata 53145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in expressions like (a|b)(c|d) 53155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 53165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [2] branch ::= piece* 53175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 53185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 53195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) { 53205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr previous; 53215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret; 53225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous = ctxt->state; 53245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlFAParsePiece(ctxt); 53255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret != 0) { 53265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlFAGenerateTransitions(ctxt, previous, 53275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0) 53285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 53295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous = ctxt->state; 53305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom = NULL; 53315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 53325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((ret != 0) && (ctxt->error == 0)) { 53335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlFAParsePiece(ctxt); 53345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret != 0) { 53355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlFAGenerateTransitions(ctxt, previous, 53365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0) 53375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 53385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous = ctxt->state; 53395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->atom = NULL; 53405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 53415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 53425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 53435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 53445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 53465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFAParseRegExp: 53475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a regexp parser context 53485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @top: is this the top-level expression ? 53495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 53505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [1] regExp ::= branch ( '|' branch )* 53515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 53525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 53535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) { 53545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePtr start, end; 53555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if not top start should have been generated by an epsilon trans */ 53575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start = ctxt->state; 53585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->end = NULL; 53595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParseBranch(ctxt, NULL); 53605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (top) { 53615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_REGEXP_GRAPH 53625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("State %d is final\n", ctxt->state->no); 53635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 53645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state->type = XML_REGEXP_FINAL_STATE; 53655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 53665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != '|') { 53675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->end = ctxt->state; 53685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 53695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 53705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = ctxt->state; 53715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((CUR == '|') && (ctxt->error == 0)) { 53725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 53735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = start; 53745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->end = NULL; 53755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParseBranch(ctxt, end); 53765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 53775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!top) { 53785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = end; 53795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->end = end; 53805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 53815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 53825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 53845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 53855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The basic API * 53865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 53875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 53885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 53905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegexpPrint: 53915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @output: the file for the output debug 53925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @regexp: the compiled regexp 53935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 53945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Print the content of the compiled regular expression 53955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 53965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 53975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpPrint(FILE *output, xmlRegexpPtr regexp) { 53985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 53995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (output == NULL) 54015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 54025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, " regexp: "); 54035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (regexp == NULL) { 54045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "NULL\n"); 54055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 54065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 54075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "'%s' ", regexp->string); 54085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "\n"); 54095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "%d atoms:\n", regexp->nbAtoms); 54105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < regexp->nbAtoms; i++) { 54115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, " %02d ", i); 54125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegPrintAtom(output, regexp->atoms[i]); 54135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 54145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "%d states:", regexp->nbStates); 54155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "\n"); 54165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < regexp->nbStates; i++) { 54175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegPrintState(output, regexp->states[i]); 54185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 54195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, "%d counters:\n", regexp->nbCounters); 54205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < regexp->nbCounters; i++) { 54215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(output, " %d: min %d max %d\n", i, regexp->counters[i].min, 54225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regexp->counters[i].max); 54235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 54245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 54255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 54275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegexpCompile: 54285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @regexp: a regular expression string 54295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 54305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parses a regular expression conforming to XML Schemas Part 2 Datatype 54315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Appendix F and builds an automata suitable for testing strings against 54325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * that regular expression 54335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 54345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the compiled expression or NULL in case of error 54355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 54365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpPtr 54375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpCompile(const xmlChar *regexp) { 54385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpPtr ret; 54395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegParserCtxtPtr ctxt; 54405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt = xmlRegNewParserCtxt(regexp); 54425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 54435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 54445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* initialize the parser */ 54465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->end = NULL; 54475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->start = ctxt->state = xmlRegNewState(ctxt); 54485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(ctxt, ctxt->start); 54495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* parse the expression building an automata */ 54515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAParseRegExp(ctxt, 1); 54525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != 0) { 54535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR("xmlFAParseRegExp: extra characters"); 54545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 54555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->error != 0) { 54565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeParserCtxt(ctxt); 54575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 54585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 54595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->end = ctxt->state; 54605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->start->type = XML_REGEXP_START_STATE; 54615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->end->type = XML_REGEXP_FINAL_STATE; 54625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* remove the Epsilon except for counted transitions */ 54645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAEliminateEpsilonTransitions(ctxt); 54655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->error != 0) { 54685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeParserCtxt(ctxt); 54695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 54705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 54715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegEpxFromParse(ctxt); 54725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeParserCtxt(ctxt); 54735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 54745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 54755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 54775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegexpExec: 54785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: the compiled regular expression 54795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @content: the value to check against the regular expression 54805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 54815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check if the regular expression generates the value 54825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 54835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if it matches, 0 if not and a negative value in case of error 54845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 54855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 54865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpExec(xmlRegexpPtr comp, const xmlChar *content) { 54875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((comp == NULL) || (content == NULL)) 54885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 54895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlFARegExec(comp, content)); 54905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 54915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 54935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegexpIsDeterminist: 54945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: the compiled regular expression 54955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 54965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check if the regular expression is determinist 54975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 54985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if it yes, 0 if not and a negative value in case of error 54995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 55005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 55015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpIsDeterminist(xmlRegexpPtr comp) { 55025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataPtr am; 55035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret; 55045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp == NULL) 55065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 55075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->determinist != -1) 55085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(comp->determinist); 55095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am = xmlNewAutomata(); 55115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (am->states != NULL) { 55125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 55135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < am->nbStates;i++) 55155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeState(am->states[i]); 55165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(am->states); 55175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 55185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->nbAtoms = comp->nbAtoms; 55195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->atoms = comp->atoms; 55205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->nbStates = comp->nbStates; 55215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->states = comp->states; 55225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->determinist = -1; 55235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->flags = comp->flags; 55245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlFAComputesDeterminism(am); 55255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->atoms = NULL; 55265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->states = NULL; 55275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeAutomata(am); 55285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->determinist = ret; 55295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 55305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 55315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 55335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlRegFreeRegexp: 55345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @regexp: the regexp 55355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free a regexp 55375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 55385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 55395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegFreeRegexp(xmlRegexpPtr regexp) { 55405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 55415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (regexp == NULL) 55425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 55435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (regexp->string != NULL) 55455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(regexp->string); 55465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (regexp->states != NULL) { 55475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < regexp->nbStates;i++) 55485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeState(regexp->states[i]); 55495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(regexp->states); 55505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 55515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (regexp->atoms != NULL) { 55525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < regexp->nbAtoms;i++) 55535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeAtom(regexp->atoms[i]); 55545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(regexp->atoms); 55555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 55565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (regexp->counters != NULL) 55575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(regexp->counters); 55585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (regexp->compact != NULL) 55595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(regexp->compact); 55605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (regexp->transdata != NULL) 55615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(regexp->transdata); 55625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (regexp->stringMap != NULL) { 55635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < regexp->nbstrings;i++) 55645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(regexp->stringMap[i]); 55655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(regexp->stringMap); 55665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 55675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(regexp); 55695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 55705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_AUTOMATA_ENABLED 55725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 55735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 55745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Automata interface * 55755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 55765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 55775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 55795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNewAutomata: 55805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new automata 55825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new object or NULL in case of failure 55845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 55855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataPtr 55865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNewAutomata(void) { 55875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataPtr ctxt; 55885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt = xmlRegNewParserCtxt(NULL); 55905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 55915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 55925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* initialize the parser */ 55945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->end = NULL; 55955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->start = ctxt->state = xmlRegNewState(ctxt); 55965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->start == NULL) { 55975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeAutomata(ctxt); 55985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 55995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 56005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->start->type = XML_REGEXP_START_STATE; 56015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlRegStatePush(ctxt, ctxt->start) < 0) { 56025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeState(ctxt->start); 56035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeAutomata(ctxt); 56045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 56055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 56065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->flags = 0; 56075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ctxt); 56095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 56105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 56125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlFreeAutomata: 56135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 56145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 56155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free an automata 56165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 56175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 56185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlFreeAutomata(xmlAutomataPtr am) { 56195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (am == NULL) 56205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 56215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeParserCtxt(am); 56225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 56235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 56255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataSetFlags: 56265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 56275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @flags: a set of internal flags 56285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 56295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Set some flags on the automata 56305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 56315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 56325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataSetFlags(xmlAutomataPtr am, int flags) { 56335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (am == NULL) 56345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 56355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->flags |= flags; 56365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 56375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 56395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataGetInitState: 56405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 56415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 56425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Initial state lookup 56435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 56445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the initial state of the automata 56455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 56465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr 56475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataGetInitState(xmlAutomataPtr am) { 56485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (am == NULL) 56495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 56505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(am->start); 56515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 56525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 56545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataSetFinalState: 56555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 56565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @state: a state in this automata 56575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 56585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Makes that state a final state 56595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 56605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 0 or -1 in case of error 56615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 56625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 56635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataSetFinalState(xmlAutomataPtr am, xmlAutomataStatePtr state) { 56645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((am == NULL) || (state == NULL)) 56655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 56665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->type = XML_REGEXP_FINAL_STATE; 56675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 56685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 56695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 56715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewTransition: 56725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 56735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition 56745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL 56755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the input string associated to that transition 56765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data passed to the callback function if the transition is activated 56775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 56785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata 56795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state 56805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by the value of @token 56815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 56825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error 56835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 56845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr 56855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewTransition(xmlAutomataPtr am, xmlAutomataStatePtr from, 56865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataStatePtr to, const xmlChar *token, 56875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *data) { 56885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom; 56895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((am == NULL) || (from == NULL) || (token == NULL)) 56915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 56925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 56935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom == NULL) 56945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 56955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->data = data; 56965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom == NULL) 56975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 56985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->valuep = xmlStrdup(token); 56995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlFAGenerateTransitions(am, from, to, atom) < 0) { 57015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeAtom(atom); 57025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 57035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 57045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) 57055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(am->state); 57065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(to); 57075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 57085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 57105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewTransition2: 57115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 57125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition 57135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL 57145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the first input string associated to that transition 57155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token2: the second input string associated to that transition 57165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data passed to the callback function if the transition is activated 57175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 57185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata 57195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state 57205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by the value of @token 57215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 57225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error 57235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 57245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr 57255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewTransition2(xmlAutomataPtr am, xmlAutomataStatePtr from, 57265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataStatePtr to, const xmlChar *token, 57275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *token2, void *data) { 57285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom; 57295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((am == NULL) || (from == NULL) || (token == NULL)) 57315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 57325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 57335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom == NULL) 57345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 57355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->data = data; 57365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((token2 == NULL) || (*token2 == 0)) { 57375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->valuep = xmlStrdup(token); 57385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 57395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lenn, lenp; 57405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *str; 57415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lenn = strlen((char *) token2); 57435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lenp = strlen((char *) token); 57445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 57465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str == NULL) { 57475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeAtom(atom); 57485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 57495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 57505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&str[0], token, lenp); 57515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[lenp] = '|'; 57525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&str[lenp + 1], token2, lenn); 57535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[lenn + lenp + 1] = 0; 57545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->valuep = str; 57565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 57575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlFAGenerateTransitions(am, from, to, atom) < 0) { 57595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeAtom(atom); 57605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 57615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 57625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) 57635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(am->state); 57645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(to); 57655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 57665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 57685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewNegTrans: 57695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 57705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition 57715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL 57725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the first input string associated to that transition 57735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token2: the second input string associated to that transition 57745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data passed to the callback function if the transition is activated 57755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 57765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata 57775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state 57785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by any value except (@token,@token2) 57795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note that if @token2 is not NULL, then (X, NULL) won't match to follow 57805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # the semantic of XSD ##other 57815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 57825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error 57835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 57845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr 57855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewNegTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 57865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataStatePtr to, const xmlChar *token, 57875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *token2, void *data) { 57885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom; 57895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar err_msg[200]; 57905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((am == NULL) || (from == NULL) || (token == NULL)) 57925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 57935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 57945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom == NULL) 57955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 57965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->data = data; 57975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->neg = 1; 57985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((token2 == NULL) || (*token2 == 0)) { 57995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->valuep = xmlStrdup(token); 58005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 58015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lenn, lenp; 58025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *str; 58035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lenn = strlen((char *) token2); 58055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lenp = strlen((char *) token); 58065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 58085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str == NULL) { 58095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeAtom(atom); 58105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 58115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 58125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&str[0], token, lenp); 58135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[lenp] = '|'; 58145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&str[lenp + 1], token2, lenn); 58155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[lenn + lenp + 1] = 0; 58165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->valuep = str; 58185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 58195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf((char *) err_msg, 199, "not %s", (const char *) atom->valuep); 58205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err_msg[199] = 0; 58215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->valuep2 = xmlStrdup(err_msg); 58225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlFAGenerateTransitions(am, from, to, atom) < 0) { 58245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeAtom(atom); 58255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 58265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 58275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->negs++; 58285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) 58295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(am->state); 58305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(to); 58315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 58325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 58345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewCountTrans2: 58355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 58365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition 58375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL 58385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the input string associated to that transition 58395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token2: the second input string associated to that transition 58405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @min: the minimum successive occurences of token 58415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @max: the maximum successive occurences of token 58425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data associated to the transition 58435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 58445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata 58455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state 58465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by a succession of input of value @token and @token2 and 58475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * whose number is between @min and @max 58485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 58495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error 58505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 58515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr 58525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, 58535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataStatePtr to, const xmlChar *token, 58545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *token2, 58555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min, int max, void *data) { 58565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom; 58575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int counter; 58585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((am == NULL) || (from == NULL) || (token == NULL)) 58605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 58615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min < 0) 58625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 58635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((max < min) || (max < 1)) 58645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 58655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 58665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom == NULL) 58675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 58685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((token2 == NULL) || (*token2 == 0)) { 58695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->valuep = xmlStrdup(token); 58705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 58715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lenn, lenp; 58725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *str; 58735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lenn = strlen((char *) token2); 58755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lenp = strlen((char *) token); 58765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 58785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str == NULL) { 58795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeAtom(atom); 58805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 58815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 58825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&str[0], token, lenp); 58835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[lenp] = '|'; 58845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&str[lenp + 1], token2, lenn); 58855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[lenn + lenp + 1] = 0; 58865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->valuep = str; 58885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 58895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->data = data; 58905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min == 0) 58915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->min = 1; 58925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 58935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->min = min; 58945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->max = max; 58955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 58975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * associate a counter to the transition. 58985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 58995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = xmlRegGetCounter(am); 59005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->counters[counter].min = min; 59015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->counters[counter].max = max; 59025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* xmlFAGenerateTransitions(am, from, to, atom); */ 59045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) { 59055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = xmlRegNewState(am); 59065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(am, to); 59075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 59085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(am, from, atom, to, counter, -1); 59095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPush(am, atom); 59105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->state = to; 59115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) 59135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = am->state; 59145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) 59155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 59165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min == 0) 59175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(am, from, to); 59185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(to); 59195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 59205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 59225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewCountTrans: 59235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 59245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition 59255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL 59265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the input string associated to that transition 59275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @min: the minimum successive occurences of token 59285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @max: the maximum successive occurences of token 59295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data associated to the transition 59305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 59315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata 59325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state 59335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by a succession of input of value @token and whose number 59345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is between @min and @max 59355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 59365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error 59375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 59385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr 59395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 59405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataStatePtr to, const xmlChar *token, 59415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min, int max, void *data) { 59425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom; 59435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int counter; 59445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((am == NULL) || (from == NULL) || (token == NULL)) 59465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 59475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min < 0) 59485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 59495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((max < min) || (max < 1)) 59505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 59515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 59525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom == NULL) 59535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 59545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->valuep = xmlStrdup(token); 59555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->data = data; 59565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min == 0) 59575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->min = 1; 59585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 59595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->min = min; 59605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->max = max; 59615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 59635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * associate a counter to the transition. 59645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 59655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = xmlRegGetCounter(am); 59665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->counters[counter].min = min; 59675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->counters[counter].max = max; 59685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* xmlFAGenerateTransitions(am, from, to, atom); */ 59705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) { 59715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = xmlRegNewState(am); 59725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(am, to); 59735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 59745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(am, from, atom, to, counter, -1); 59755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPush(am, atom); 59765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->state = to; 59775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) 59795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = am->state; 59805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) 59815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 59825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min == 0) 59835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(am, from, to); 59845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(to); 59855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 59865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 59885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewOnceTrans2: 59895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 59905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition 59915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL 59925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the input string associated to that transition 59935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token2: the second input string associated to that transition 59945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @min: the minimum successive occurences of token 59955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @max: the maximum successive occurences of token 59965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data associated to the transition 59975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 59985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata 59995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state 60005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by a succession of input of value @token and @token2 and whose 60015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * number is between @min and @max, moreover that transition can only be 60025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * crossed once. 60035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 60045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error 60055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 60065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr 60075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, 60085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataStatePtr to, const xmlChar *token, 60095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *token2, 60105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min, int max, void *data) { 60115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom; 60125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int counter; 60135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((am == NULL) || (from == NULL) || (token == NULL)) 60155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 60165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min < 1) 60175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 60185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((max < min) || (max < 1)) 60195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 60205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 60215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom == NULL) 60225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 60235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((token2 == NULL) || (*token2 == 0)) { 60245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->valuep = xmlStrdup(token); 60255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 60265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lenn, lenp; 60275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *str; 60285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lenn = strlen((char *) token2); 60305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lenp = strlen((char *) token); 60315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); 60335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str == NULL) { 60345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegFreeAtom(atom); 60355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 60365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 60375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&str[0], token, lenp); 60385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[lenp] = '|'; 60395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&str[lenp + 1], token2, lenn); 60405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[lenn + lenp + 1] = 0; 60415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->valuep = str; 60435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 60445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->data = data; 60455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->quant = XML_REGEXP_QUANT_ONCEONLY; 60465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->min = min; 60475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->max = max; 60485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 60495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * associate a counter to the transition. 60505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 60515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = xmlRegGetCounter(am); 60525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->counters[counter].min = 1; 60535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->counters[counter].max = 1; 60545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* xmlFAGenerateTransitions(am, from, to, atom); */ 60565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) { 60575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = xmlRegNewState(am); 60585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(am, to); 60595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 60605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(am, from, atom, to, counter, -1); 60615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPush(am, atom); 60625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->state = to; 60635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(to); 60645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 60655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 60695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewOnceTrans: 60705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 60715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition 60725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL 60735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: the input string associated to that transition 60745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @min: the minimum successive occurences of token 60755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @max: the maximum successive occurences of token 60765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: data associated to the transition 60775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 60785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata 60795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a transition from the @from state to the target state 60805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * activated by a succession of input of value @token and whose number 60815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is between @min and @max, moreover that transition can only be crossed 60825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * once. 60835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 60845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error 60855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 60865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr 60875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 60885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataStatePtr to, const xmlChar *token, 60895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min, int max, void *data) { 60905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPtr atom; 60915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int counter; 60925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((am == NULL) || (from == NULL) || (token == NULL)) 60945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 60955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min < 1) 60965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 60975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((max < min) || (max < 1)) 60985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 60995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom = xmlRegNewAtom(am, XML_REGEXP_STRING); 61005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (atom == NULL) 61015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 61025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->valuep = xmlStrdup(token); 61035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->data = data; 61045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->quant = XML_REGEXP_QUANT_ONCEONLY; 61055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->min = min; 61065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) atom->max = max; 61075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 61085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * associate a counter to the transition. 61095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 61105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter = xmlRegGetCounter(am); 61115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->counters[counter].min = 1; 61125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->counters[counter].max = 1; 61135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 61145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* xmlFAGenerateTransitions(am, from, to, atom); */ 61155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) { 61165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = xmlRegNewState(am); 61175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(am, to); 61185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 61195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStateAddTrans(am, from, atom, to, counter, -1); 61205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegAtomPush(am, atom); 61215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->state = to; 61225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(to); 61235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 61245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 61255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 61265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewState: 61275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 61285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 61295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new disconnected state in the automata 61305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 61315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new state or NULL in case of error 61325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 61335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr 61345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewState(xmlAutomataPtr am) { 61355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataStatePtr to; 61365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 61375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (am == NULL) 61385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 61395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to = xmlRegNewState(am); 61405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegStatePush(am, to); 61415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(to); 61425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 61435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 61445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 61455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewEpsilon: 61465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 61475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition 61485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL 61495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 61505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata 61515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds an epsilon transition from the @from state to the 61525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * target state 61535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 61545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error 61555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 61565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr 61575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewEpsilon(xmlAutomataPtr am, xmlAutomataStatePtr from, 61585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataStatePtr to) { 61595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((am == NULL) || (from == NULL)) 61605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 61615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateEpsilonTransition(am, from, to); 61625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) 61635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(am->state); 61645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(to); 61655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 61665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 61675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 61685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewAllTrans: 61695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 61705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition 61715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL 61725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @lax: allow to transition if not all all transitions have been activated 61735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 61745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata 61755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds a an ALL transition from the @from state to the 61765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * target state. That transition is an epsilon transition allowed only when 61775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all transitions from the @from node have been activated. 61785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 61795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error 61805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 61815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr 61825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewAllTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 61835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataStatePtr to, int lax) { 61845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((am == NULL) || (from == NULL)) 61855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 61865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateAllTransition(am, from, to, lax); 61875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) 61885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(am->state); 61895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(to); 61905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 61915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 61925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 61935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewCounter: 61945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 61955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @min: the minimal value on the counter 61965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @max: the maximal value on the counter 61975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 61985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new counter 61995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 62005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the counter number or -1 in case of error 62015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 62025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 62035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewCounter(xmlAutomataPtr am, int min, int max) { 62045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret; 62055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (am == NULL) 62075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 62085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegGetCounter(am); 62105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret < 0) 62115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 62125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->counters[ret].min = min; 62135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) am->counters[ret].max = max; 62145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 62155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 62165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 62185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewCountedTrans: 62195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 62205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition 62215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL 62225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @counter: the counter associated to that transition 62235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 62245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata 62255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds an epsilon transition from the @from state to the target state 62265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * which will increment the counter provided 62275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 62285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error 62295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 62305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr 62315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewCountedTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 62325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataStatePtr to, int counter) { 62335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((am == NULL) || (from == NULL) || (counter < 0)) 62345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 62355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateCountedEpsilonTransition(am, from, to, counter); 62365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) 62375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(am->state); 62385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(to); 62395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 62405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 62425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataNewCounterTrans: 62435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 62445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @from: the starting point of the transition 62455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @to: the target point of the transition or NULL 62465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @counter: the counter associated to that transition 62475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 62485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If @to is NULL, this creates first a new target state in the automata 62495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and then adds an epsilon transition from the @from state to the target state 62505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * which will be allowed only if the counter is within the right range. 62515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 62525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the target state or NULL in case of error 62535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 62545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataStatePtr 62555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataNewCounterTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, 62565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAutomataStatePtr to, int counter) { 62575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((am == NULL) || (from == NULL) || (counter < 0)) 62585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 62595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAGenerateCountedTransition(am, from, to, counter); 62605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to == NULL) 62615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(am->state); 62625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(to); 62635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 62645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 62665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataCompile: 62675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 62685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 62695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the automata into a Reg Exp ready for being executed. 62705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The automata should be free after this point. 62715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 62725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the compiled regexp or NULL in case of error 62735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 62745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlRegexpPtr 62755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataCompile(xmlAutomataPtr am) { 62765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRegexpPtr ret; 62775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((am == NULL) || (am->error != 0)) return(NULL); 62795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFAEliminateEpsilonTransitions(am); 62805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* xmlFAComputesDeterminism(am); */ 62815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlRegEpxFromParse(am); 62825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 62845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 62855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 62875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlAutomataIsDeterminist: 62885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @am: an automata 62895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 62905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Checks if an automata is determinist. 62915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 62925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if true, 0 if not, and -1 in case of error 62935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 62945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 62955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlAutomataIsDeterminist(xmlAutomataPtr am) { 62965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret; 62975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (am == NULL) 62995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 63005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 63015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlFAComputesDeterminism(am); 63025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 63035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 63045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* LIBXML_AUTOMATA_ENABLED */ 63055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 63065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_EXPR_ENABLED 63075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 63085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 63095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Formal Expression handling code * 63105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 63115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 63125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 63135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 63145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Expression handling context * 63155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 63165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 63175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 63185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlExpCtxt { 63195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictPtr dict; 63205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr *table; 63215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 63225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbElems; 63235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nb_nodes; 63245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxNodes; 63255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *expr; 63265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *cur; 63275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nb_cons; 63285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tabSize; 63295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 63305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 63315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 63325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpNewCtxt: 63335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @maxNodes: the maximum number of nodes 63345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @dict: optional dictionnary to use internally 63355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 63365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Creates a new context for manipulating expressions 63375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 63385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the context or NULL in case of error 63395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 63405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpCtxtPtr 63415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNewCtxt(int maxNodes, xmlDictPtr dict) { 63425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpCtxtPtr ret; 63435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size = 256; 63445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 63455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (maxNodes <= 4096) 63465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxNodes = 4096; 63475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 63485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlExpCtxtPtr) xmlMalloc(sizeof(xmlExpCtxt)); 63495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 63505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 63515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlExpCtxt)); 63525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->size = size; 63535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nbElems = 0; 63545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->maxNodes = maxNodes; 63555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->table = xmlMalloc(size * sizeof(xmlExpNodePtr)); 63565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->table == NULL) { 63575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ret); 63585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 63595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 63605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret->table, 0, size * sizeof(xmlExpNodePtr)); 63615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict == NULL) { 63625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->dict = xmlDictCreate(); 63635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->dict == NULL) { 63645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ret->table); 63655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ret); 63665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 63675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 63685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 63695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->dict = dict; 63705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictReference(ret->dict); 63715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 63725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 63735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 63745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 63755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 63765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpFreeCtxt: 63775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an expression context 63785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 63795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free an expression context 63805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 63815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 63825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpFreeCtxt(xmlExpCtxtPtr ctxt) { 63835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 63845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 63855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictFree(ctxt->dict); 63865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->table != NULL) 63875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->table); 63885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt); 63895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 63905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 63915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 63925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 63935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Structure associated to an expression node * 63945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 63955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 63965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX_NODES 10000 63975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 63985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_DERIV */ 63995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 64015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: 64025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - Wildcards 64035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - public API for creation 64045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 64055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Started 64065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - regression testing 64075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 64085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Done 64095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - split into module and test tool 64105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - memleaks 64115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 64125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum { 64145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_EXP_NILABLE = (1 << 0) 64155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xmlExpNodeInfo; 64165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IS_NILLABLE(node) ((node)->info & XML_EXP_NILABLE) 64185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlExpNode { 64205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char type;/* xmlExpNodeType */ 64215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char info;/* OR of xmlExpNodeInfo */ 64225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short key; /* the hash key */ 64235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int ref; /* The number of references */ 64245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int c_max; /* the maximum length it can consume */ 64255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr exp_left; 64265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr next;/* the next node in the hash table or free list */ 64275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 64285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 64295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int f_min; 64305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int f_max; 64315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } count; 64325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 64335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr f_right; 64345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } children; 64355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *f_str; 64365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } field; 64375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 64385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define exp_min field.count.f_min 64405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define exp_max field.count.f_max 64415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define exp_left field.children.f_left */ 64425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define exp_right field.children.f_right 64435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define exp_str field.f_str 64445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr xmlExpNewNode(xmlExpCtxtPtr ctxt, xmlExpNodeType type); 64465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNode forbiddenExpNode = { 64475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_EXP_FORBID, 0, 0, 0, 0, NULL, NULL, {{ 0, 0}} 64485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 64495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr forbiddenExp = &forbiddenExpNode; 64505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNode emptyExpNode = { 64515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_EXP_EMPTY, 1, 0, 0, 0, NULL, NULL, {{ 0, 0}} 64525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 64535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr emptyExp = &emptyExpNode; 64545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 64565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 64575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The custom hash table for unicity and canonicalization * 64585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of sub-expressions pointers * 64595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 64605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 64615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 64625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpHashNameComputeKey: 64635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Calculate the hash key for a token 64645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 64655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned short 64665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpHashNameComputeKey(const xmlChar *name) { 64675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short value = 0L; 64685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char ch; 64695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name != NULL) { 64715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value += 30 * (*name); 64725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((ch = *name++) != 0) { 64735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = value ^ ((value << 5) + (value >> 3) + (unsigned short)ch); 64745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 64755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 64765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (value); 64775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 64785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 64805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpHashComputeKey: 64815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Calculate the hash key for a compound expression 64825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 64835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned short 64845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpHashComputeKey(xmlExpNodeType type, xmlExpNodePtr left, 64855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr right) { 64865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long value; 64875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short ret; 64885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 64905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_SEQ: 64915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = left->key; 64925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value += right->key; 64935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value *= 3; 64945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (unsigned short) value; 64955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 64965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_OR: 64975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = left->key; 64985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value += right->key; 64995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value *= 7; 65005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (unsigned short) value; 65015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 65025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_COUNT: 65035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = left->key; 65045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value += right->key; 65055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (unsigned short) value; 65065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 65075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 65085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 65095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 65105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 65115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 65125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr 65155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNewNode(xmlExpCtxtPtr ctxt, xmlExpNodeType type) { 65165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr ret; 65175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->nb_nodes >= MAX_NODES) 65195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 65205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlExpNodePtr) xmlMalloc(sizeof(xmlExpNode)); 65215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 65225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 65235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlExpNode)); 65245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->type = type; 65255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->next = NULL; 65265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nb_nodes++; 65275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nb_cons++; 65285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 65295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 65305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 65325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpHashGetEntry: 65335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @table: the hash table 65345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 65355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the unique entry from the hash table. The entry is created if 65365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * needed. @left and @right are consumed, i.e. their ref count will 65375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * be decremented by the operation. 65385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 65395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the pointer or NULL in case of error 65405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 65415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr 65425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpHashGetEntry(xmlExpCtxtPtr ctxt, xmlExpNodeType type, 65435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr left, xmlExpNodePtr right, 65445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *name, int min, int max) { 65455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short kbase, key; 65465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr entry; 65475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr insert; 65485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 65505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 65515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 65535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check for duplicate and insertion location. 65545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 65555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == XML_EXP_ATOM) { 65565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kbase = xmlExpHashNameComputeKey(name); 65575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (type == XML_EXP_COUNT) { 65585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* COUNT reduction rule 1 */ 65595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* a{1} -> a */ 65605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min == max) { 65615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min == 1) { 65625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(left); 65635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 65645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min == 0) { 65655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, left); 65665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(emptyExp); 65675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 65685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 65695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min < 0) { 65705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, left); 65715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 65725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 65735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (max == -1) 65745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kbase = min + 79; 65755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 65765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kbase = max - min; 65775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kbase += left->key; 65785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (type == XML_EXP_OR) { 65795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Forbid reduction rules */ 65805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (left->type == XML_EXP_FORBID) { 65815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, left); 65825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(right); 65835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 65845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (right->type == XML_EXP_FORBID) { 65855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, right); 65865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(left); 65875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 65885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* OR reduction rule 1 */ 65905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* a | a reduced to a */ 65915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (left == right) { 65925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) left->ref--; 65935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(left); 65945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 65955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* OR canonicalization rule 1 */ 65965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* linearize (a | b) | c into a | (b | c) */ 65975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((left->type == XML_EXP_OR) && (right->type != XML_EXP_OR)) { 65985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr tmp = left; 65995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) left = right; 66005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) right = tmp; 66015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* OR reduction rule 2 */ 66035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* a | (a | b) and b | (a | b) are reduced to a | b */ 66045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (right->type == XML_EXP_OR) { 66055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((left == right->exp_left) || 66065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (left == right->exp_right)) { 66075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, left); 66085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(right); 66095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* OR canonicalization rule 2 */ 66125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* linearize (a | b) | c into a | (b | c) */ 66135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (left->type == XML_EXP_OR) { 66145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr tmp; 66155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 66165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* OR canonicalization rule 2 */ 66175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((left->exp_right->type != XML_EXP_OR) && 66185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (left->exp_right->key < left->exp_left->key)) { 66195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = left->exp_right; 66205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) left->exp_right = left->exp_left; 66215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) left->exp_left = tmp; 66225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) left->exp_right->ref++; 66245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left->exp_right, right, 66255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 0, 0); 66265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) left->exp_left->ref++; 66275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left->exp_left, tmp, 66285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 0, 0); 66295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 66305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, left); 66315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp); 66325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (right->type == XML_EXP_OR) { 66345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ordering in the tree */ 66355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* C | (A | B) -> A | (B | C) */ 66365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (left->key > right->exp_right->key) { 66375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr tmp; 66385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) right->exp_right->ref++; 66395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_right, 66405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) left, NULL, 0, 0); 66415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) right->exp_left->ref++; 66425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_left, 66435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp, NULL, 0, 0); 66445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, right); 66455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp); 66465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ordering in the tree */ 66485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* B | (A | C) -> A | (B | C) */ 66495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (left->key > right->exp_left->key) { 66505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr tmp; 66515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) right->exp_right->ref++; 66525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, left, 66535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) right->exp_right, NULL, 0, 0); 66545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) right->exp_left->ref++; 66555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpHashGetEntry(ctxt, XML_EXP_OR, right->exp_left, 66565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp, NULL, 0, 0); 66575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, right); 66585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp); 66595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* we know both types are != XML_EXP_OR here */ 66625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (left->key > right->key) { 66635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr tmp = left; 66645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) left = right; 66655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) right = tmp; 66665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kbase = xmlExpHashComputeKey(type, left, right); 66685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (type == XML_EXP_SEQ) { 66695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Forbid reduction rules */ 66705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (left->type == XML_EXP_FORBID) { 66715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, right); 66725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(left); 66735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (right->type == XML_EXP_FORBID) { 66755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, left); 66765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(right); 66775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Empty reduction rules */ 66795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (right->type == XML_EXP_EMPTY) { 66805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(left); 66815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (left->type == XML_EXP_EMPTY) { 66835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(right); 66845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 66855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kbase = xmlExpHashComputeKey(type, left, right); 66865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 66875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 66885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 66895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = kbase % ctxt->size; 66905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->table[key] != NULL) { 66915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (insert = ctxt->table[key]; insert != NULL; 66925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert = insert->next) { 66935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((insert->key == kbase) && 66945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (insert->type == type)) { 66955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == XML_EXP_ATOM) { 66965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name == insert->exp_str) { 66975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert->ref++; 66985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(insert); 66995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 67005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (type == XML_EXP_COUNT) { 67015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((insert->exp_min == min) && (insert->exp_max == max) && 67025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (insert->exp_left == left)) { 67035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert->ref++; 67045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) left->ref--; 67055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(insert); 67065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 67075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((insert->exp_left == left) && 67085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (insert->exp_right == right)) { 67095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert->ref++; 67105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) left->ref--; 67115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) right->ref--; 67125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(insert); 67135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 67145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 67155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 67165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 67175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry = xmlExpNewNode(ctxt, type); 67195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry == NULL) 67205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 67215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->key = kbase; 67225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == XML_EXP_ATOM) { 67235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->exp_str = name; 67245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->c_max = 1; 67255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (type == XML_EXP_COUNT) { 67265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->exp_min = min; 67275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->exp_max = max; 67285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->exp_left = left; 67295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((min == 0) || (IS_NILLABLE(left))) 67305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->info |= XML_EXP_NILABLE; 67315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (max < 0) 67325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->c_max = -1; 67335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 67345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->c_max = max * entry->exp_left->c_max; 67355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 67365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->exp_left = left; 67375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->exp_right = right; 67385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == XML_EXP_OR) { 67395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((IS_NILLABLE(left)) || (IS_NILLABLE(right))) 67405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->info |= XML_EXP_NILABLE; 67415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((entry->exp_left->c_max == -1) || 67425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (entry->exp_right->c_max == -1)) 67435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->c_max = -1; 67445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (entry->exp_left->c_max > entry->exp_right->c_max) 67455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->c_max = entry->exp_left->c_max; 67465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 67475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->c_max = entry->exp_right->c_max; 67485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 67495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((IS_NILLABLE(left)) && (IS_NILLABLE(right))) 67505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->info |= XML_EXP_NILABLE; 67515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((entry->exp_left->c_max == -1) || 67525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (entry->exp_right->c_max == -1)) 67535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->c_max = -1; 67545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 67555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->c_max = entry->exp_left->c_max + entry->exp_right->c_max; 67565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 67575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 67585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->ref = 1; 67595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->table[key] != NULL) 67605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->next = ctxt->table[key]; 67615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->table[key] = entry; 67635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nbElems++; 67645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(entry); 67665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 67675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 67695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpFree: 67705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context 67715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the expression 67725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 67735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Dereference the expression 67745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 67755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 67765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpFree(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp) { 67775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exp == NULL) || (exp == forbiddenExp) || (exp == emptyExp)) 67785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 67795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exp->ref--; 67805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->ref == 0) { 67815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short key; 67825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Unlink it first from the hash table */ 67845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = exp->key % ctxt->size; 67855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->table[key] == exp) { 67865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->table[key] = exp->next; 67875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 67885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr tmp; 67895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = ctxt->table[key]; 67915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (tmp != NULL) { 67925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp->next == exp) { 67935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp->next = exp->next; 67945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 67955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 67965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = tmp->next; 67975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 67985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 67995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 68005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exp->type == XML_EXP_SEQ) || (exp->type == XML_EXP_OR)) { 68015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, exp->exp_left); 68025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, exp->exp_right); 68035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (exp->type == XML_EXP_COUNT) { 68045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, exp->exp_left); 68055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 68065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(exp); 68075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nb_nodes--; 68085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 68095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 68105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 68115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 68125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpRef: 68135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the expression 68145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 68155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Increase the reference count of the expression 68165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 68175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 68185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpRef(xmlExpNodePtr exp) { 68195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp != NULL) 68205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exp->ref++; 68215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 68225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 68235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 68245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpNewAtom: 68255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context 68265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name: the atom name 68275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: the atom name lenght in byte (or -1); 68285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 68295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the atom associated to this name from that context 68305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 68315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the node or NULL in case of error 68325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 68335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr 68345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNewAtom(xmlExpCtxtPtr ctxt, const xmlChar *name, int len) { 68355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (name == NULL)) 68365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 68375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = xmlDictLookup(ctxt->dict, name, len); 68385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name == NULL) 68395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 68405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlExpHashGetEntry(ctxt, XML_EXP_ATOM, NULL, NULL, name, 0, 0)); 68415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 68425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 68435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 68445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpNewOr: 68455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context 68465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @left: left expression 68475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @right: right expression 68485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 68495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the atom associated to the choice @left | @right 68505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note that @left and @right are consumed in the operation, to keep 68515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * an handle on them use xmlExpRef() and use xmlExpFree() to release them, 68525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is true even in case of failure (unless ctxt == NULL). 68535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 68545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the node or NULL in case of error 68555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 68565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr 68575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNewOr(xmlExpCtxtPtr ctxt, xmlExpNodePtr left, xmlExpNodePtr right) { 68585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 68595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 68605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((left == NULL) || (right == NULL)) { 68615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, left); 68625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, right); 68635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 68645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 68655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, left, right, NULL, 0, 0)); 68665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 68675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 68685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 68695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpNewSeq: 68705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context 68715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @left: left expression 68725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @right: right expression 68735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 68745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the atom associated to the sequence @left , @right 68755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note that @left and @right are consumed in the operation, to keep 68765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * an handle on them use xmlExpRef() and use xmlExpFree() to release them, 68775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is true even in case of failure (unless ctxt == NULL). 68785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 68795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the node or NULL in case of error 68805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 68815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr 68825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNewSeq(xmlExpCtxtPtr ctxt, xmlExpNodePtr left, xmlExpNodePtr right) { 68835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 68845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 68855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((left == NULL) || (right == NULL)) { 68865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, left); 68875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, right); 68885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 68895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 68905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, left, right, NULL, 0, 0)); 68915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 68925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 68935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 68945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpNewRange: 68955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context 68965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @subset: the expression to be repeated 68975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @min: the lower bound for the repetition 68985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @max: the upper bound for the repetition, -1 means infinite 68995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 69005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the atom associated to the range (@subset){@min, @max} 69015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note that @subset is consumed in the operation, to keep 69025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * an handle on it use xmlExpRef() and use xmlExpFree() to release it, 69035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this is true even in case of failure (unless ctxt == NULL). 69045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 69055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the node or NULL in case of error 69065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 69075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr 69085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNewRange(xmlExpCtxtPtr ctxt, xmlExpNodePtr subset, int min, int max) { 69095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 69105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 69115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((subset == NULL) || (min < 0) || (max < -1) || 69125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((max >= 0) && (min > max))) { 69135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, subset); 69145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 69155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 69165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, subset, 69175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL, min, max)); 69185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 69195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 69205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 69215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 69225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Public API for operations on expressions * 69235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 69245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 69255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 69265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 69275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpGetLanguageInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 69285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar**list, int len, int nb) { 69295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tmp, tmp2; 69305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)tail: 69315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (exp->type) { 69325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_EMPTY: 69335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 69345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_ATOM: 69355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (tmp = 0;tmp < nb;tmp++) 69365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list[tmp] == exp->exp_str) 69375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 69385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nb >= len) 69395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-2); 69405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list[nb] = exp->exp_str; 69415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 69425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_COUNT: 69435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exp = exp->exp_left; 69445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto tail; 69455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_SEQ: 69465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_OR: 69475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpGetLanguageInt(ctxt, exp->exp_left, list, len, nb); 69485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp < 0) 69495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp); 69505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp2 = xmlExpGetLanguageInt(ctxt, exp->exp_right, list, len, 69515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nb + tmp); 69525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp2 < 0) 69535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp2); 69545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp + tmp2); 69555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 69565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 69575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 69585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 69595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 69605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpGetLanguage: 69615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context 69625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the expression 69635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @langList: where to store the tokens 69645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: the allocated lenght of @list 69655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 69665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Find all the strings used in @exp and store them in @list 69675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 69685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of unique strings found, -1 in case of errors and 69695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * -2 if there is more than @len strings 69705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 69715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 69725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpGetLanguage(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 69735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar**langList, int len) { 69745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (exp == NULL) || (langList == NULL) || (len <= 0)) 69755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 69765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlExpGetLanguageInt(ctxt, exp, langList, len, 0)); 69775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 69785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 69795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 69805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpGetStartInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 69815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar**list, int len, int nb) { 69825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tmp, tmp2; 69835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)tail: 69845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (exp->type) { 69855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_FORBID: 69865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 69875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_EMPTY: 69885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 69895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_ATOM: 69905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (tmp = 0;tmp < nb;tmp++) 69915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list[tmp] == exp->exp_str) 69925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 69935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nb >= len) 69945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-2); 69955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list[nb] = exp->exp_str; 69965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 69975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_COUNT: 69985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exp = exp->exp_left; 69995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto tail; 70005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_SEQ: 70015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpGetStartInt(ctxt, exp->exp_left, list, len, nb); 70025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp < 0) 70035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp); 70045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IS_NILLABLE(exp->exp_left)) { 70055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp2 = xmlExpGetStartInt(ctxt, exp->exp_right, list, len, 70065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nb + tmp); 70075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp2 < 0) 70085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp2); 70095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp += tmp2; 70105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 70115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp); 70125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_OR: 70135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpGetStartInt(ctxt, exp->exp_left, list, len, nb); 70145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp < 0) 70155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp); 70165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp2 = xmlExpGetStartInt(ctxt, exp->exp_right, list, len, 70175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nb + tmp); 70185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp2 < 0) 70195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp2); 70205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp + tmp2); 70215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 70225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 70235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 70245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 70255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 70265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpGetStart: 70275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context 70285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the expression 70295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @tokList: where to store the tokens 70305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: the allocated lenght of @list 70315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 70325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Find all the strings that appears at the start of the languages 70335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * accepted by @exp and store them in @list. E.g. for (a, b) | c 70345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it will return the list [a, c] 70355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 70365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of unique strings found, -1 in case of errors and 70375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * -2 if there is more than @len strings 70385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 70395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 70405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpGetStart(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 70415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar**tokList, int len) { 70425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (exp == NULL) || (tokList == NULL) || (len <= 0)) 70435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 70445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlExpGetStartInt(ctxt, exp, tokList, len, 0)); 70455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 70465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 70475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 70485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpIsNillable: 70495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the expression 70505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 70515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Finds if the expression is nillable, i.e. if it accepts the empty sequqnce 70525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 70535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if nillable, 0 if not and -1 in case of error 70545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 70555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 70565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpIsNillable(xmlExpNodePtr exp) { 70575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp == NULL) 70585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 70595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(IS_NILLABLE(exp) != 0); 70605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 70615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 70625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr 70635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpStringDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, const xmlChar *str) 70645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 70655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr ret; 70665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 70675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (exp->type) { 70685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_EMPTY: 70695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 70705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_FORBID: 70715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 70725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_ATOM: 70735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_str == str) { 70745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 70755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("deriv atom: equal => Empty\n"); 70765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 70775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = emptyExp; 70785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 70795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 70805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("deriv atom: mismatch => forbid\n"); 70815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 70825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO wildcards here */ 70835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = forbiddenExp; 70845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 70855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 70865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_OR: { 70875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr tmp; 70885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 70895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 70905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("deriv or: => or(derivs)\n"); 70915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 70925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpStringDeriveInt(ctxt, exp->exp_left, str); 70935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 70945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 70955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 70965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpStringDeriveInt(ctxt, exp->exp_right, str); 70975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 70985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 70995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 71005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 71015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, tmp, ret, 71025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 0, 0); 71035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 71045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 71055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_SEQ: 71065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 71075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("deriv seq: starting with left\n"); 71085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 71095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpStringDeriveInt(ctxt, exp->exp_left, str); 71105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 71115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 71125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ret == forbiddenExp) { 71135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IS_NILLABLE(exp->exp_left)) { 71145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 71155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("deriv seq: left failed but nillable\n"); 71165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 71175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpStringDeriveInt(ctxt, exp->exp_right, str); 71185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 71195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 71205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 71215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("deriv seq: left match => sequence\n"); 71225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 71235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exp->exp_right->ref++; 71245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, exp->exp_right, 71255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 0, 0); 71265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 71275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 71285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_COUNT: { 71295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min, max; 71305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr tmp; 71315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_max == 0) 71335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 71345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpStringDeriveInt(ctxt, exp->exp_left, str); 71355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 71365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 71375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == forbiddenExp) { 71385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 71395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("deriv count: pattern mismatch => forbid\n"); 71405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 71415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 71425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 71435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_max == 1) 71445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 71455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_max < 0) /* unbounded */ 71465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = -1; 71475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 71485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = exp->exp_max - 1; 71495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_min > 0) 71505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = exp->exp_min - 1; 71515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 71525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = 0; 71535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exp->exp_left->ref++; 71545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left, NULL, 71555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, min, max); 71565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == emptyExp) { 71575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 71585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("deriv count: match to empty => new count\n"); 71595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 71605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp); 71615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 71625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 71635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("deriv count: match => sequence with new count\n"); 71645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 71655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, tmp, 71665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 0, 0)); 71675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 71685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 71695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 71705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 71715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 71735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpStringDerive: 71745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expression context 71755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the expression 71765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @str: the string 71775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: the string len in bytes if available 71785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 71795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Do one step of Brzozowski derivation of the expression @exp with 71805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * respect to the input string 71815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 71825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the resulting expression or NULL in case of internal error 71835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 71845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr 71855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpStringDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 71865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *str, int len) { 71875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *input; 71885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exp == NULL) || (ctxt == NULL) || (str == NULL)) { 71905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 71915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 71925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 71935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * check the string is in the dictionnary, if yes use an interned 71945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copy, otherwise we know it's not an acceptable input 71955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 71965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input = xmlDictExists(ctxt->dict, str, len); 71975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (input == NULL) { 71985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 71995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 72005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlExpStringDeriveInt(ctxt, exp, input)); 72015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 72025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 72045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpCheckCard(xmlExpNodePtr exp, xmlExpNodePtr sub) { 72055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 1; 72065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sub->c_max == -1) { 72085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->c_max != -1) 72095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 72105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((exp->c_max >= 0) && (exp->c_max < sub->c_max)) { 72115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 72125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 72135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 72145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((IS_NILLABLE(sub)) && (!IS_NILLABLE(exp))) 72155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 0; 72165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 72175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 72185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 72195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, 72215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr sub); 72225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 72235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpDivide: 72245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expressions context 72255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the englobing expression 72265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @sub: the subexpression 72275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @mult: the multiple expression 72285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @remain: the remain from the derivation of the multiple 72295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 72305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check if exp is a multiple of sub, i.e. if there is a finite number n 72315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * so that sub{n} subsume exp 72325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 72335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the multiple value if successful, 0 if it is not a multiple 72345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and -1 in case of internel error. 72355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 72365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 72385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpDivide(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub, 72395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr *mult, xmlExpNodePtr *remain) { 72405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 72415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr tmp, tmp2; 72425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mult != NULL) *mult = NULL; 72445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remain != NULL) *remain = NULL; 72455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->c_max == -1) return(0); 72465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IS_NILLABLE(exp) && (!IS_NILLABLE(sub))) return(0); 72475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 1;i <= exp->c_max;i++) { 72495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sub->ref++; 72505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, 72515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sub, NULL, NULL, i, i); 72525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 72535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 72545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 72555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlExpCheckCard(tmp, exp)) { 72565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 72575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 72585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 72595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp2 = xmlExpExpDeriveInt(ctxt, tmp, exp); 72605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp2 == NULL) { 72615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 72625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 72635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 72645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp2 != forbiddenExp) && (IS_NILLABLE(tmp2))) { 72655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remain != NULL) 72665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *remain = tmp2; 72675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 72685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp2); 72695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mult != NULL) 72705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *mult = tmp; 72715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 72725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 72735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 72745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Divide succeeded %d\n", i); 72755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 72765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(i); 72775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 72785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 72795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp2); 72805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 72815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 72825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Divide failed\n"); 72835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 72845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 72855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 72865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 72885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpExpDeriveInt: 72895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expressions context 72905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the englobing expression 72915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @sub: the subexpression 72925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 72935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Try to do a step of Brzozowski derivation but at a higher level 72945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the input being a subexpression. 72955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 72965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the resulting expression or NULL in case of internal error 72975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 72985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr 72995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) { 73005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr ret, tmp, tmp2, tmp3; 73015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar **tab; 73025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len, i; 73035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 73045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 73055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * In case of equality and if the expression can only consume a finite 73065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * amount, then the derivation is empty 73075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 73085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exp == sub) && (exp->c_max >= 0)) { 73095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 73105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Equal(exp, sub) and finite -> Empty\n"); 73115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 73125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(emptyExp); 73135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 73145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 73155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * decompose sub sequence first 73165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 73175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sub->type == XML_EXP_EMPTY) { 73185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 73195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Empty(sub) -> Empty\n"); 73205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 73215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exp->ref++; 73225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(exp); 73235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 73245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sub->type == XML_EXP_SEQ) { 73255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 73265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Seq(sub) -> decompose\n"); 73275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 73285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpExpDeriveInt(ctxt, exp, sub->exp_left); 73295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) 73305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 73315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == forbiddenExp) 73325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp); 73335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpExpDeriveInt(ctxt, tmp, sub->exp_right); 73345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 73355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 73365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 73375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sub->type == XML_EXP_OR) { 73385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 73395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Or(sub) -> decompose\n"); 73405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 73415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpExpDeriveInt(ctxt, exp, sub->exp_left); 73425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == forbiddenExp) 73435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp); 73445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) 73455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 73465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpExpDeriveInt(ctxt, exp, sub->exp_right); 73475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret == NULL) || (ret == forbiddenExp)) { 73485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 73495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 73505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 73515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, tmp, ret, NULL, 0, 0)); 73525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 73535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlExpCheckCard(exp, sub)) { 73545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 73555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("CheckCard(exp, sub) failed -> Forbid\n"); 73565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 73575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 73585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 73595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (exp->type) { 73605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_EMPTY: 73615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sub == emptyExp) 73625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(emptyExp); 73635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 73645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Empty(exp) -> Forbid\n"); 73655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 73665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 73675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_FORBID: 73685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 73695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Forbid(exp) -> Forbid\n"); 73705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 73715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 73725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_ATOM: 73735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sub->type == XML_EXP_ATOM) { 73745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: handle wildcards */ 73755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_str == sub->exp_str) { 73765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 73775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Atom match -> Empty\n"); 73785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 73795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(emptyExp); 73805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 73815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 73825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Atom mismatch -> Forbid\n"); 73835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 73845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 73855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 73865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((sub->type == XML_EXP_COUNT) && 73875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sub->exp_max == 1) && 73885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sub->exp_left->type == XML_EXP_ATOM)) { 73895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: handle wildcards */ 73905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_str == sub->exp_left->exp_str) { 73915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 73925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Atom match -> Empty\n"); 73935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 73945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(emptyExp); 73955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 73965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 73975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Atom mismatch -> Forbid\n"); 73985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 73995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 74005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 74015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 74025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Compex exp vs Atom -> Forbid\n"); 74035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 74045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 74055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_SEQ: 74065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* try to get the sequence consumed only if possible */ 74075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlExpCheckCard(exp->exp_left, sub)) { 74085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* See if the sequence can be consumed directly */ 74095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 74105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Seq trying left only\n"); 74115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 74125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub); 74135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret != forbiddenExp) && (ret != NULL)) { 74145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 74155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Seq trying left only worked\n"); 74165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 74175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 74185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: assumption here that we are determinist 74195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * i.e. we won't get to a nillable exp left 74205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * subset which could be matched by the right 74215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * part too. 74225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * e.g.: (a | b)+,(a | c) and 'a+,a' 74235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 74245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exp->exp_right->ref++; 74255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, 74265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exp->exp_right, NULL, 0, 0)); 74275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 74285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 74295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 74305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Seq: left too short\n"); 74315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 74325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 74335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Try instead to decompose */ 74345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sub->type == XML_EXP_COUNT) { 74355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min, max; 74365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 74385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Seq: sub is a count\n"); 74395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 74405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub->exp_left); 74415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 74425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 74435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret != forbiddenExp) { 74445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 74455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Seq , Count match on left\n"); 74465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 74475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sub->exp_max < 0) 74485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = -1; 74495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 74505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = sub->exp_max -1; 74515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sub->exp_min > 0) 74525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = sub->exp_min -1; 74535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 74545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = 0; 74555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exp->exp_right->ref++; 74565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, 74575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exp->exp_right, NULL, 0, 0); 74585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) 74595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 74605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sub->exp_left->ref++; 74625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, 74635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sub->exp_left, NULL, NULL, min, max); 74645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp2 == NULL) { 74655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 74665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 74675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 74685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpExpDeriveInt(ctxt, tmp, tmp2); 74695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 74705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp2); 74715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 74725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 74735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 74745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* we made no progress on structured operations */ 74755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 74765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_OR: 74775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 74785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Or , trying both side\n"); 74795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 74805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub); 74815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 74825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 74835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpExpDeriveInt(ctxt, exp->exp_right, sub); 74845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 74855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, ret); 74865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 74875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 74885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, tmp, NULL, 0, 0)); 74895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_COUNT: { 74905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min, max; 74915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sub->type == XML_EXP_COUNT) { 74935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 74945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Try to see if the loop is completely subsumed 74955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 74965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub->exp_left); 74975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) 74985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 74995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == forbiddenExp) { 75005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mult; 75015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 75035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Count, Count inner don't subsume\n"); 75045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 75055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mult = xmlExpDivide(ctxt, sub->exp_left, exp->exp_left, 75065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, &tmp); 75075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mult <= 0) { 75085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 75095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Count, Count not multiple => forbidden\n"); 75105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 75115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 75125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 75135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sub->exp_max == -1) { 75145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = -1; 75155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_max == -1) { 75165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_min <= sub->exp_min * mult) 75175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = 0; 75185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 75195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = exp->exp_min - sub->exp_min * mult; 75205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 75215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 75225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Count, Count finite can't subsume infinite\n"); 75235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 75245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 75255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 75265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 75275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 75285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_max == -1) { 75295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 75305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Infinite loop consume mult finite loop\n"); 75315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 75325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_min > sub->exp_min * mult) { 75335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = -1; 75345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = exp->exp_min - sub->exp_min * mult; 75355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 75365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = -1; 75375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = 0; 75385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 75395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 75405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_max < sub->exp_max * mult) { 75415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 75425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("loops max mult mismatch => forbidden\n"); 75435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 75445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 75455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 75465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 75475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sub->exp_max * mult > exp->exp_min) 75485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = 0; 75495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 75505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = exp->exp_min - sub->exp_max * mult; 75515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = exp->exp_max - sub->exp_max * mult; 75525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 75535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 75545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!IS_NILLABLE(tmp)) { 75555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 75565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: loop here to try to grow if working on finite 75575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * blocks. 75585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 75595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 75605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Count, Count remain not nillable => forbidden\n"); 75615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 75625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 75635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 75645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (sub->exp_max == -1) { 75655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_max == -1) { 75665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_min <= sub->exp_min) { 75675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 75685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Infinite loops Okay => COUNT(0,Inf)\n"); 75695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 75705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = -1; 75715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = 0; 75725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 75735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 75745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Infinite loops min => Count(X,Inf)\n"); 75755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 75765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = -1; 75775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = exp->exp_min - sub->exp_min; 75785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 75795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (exp->exp_min > sub->exp_min) { 75805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 75815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("loops min mismatch 1 => forbidden ???\n"); 75825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 75835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 75845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 75855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 75865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = -1; 75875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = 0; 75885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 75895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 75905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_max == -1) { 75915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 75925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Infinite loop consume finite loop\n"); 75935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 75945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_min > sub->exp_min) { 75955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = -1; 75965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = exp->exp_min - sub->exp_min; 75975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 75985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = -1; 75995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = 0; 76005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 76015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 76025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_max < sub->exp_max) { 76035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 76045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("loops max mismatch => forbidden\n"); 76055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 76065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 76075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 76085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 76095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sub->exp_max > exp->exp_min) 76105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = 0; 76115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 76125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = exp->exp_min - sub->exp_max; 76135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = exp->exp_max - sub->exp_max; 76145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 76155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 76165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 76175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("loops match => SEQ(COUNT())\n"); 76185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 76195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exp->exp_left->ref++; 76205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left, 76215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL, min, max); 76225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp2 == NULL) { 76235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 76245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 76255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, tmp, tmp2, 76265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 0, 0); 76275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 76285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 76295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub); 76305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) 76315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 76325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == forbiddenExp) { 76335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 76345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("loop mismatch => forbidden\n"); 76355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 76365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 76375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 76385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_min > 0) 76395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = exp->exp_min - 1; 76405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 76415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = 0; 76425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exp->exp_max < 0) 76435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = -1; 76445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 76455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = exp->exp_max - 1; 76465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 76485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("loop match => SEQ(COUNT())\n"); 76495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 76505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exp->exp_left->ref++; 76515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left, 76525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL, min, max); 76535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp2 == NULL) 76545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 76555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, tmp, tmp2, 76565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 0, 0); 76575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 76585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 76595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 76605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 76625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Fallback to derivative\n"); 76635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 76645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IS_NILLABLE(sub)) { 76655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(IS_NILLABLE(exp))) 76665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 76675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 76685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = emptyExp; 76695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 76705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = NULL; 76715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 76725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * here the structured derivation made no progress so 76735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we use the default token based derivation to force one more step 76745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 76755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->tabSize == 0) 76765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->tabSize = 40; 76775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab = (const xmlChar **) xmlMalloc(ctxt->tabSize * 76795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(const xmlChar *)); 76805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab == NULL) { 76815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 76825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 76835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 76855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * collect all the strings accepted by the subexpression on input 76865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 76875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0); 76885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (len < 0) { 76895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar **temp; 76905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = (const xmlChar **) xmlRealloc((xmlChar **) tab, ctxt->tabSize * 2 * 76915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(const xmlChar *)); 76925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp == NULL) { 76935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree((xmlChar **) tab); 76945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 76955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 76965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab = temp; 76975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->tabSize *= 2; 76985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0); 76995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 77005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < len;i++) { 77015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpStringDeriveInt(ctxt, exp, tab[i]); 77025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp == NULL) || (tmp == forbiddenExp)) { 77035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, ret); 77045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree((xmlChar **) tab); 77055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp); 77065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 77075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp2 = xmlExpStringDeriveInt(ctxt, sub, tab[i]); 77085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp2 == NULL) || (tmp2 == forbiddenExp)) { 77095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 77105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, ret); 77115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree((xmlChar **) tab); 77125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp); 77135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 77145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp3 = xmlExpExpDeriveInt(ctxt, tmp, tmp2); 77155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 77165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp2); 77175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp3 == NULL) || (tmp3 == forbiddenExp)) { 77195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, ret); 77205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree((xmlChar **) tab); 77215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp3); 77225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 77235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 77255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = tmp3; 77265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 77275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, tmp3, NULL, 0, 0); 77285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 77295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree((xmlChar **) tab); 77305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 77315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 77325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 77335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 77345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree((xmlChar **) tab); 77355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 77365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 77375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 77395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpExpDerive: 77405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expressions context 77415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the englobing expression 77425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @sub: the subexpression 77435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 77445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Evaluates the expression resulting from @exp consuming a sub expression @sub 77455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Based on algebraic derivation and sometimes direct Brzozowski derivation 77465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it usually tatkes less than linear time and can handle expressions generating 77475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * infinite languages. 77485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 77495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the resulting expression or NULL in case of internal error, the 77505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * result must be freed 77515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 77525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr 77535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpExpDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) { 77545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exp == NULL) || (ctxt == NULL) || (sub == NULL)) 77555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 77565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 77585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * O(1) speedups 77595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 77605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IS_NILLABLE(sub) && (!IS_NILLABLE(exp))) { 77615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 77625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Sub nillable and not exp : can't subsume\n"); 77635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 77645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 77655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 77665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlExpCheckCard(exp, sub) == 0) { 77675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 77685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("sub generate longuer sequances than exp : can't subsume\n"); 77695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 77705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(forbiddenExp); 77715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 77725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlExpExpDeriveInt(ctxt, exp, sub)); 77735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 77745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 77765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpSubsume: 77775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expressions context 77785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @exp: the englobing expression 77795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @sub: the subexpression 77805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 77815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check whether @exp accepts all the languages accexpted by @sub 77825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the input being a subexpression. 77835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 77845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if true 0 if false and -1 in case of failure. 77855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 77865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 77875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpSubsume(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) { 77885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr tmp; 77895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((exp == NULL) || (ctxt == NULL) || (sub == NULL)) 77915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 77925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 77945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: speedup by checking the language of sub is a subset of the 77955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * language of exp 77965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 77975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 77985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * O(1) speedups 77995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 78005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IS_NILLABLE(sub) && (!IS_NILLABLE(exp))) { 78015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 78025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Sub nillable and not exp : can't subsume\n"); 78035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 78045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 78055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 78065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlExpCheckCard(exp, sub) == 0) { 78075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 78085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("sub generate longuer sequances than exp : can't subsume\n"); 78095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 78105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 78115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 78125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = xmlExpExpDeriveInt(ctxt, exp, sub); 78135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_DERIV 78145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Result derivation :\n"); 78155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRINT_EXP(tmp); 78165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 78175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) 78185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 78195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == forbiddenExp) 78205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 78215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == emptyExp) 78225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 78235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp != NULL) && (IS_NILLABLE(tmp))) { 78245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 78255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 78265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 78275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, tmp); 78285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 78295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 78305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 78325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 78335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parsing expression * 78345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 78355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 78365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr xmlExpParseExpr(xmlExpCtxtPtr ctxt); 78385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef CUR 78405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CUR (*ctxt->cur) 78415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef NEXT 78425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEXT ctxt->cur++; 78435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef IS_BLANK 78445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IS_BLANK(c) ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t')) 78455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SKIP_BLANKS while (IS_BLANK(*ctxt->cur)) ctxt->cur++; 78465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 78485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpParseNumber(xmlExpCtxtPtr ctxt) { 78495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 0; 78505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 78525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '*') { 78535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT 78545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 78555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 78565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((CUR < '0') || (CUR > '9')) 78575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 78585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((CUR >= '0') && (CUR <= '9')) { 78595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = ret * 10 + (CUR - '0'); 78605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT 78615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 78625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 78635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 78645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr 78665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpParseOr(xmlExpCtxtPtr ctxt) { 78675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *base; 78685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr ret; 78695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *val; 78705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 78725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base = ctxt->cur; 78735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*ctxt->cur == '(') { 78745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT 78755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpParseExpr(ctxt); 78765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 78775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*ctxt->cur != ')') { 78785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "unbalanced '(' : %s\n", base); 78795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, ret); 78805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 78815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 78825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 78835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 78845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto parse_quantifier; 78855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 78865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((CUR != 0) && (!(IS_BLANK(CUR))) && (CUR != '(') && 78875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (CUR != ')') && (CUR != '|') && (CUR != ',') && (CUR != '{') && 78885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (CUR != '*') && (CUR != '+') && (CUR != '?') && (CUR != '}')) 78895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 78905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val = xmlDictLookup(ctxt->dict, BAD_CAST base, ctxt->cur - base); 78915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (val == NULL) 78925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 78935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpHashGetEntry(ctxt, XML_EXP_ATOM, NULL, NULL, val, 0, 0); 78945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 78955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 78965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 78975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)parse_quantifier: 78985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '{') { 78995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min, max; 79005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT 79025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min = xmlExpParseNumber(ctxt); 79035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min < 0) { 79045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, ret); 79055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 79065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 79075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 79085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == ',') { 79095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT 79105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = xmlExpParseNumber(ctxt); 79115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 79125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 79135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = min; 79145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != '}') { 79155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, ret); 79165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 79175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 79185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT 79195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL, 79205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min, max); 79215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 79225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == '?') { 79235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT 79245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL, 79255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 1); 79265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 79275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == '+') { 79285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT 79295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL, 79305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, -1); 79315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 79325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == '*') { 79335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT 79345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, ret, NULL, NULL, 79355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, -1); 79365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 79375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 79385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 79395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 79405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr 79435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpParseSeq(xmlExpCtxtPtr ctxt) { 79445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr ret, right; 79455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpParseOr(ctxt); 79475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 79485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (CUR == '|') { 79495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT 79505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) right = xmlExpParseOr(ctxt); 79515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (right == NULL) { 79525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, ret); 79535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 79545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 79555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpHashGetEntry(ctxt, XML_EXP_OR, ret, right, NULL, 0, 0); 79565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 79575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 79585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 79595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 79605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 79615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlExpNodePtr 79635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpParseExpr(xmlExpCtxtPtr ctxt) { 79645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr ret, right; 79655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpParseSeq(ctxt); 79675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 79685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (CUR == ',') { 79695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT 79705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) right = xmlExpParseSeq(ctxt); 79715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (right == NULL) { 79725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, ret); 79735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 79745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 79755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, right, NULL, 0, 0); 79765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 79775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 79785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 79795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 79805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 79815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 79835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpParse: 79845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the expressions context 79855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @expr: the 0 terminated string 79865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 79875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Minimal parser for regexps, it understand the following constructs 79885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - string terminals 79895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - choice operator | 79905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - sequence operator , 79915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - subexpressions (...) 79925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - usual cardinality operators + * and ? 79935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - finite sequences { min, max } 79945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - infinite sequences { min, * } 79955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * There is minimal checkings made especially no checking on strings values 79965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 79975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a new expression or NULL in case of failure 79985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 79995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpNodePtr 80005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpParse(xmlExpCtxtPtr ctxt, const char *expr) { 80015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr ret; 80025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->expr = expr; 80045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->cur = expr; 80055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlExpParseExpr(ctxt); 80075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS 80085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*ctxt->cur != 0) { 80095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpFree(ctxt, ret); 80105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 80115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 80125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 80135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 80145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 80165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpDumpInt(xmlBufferPtr buf, xmlExpNodePtr expr, int glob) { 80175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpNodePtr c; 80185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (expr == NULL) return; 80205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (glob) xmlBufferWriteChar(buf, "("); 80215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (expr->type) { 80225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_EMPTY: 80235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlBufferWriteChar(buf, "empty"); 80245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 80255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_FORBID: 80265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlBufferWriteChar(buf, "forbidden"); 80275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 80285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_ATOM: 80295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlBufferWriteCHAR(buf, expr->exp_str); 80305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 80315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_SEQ: 80325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = expr->exp_left; 80335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 80345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpDumpInt(buf, c, 1); 80355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 80365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpDumpInt(buf, c, 0); 80375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlBufferWriteChar(buf, " , "); 80385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = expr->exp_right; 80395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 80405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpDumpInt(buf, c, 1); 80415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 80425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpDumpInt(buf, c, 0); 80435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 80445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_OR: 80455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = expr->exp_left; 80465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 80475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpDumpInt(buf, c, 1); 80485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 80495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpDumpInt(buf, c, 0); 80505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlBufferWriteChar(buf, " | "); 80515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = expr->exp_right; 80525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 80535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpDumpInt(buf, c, 1); 80545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 80555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpDumpInt(buf, c, 0); 80565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 80575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_EXP_COUNT: { 80585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char rep[40]; 80595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = expr->exp_left; 80615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((c->type == XML_EXP_SEQ) || (c->type == XML_EXP_OR)) 80625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpDumpInt(buf, c, 1); 80635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 80645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpDumpInt(buf, c, 0); 80655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((expr->exp_min == 0) && (expr->exp_max == 1)) { 80665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep[0] = '?'; 80675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep[1] = 0; 80685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((expr->exp_min == 0) && (expr->exp_max == -1)) { 80695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep[0] = '*'; 80705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep[1] = 0; 80715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((expr->exp_min == 1) && (expr->exp_max == -1)) { 80725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep[0] = '+'; 80735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep[1] = 0; 80745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (expr->exp_max == expr->exp_min) { 80755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(rep, 39, "{%d}", expr->exp_min); 80765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (expr->exp_max < 0) { 80775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(rep, 39, "{%d,inf}", expr->exp_min); 80785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 80795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(rep, 39, "{%d,%d}", expr->exp_min, expr->exp_max); 80805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 80815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rep[39] = 0; 80825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlBufferWriteChar(buf, rep); 80835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 80845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 80855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 80865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Error in tree\n"); 80875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 80885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (glob) 80895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlBufferWriteChar(buf, ")"); 80905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 80915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 80925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpDump: 80935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @buf: a buffer to receive the output 80945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @expr: the compiled expression 80955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 80965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Serialize the expression as compiled to the buffer 80975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 80985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 80995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpDump(xmlBufferPtr buf, xmlExpNodePtr expr) { 81005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((buf == NULL) || (expr == NULL)) 81015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 81025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlExpDumpInt(buf, expr, 0); 81035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 81045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 81055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 81065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpMaxToken: 81075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @expr: a compiled expression 81085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 81095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Indicate the maximum number of input a expression can accept 81105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 81115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the maximum length or -1 in case of error 81125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 81135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 81145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpMaxToken(xmlExpNodePtr expr) { 81155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (expr == NULL) 81165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 81175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(expr->c_max); 81185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 81195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 81205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 81215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpCtxtNbNodes: 81225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an expression context 81235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 81245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Debugging facility provides the number of allocated nodes at a that point 81255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 81265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of nodes in use or -1 in case of error 81275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 81285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 81295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpCtxtNbNodes(xmlExpCtxtPtr ctxt) { 81305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 81315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 81325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ctxt->nb_nodes); 81335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 81345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 81355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 81365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlExpCtxtNbCons: 81375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an expression context 81385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 81395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Debugging facility provides the number of allocated nodes over lifetime 81405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 81415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of nodes ever allocated or -1 in case of error 81425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 81435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 81445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlExpCtxtNbCons(xmlExpCtxtPtr ctxt) { 81455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 81465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 81475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ctxt->nb_cons); 81485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 81495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 81505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* LIBXML_EXPR_ENABLED */ 81515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define bottom_xmlregexp 81525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "elfgcchack.h" 81535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* LIBXML_REGEXP_ENABLED */ 8154