📄 relaxng.c
字号:
/*
* relaxng.c : implementation of the Relax-NG handling and validity checking
*
* See Copyright for the status of this software.
*
* Daniel Veillard <veillard@redhat.com>
*/
/**
* TODO:
* - add support for DTD compatibility spec
* http://www.oasis-open.org/committees/relax-ng/compatibility-20011203.html
* - report better mem allocations pbms at runtime and abort immediately.
*/
#define IN_LIBXML
#include "libxml.h"
#ifdef LIBXML_SCHEMAS_ENABLED
#include <string.h>
#include <stdio.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/hash.h>
#include <libxml/uri.h>
#include <libxml/relaxng.h>
#include <libxml/xmlschemastypes.h>
#include <libxml/xmlautomata.h>
#include <libxml/xmlregexp.h>
#include <libxml/xmlschemastypes.h>
/*
* The Relax-NG namespace
*/
static const xmlChar *xmlRelaxNGNs = (const xmlChar *)
"http://relaxng.org/ns/structure/1.0";
#define IS_RELAXNG(node, type) \
((node != NULL) && (node->ns != NULL) && \
(xmlStrEqual(node->name, (const xmlChar *) type)) && \
(xmlStrEqual(node->ns->href, xmlRelaxNGNs)))
/* #define DEBUG 1 */
/* #define DEBUG_GRAMMAR 1 */
/* #define DEBUG_CONTENT 1 */
/* #define DEBUG_TYPE 1 */
/* #define DEBUG_VALID 1 */
/* #define DEBUG_INTERLEAVE 1 */
/* #define DEBUG_LIST 1 */
/* #define DEBUG_INCLUDE */
/* #define DEBUG_ERROR 1 */
/* #define DEBUG_COMPILE 1 */
/* #define DEBUG_PROGRESSIVE 1 */
#define MAX_ERROR 5
#define TODO \
xmlGenericError(xmlGenericErrorContext, \
"Unimplemented block at %s:%d\n", \
__FILE__, __LINE__);
typedef struct _xmlRelaxNGSchema xmlRelaxNGSchema;
typedef xmlRelaxNGSchema *xmlRelaxNGSchemaPtr;
typedef struct _xmlRelaxNGDefine xmlRelaxNGDefine;
typedef xmlRelaxNGDefine *xmlRelaxNGDefinePtr;
typedef struct _xmlRelaxNGDocument xmlRelaxNGDocument;
typedef xmlRelaxNGDocument *xmlRelaxNGDocumentPtr;
typedef struct _xmlRelaxNGInclude xmlRelaxNGInclude;
typedef xmlRelaxNGInclude *xmlRelaxNGIncludePtr;
typedef enum {
XML_RELAXNG_COMBINE_UNDEFINED = 0, /* undefined */
XML_RELAXNG_COMBINE_CHOICE, /* choice */
XML_RELAXNG_COMBINE_INTERLEAVE /* interleave */
} xmlRelaxNGCombine;
typedef enum {
XML_RELAXNG_CONTENT_ERROR = -1,
XML_RELAXNG_CONTENT_EMPTY = 0,
XML_RELAXNG_CONTENT_SIMPLE,
XML_RELAXNG_CONTENT_COMPLEX
} xmlRelaxNGContentType;
typedef struct _xmlRelaxNGGrammar xmlRelaxNGGrammar;
typedef xmlRelaxNGGrammar *xmlRelaxNGGrammarPtr;
struct _xmlRelaxNGGrammar {
xmlRelaxNGGrammarPtr parent; /* the parent grammar if any */
xmlRelaxNGGrammarPtr children; /* the children grammar if any */
xmlRelaxNGGrammarPtr next; /* the next grammar if any */
xmlRelaxNGDefinePtr start; /* <start> content */
xmlRelaxNGCombine combine; /* the default combine value */
xmlRelaxNGDefinePtr startList; /* list of <start> definitions */
xmlHashTablePtr defs; /* define* */
xmlHashTablePtr refs; /* references */
};
typedef enum {
XML_RELAXNG_NOOP = -1, /* a no operation from simplification */
XML_RELAXNG_EMPTY = 0, /* an empty pattern */
XML_RELAXNG_NOT_ALLOWED, /* not allowed top */
XML_RELAXNG_EXCEPT, /* except present in nameclass defs */
XML_RELAXNG_TEXT, /* textual content */
XML_RELAXNG_ELEMENT, /* an element */
XML_RELAXNG_DATATYPE, /* extenal data type definition */
XML_RELAXNG_PARAM, /* extenal data type parameter */
XML_RELAXNG_VALUE, /* value from an extenal data type definition */
XML_RELAXNG_LIST, /* a list of patterns */
XML_RELAXNG_ATTRIBUTE, /* an attrbute following a pattern */
XML_RELAXNG_DEF, /* a definition */
XML_RELAXNG_REF, /* reference to a definition */
XML_RELAXNG_EXTERNALREF, /* reference to an external def */
XML_RELAXNG_PARENTREF, /* reference to a def in the parent grammar */
XML_RELAXNG_OPTIONAL, /* optional patterns */
XML_RELAXNG_ZEROORMORE, /* zero or more non empty patterns */
XML_RELAXNG_ONEORMORE, /* one or more non empty patterns */
XML_RELAXNG_CHOICE, /* a choice between non empty patterns */
XML_RELAXNG_GROUP, /* a pair/group of non empty patterns */
XML_RELAXNG_INTERLEAVE, /* interleaving choice of non-empty patterns */
XML_RELAXNG_START /* Used to keep track of starts on grammars */
} xmlRelaxNGType;
#define IS_NULLABLE (1 << 0)
#define IS_NOT_NULLABLE (1 << 1)
#define IS_INDETERMINIST (1 << 2)
#define IS_MIXED (1 << 3)
#define IS_TRIABLE (1 << 4)
#define IS_PROCESSED (1 << 5)
#define IS_COMPILABLE (1 << 6)
#define IS_NOT_COMPILABLE (1 << 7)
struct _xmlRelaxNGDefine {
xmlRelaxNGType type; /* the type of definition */
xmlNodePtr node; /* the node in the source */
xmlChar *name; /* the element local name if present */
xmlChar *ns; /* the namespace local name if present */
xmlChar *value; /* value when available */
void *data; /* data lib or specific pointer */
xmlRelaxNGDefinePtr content; /* the expected content */
xmlRelaxNGDefinePtr parent; /* the parent definition, if any */
xmlRelaxNGDefinePtr next; /* list within grouping sequences */
xmlRelaxNGDefinePtr attrs; /* list of attributes for elements */
xmlRelaxNGDefinePtr nameClass; /* the nameClass definition if any */
xmlRelaxNGDefinePtr nextHash; /* next define in defs/refs hash tables */
short depth; /* used for the cycle detection */
short dflags; /* define related flags */
xmlRegexpPtr contModel; /* a compiled content model if available */
};
/**
* _xmlRelaxNG:
*
* A RelaxNGs definition
*/
struct _xmlRelaxNG {
void *_private; /* unused by the library for users or bindings */
xmlRelaxNGGrammarPtr topgrammar;
xmlDocPtr doc;
int idref; /* requires idref checking */
xmlHashTablePtr defs; /* define */
xmlHashTablePtr refs; /* references */
xmlRelaxNGDocumentPtr documents; /* all the documents loaded */
xmlRelaxNGIncludePtr includes; /* all the includes loaded */
int defNr; /* number of defines used */
xmlRelaxNGDefinePtr *defTab; /* pointer to the allocated definitions */
};
#define XML_RELAXNG_IN_ATTRIBUTE (1 << 0)
#define XML_RELAXNG_IN_ONEORMORE (1 << 1)
#define XML_RELAXNG_IN_LIST (1 << 2)
#define XML_RELAXNG_IN_DATAEXCEPT (1 << 3)
#define XML_RELAXNG_IN_START (1 << 4)
#define XML_RELAXNG_IN_OOMGROUP (1 << 5)
#define XML_RELAXNG_IN_OOMINTERLEAVE (1 << 6)
#define XML_RELAXNG_IN_EXTERNALREF (1 << 7)
#define XML_RELAXNG_IN_ANYEXCEPT (1 << 8)
#define XML_RELAXNG_IN_NSEXCEPT (1 << 9)
struct _xmlRelaxNGParserCtxt {
void *userData; /* user specific data block */
xmlRelaxNGValidityErrorFunc error; /* the callback in case of errors */
xmlRelaxNGValidityWarningFunc warning; /* the callback in case of warning */
xmlStructuredErrorFunc serror;
xmlRelaxNGValidErr err;
xmlRelaxNGPtr schema; /* The schema in use */
xmlRelaxNGGrammarPtr grammar; /* the current grammar */
xmlRelaxNGGrammarPtr parentgrammar; /* the parent grammar */
int flags; /* parser flags */
int nbErrors; /* number of errors at parse time */
int nbWarnings; /* number of warnings at parse time */
const xmlChar *define; /* the current define scope */
xmlRelaxNGDefinePtr def; /* the current define */
int nbInterleaves;
xmlHashTablePtr interleaves; /* keep track of all the interleaves */
xmlRelaxNGDocumentPtr documents; /* all the documents loaded */
xmlRelaxNGIncludePtr includes; /* all the includes loaded */
xmlChar *URL;
xmlDocPtr document;
int defNr; /* number of defines used */
int defMax; /* number of defines aloocated */
xmlRelaxNGDefinePtr *defTab; /* pointer to the allocated definitions */
const char *buffer;
int size;
/* the document stack */
xmlRelaxNGDocumentPtr doc; /* Current parsed external ref */
int docNr; /* Depth of the parsing stack */
int docMax; /* Max depth of the parsing stack */
xmlRelaxNGDocumentPtr *docTab; /* array of docs */
/* the include stack */
xmlRelaxNGIncludePtr inc; /* Current parsed include */
int incNr; /* Depth of the include parsing stack */
int incMax; /* Max depth of the parsing stack */
xmlRelaxNGIncludePtr *incTab; /* array of incs */
int idref; /* requires idref checking */
/* used to compile content models */
xmlAutomataPtr am; /* the automata */
xmlAutomataStatePtr state; /* used to build the automata */
int crng; /* compact syntax and other flags */
int freedoc; /* need to free the document */
};
#define FLAGS_IGNORABLE 1
#define FLAGS_NEGATIVE 2
#define FLAGS_MIXED_CONTENT 4
/**
* xmlRelaxNGInterleaveGroup:
*
* A RelaxNGs partition set associated to lists of definitions
*/
typedef struct _xmlRelaxNGInterleaveGroup xmlRelaxNGInterleaveGroup;
typedef xmlRelaxNGInterleaveGroup *xmlRelaxNGInterleaveGroupPtr;
struct _xmlRelaxNGInterleaveGroup {
xmlRelaxNGDefinePtr rule; /* the rule to satisfy */
xmlRelaxNGDefinePtr *defs; /* the array of element definitions */
xmlRelaxNGDefinePtr *attrs; /* the array of attributes definitions */
};
#define IS_DETERMINIST 1
#define IS_NEEDCHECK 2
/**
* xmlRelaxNGPartitions:
*
* A RelaxNGs partition associated to an interleave group
*/
typedef struct _xmlRelaxNGPartition xmlRelaxNGPartition;
typedef xmlRelaxNGPartition *xmlRelaxNGPartitionPtr;
struct _xmlRelaxNGPartition {
int nbgroups; /* number of groups in the partitions */
xmlHashTablePtr triage; /* hash table used to direct nodes to the
* right group when possible */
int flags; /* determinist ? */
xmlRelaxNGInterleaveGroupPtr *groups;
};
/**
* xmlRelaxNGValidState:
*
* A RelaxNGs validation state
*/
#define MAX_ATTR 20
typedef struct _xmlRelaxNGValidState xmlRelaxNGValidState;
typedef xmlRelaxNGValidState *xmlRelaxNGValidStatePtr;
struct _xmlRelaxNGValidState {
xmlNodePtr node; /* the current node */
xmlNodePtr seq; /* the sequence of children left to validate */
int nbAttrs; /* the number of attributes */
int maxAttrs; /* the size of attrs */
int nbAttrLeft; /* the number of attributes left to validate */
xmlChar *value; /* the value when operating on string */
xmlChar *endvalue; /* the end value when operating on string */
xmlAttrPtr *attrs; /* the array of attributes */
};
/**
* xmlRelaxNGStates:
*
* A RelaxNGs container for validation state
*/
typedef struct _xmlRelaxNGStates xmlRelaxNGStates;
typedef xmlRelaxNGStates *xmlRelaxNGStatesPtr;
struct _xmlRelaxNGStates {
int nbState; /* the number of states */
int maxState; /* the size of the array */
xmlRelaxNGValidStatePtr *tabState;
};
#define ERROR_IS_DUP 1
/**
* xmlRelaxNGValidError:
*
* A RelaxNGs validation error
*/
typedef struct _xmlRelaxNGValidError xmlRelaxNGValidError;
typedef xmlRelaxNGValidError *xmlRelaxNGValidErrorPtr;
struct _xmlRelaxNGValidError {
xmlRelaxNGValidErr err; /* the error number */
int flags; /* flags */
xmlNodePtr node; /* the current node */
xmlNodePtr seq; /* the current child */
const xmlChar *arg1; /* first arg */
const xmlChar *arg2; /* second arg */
};
/**
* xmlRelaxNGValidCtxt:
*
* A RelaxNGs validation context
*/
struct _xmlRelaxNGValidCtxt {
void *userData; /* user specific data block */
xmlRelaxNGValidityErrorFunc error; /* the callback in case of errors */
xmlRelaxNGValidityWarningFunc warning; /* the callback in case of warning */
xmlStructuredErrorFunc serror;
int nbErrors; /* number of errors in validation */
xmlRelaxNGPtr schema; /* The schema in use */
xmlDocPtr doc; /* the document being validated */
int flags; /* validation flags */
int depth; /* validation depth */
int idref; /* requires idref checking */
int errNo; /* the first error found */
/*
* Errors accumulated in branches may have to be stacked to be
* provided back when it's sure they affect validation.
*/
xmlRelaxNGValidErrorPtr err; /* Last error */
int errNr; /* Depth of the error stack */
int errMax; /* Max depth of the error stack */
xmlRelaxNGValidErrorPtr errTab; /* stack of errors */
xmlRelaxNGValidStatePtr state; /* the current validation state */
xmlRelaxNGStatesPtr states; /* the accumulated state list */
xmlRelaxNGStatesPtr freeState; /* the pool of free valid states */
int freeStatesNr;
int freeStatesMax;
xmlRelaxNGStatesPtr *freeStates; /* the pool of free state groups */
/*
* This is used for "progressive" validation
*/
xmlRegExecCtxtPtr elem; /* the current element regexp */
int elemNr; /* the number of element validated */
int elemMax; /* the max depth of elements */
xmlRegExecCtxtPtr *elemTab; /* the stack of regexp runtime */
int pstate; /* progressive state */
xmlNodePtr pnode; /* the current node */
xmlRelaxNGDefinePtr pdef; /* the non-streamable definition */
int perr; /* signal error in content model
* outside the regexp */
};
/**
* xmlRelaxNGInclude:
*
* Structure associated to a RelaxNGs document element
*/
struct _xmlRelaxNGInclude {
xmlRelaxNGIncludePtr next; /* keep a chain of includes */
xmlChar *href; /* the normalized href value */
xmlDocPtr doc; /* the associated XML document */
xmlRelaxNGDefinePtr content; /* the definitions */
xmlRelaxNGPtr schema; /* the schema */
};
/**
* xmlRelaxNGDocument:
*
* Structure associated to a RelaxNGs document element
*/
struct _xmlRelaxNGDocument {
xmlRelaxNGDocumentPtr next; /* keep a chain of documents */
xmlChar *href; /* the normalized href value */
xmlDocPtr doc; /* the associated XML document */
xmlRelaxNGDefinePtr content; /* the definitions */
xmlRelaxNGPtr schema; /* the schema */
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -