OLD | NEW |
1 /* | 1 /* |
2 * relaxng.c : implementation of the Relax-NG handling and validity checking | 2 * relaxng.c : implementation of the Relax-NG handling and validity checking |
3 * | 3 * |
4 * See Copyright for the status of this software. | 4 * See Copyright for the status of this software. |
5 * | 5 * |
6 * Daniel Veillard <veillard@redhat.com> | 6 * Daniel Veillard <veillard@redhat.com> |
7 */ | 7 */ |
8 | 8 |
9 /** | 9 /** |
10 * TODO: | 10 * TODO: |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 } xmlRelaxNGType; | 142 } xmlRelaxNGType; |
143 | 143 |
144 #define IS_NULLABLE (1 << 0) | 144 #define IS_NULLABLE (1 << 0) |
145 #define IS_NOT_NULLABLE (1 << 1) | 145 #define IS_NOT_NULLABLE (1 << 1) |
146 #define IS_INDETERMINIST (1 << 2) | 146 #define IS_INDETERMINIST (1 << 2) |
147 #define IS_MIXED (1 << 3) | 147 #define IS_MIXED (1 << 3) |
148 #define IS_TRIABLE (1 << 4) | 148 #define IS_TRIABLE (1 << 4) |
149 #define IS_PROCESSED (1 << 5) | 149 #define IS_PROCESSED (1 << 5) |
150 #define IS_COMPILABLE (1 << 6) | 150 #define IS_COMPILABLE (1 << 6) |
151 #define IS_NOT_COMPILABLE (1 << 7) | 151 #define IS_NOT_COMPILABLE (1 << 7) |
| 152 #define IS_EXTERNAL_REF (1 << 8) |
152 | 153 |
153 struct _xmlRelaxNGDefine { | 154 struct _xmlRelaxNGDefine { |
154 xmlRelaxNGType type; /* the type of definition */ | 155 xmlRelaxNGType type; /* the type of definition */ |
155 xmlNodePtr node; /* the node in the source */ | 156 xmlNodePtr node; /* the node in the source */ |
156 xmlChar *name; /* the element local name if present */ | 157 xmlChar *name; /* the element local name if present */ |
157 xmlChar *ns; /* the namespace local name if present */ | 158 xmlChar *ns; /* the namespace local name if present */ |
158 xmlChar *value; /* value when available */ | 159 xmlChar *value; /* value when available */ |
159 void *data; /* data lib or specific pointer */ | 160 void *data; /* data lib or specific pointer */ |
160 xmlRelaxNGDefinePtr content; /* the expected content */ | 161 xmlRelaxNGDefinePtr content; /* the expected content */ |
161 xmlRelaxNGDefinePtr parent; /* the parent definition, if any */ | 162 xmlRelaxNGDefinePtr parent; /* the parent definition, if any */ |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 * xmlRelaxNGDocument: | 408 * xmlRelaxNGDocument: |
408 * | 409 * |
409 * Structure associated to a RelaxNGs document element | 410 * Structure associated to a RelaxNGs document element |
410 */ | 411 */ |
411 struct _xmlRelaxNGDocument { | 412 struct _xmlRelaxNGDocument { |
412 xmlRelaxNGDocumentPtr next; /* keep a chain of documents */ | 413 xmlRelaxNGDocumentPtr next; /* keep a chain of documents */ |
413 xmlChar *href; /* the normalized href value */ | 414 xmlChar *href; /* the normalized href value */ |
414 xmlDocPtr doc; /* the associated XML document */ | 415 xmlDocPtr doc; /* the associated XML document */ |
415 xmlRelaxNGDefinePtr content; /* the definitions */ | 416 xmlRelaxNGDefinePtr content; /* the definitions */ |
416 xmlRelaxNGPtr schema; /* the schema */ | 417 xmlRelaxNGPtr schema; /* the schema */ |
| 418 int externalRef; /* 1 if an external ref */ |
417 }; | 419 }; |
418 | 420 |
419 | 421 |
420 /************************************************************************ | 422 /************************************************************************ |
421 * * | 423 * * |
422 * Some factorized error routines * | 424 * Some factorized error routines * |
423 * * | 425 * * |
424 ************************************************************************/ | 426 ************************************************************************/ |
425 | 427 |
426 /** | 428 /** |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 * Allocate a new RelaxNG validation state container | 1001 * Allocate a new RelaxNG validation state container |
1000 * | 1002 * |
1001 * Returns the newly allocated structure or NULL in case or error | 1003 * Returns the newly allocated structure or NULL in case or error |
1002 */ | 1004 */ |
1003 static xmlRelaxNGStatesPtr | 1005 static xmlRelaxNGStatesPtr |
1004 xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size) | 1006 xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size) |
1005 { | 1007 { |
1006 xmlRelaxNGStatesPtr ret; | 1008 xmlRelaxNGStatesPtr ret; |
1007 | 1009 |
1008 if ((ctxt != NULL) && | 1010 if ((ctxt != NULL) && |
1009 (ctxt->freeState != NULL) && (ctxt->freeStatesNr > 0)) { | 1011 (ctxt->freeStates != NULL) && (ctxt->freeStatesNr > 0)) { |
1010 ctxt->freeStatesNr--; | 1012 ctxt->freeStatesNr--; |
1011 ret = ctxt->freeStates[ctxt->freeStatesNr]; | 1013 ret = ctxt->freeStates[ctxt->freeStatesNr]; |
1012 ret->nbState = 0; | 1014 ret->nbState = 0; |
1013 return (ret); | 1015 return (ret); |
1014 } | 1016 } |
1015 if (size < 16) | 1017 if (size < 16) |
1016 size = 16; | 1018 size = 16; |
1017 | 1019 |
1018 ret = (xmlRelaxNGStatesPtr) xmlMalloc(sizeof(xmlRelaxNGStates) + | 1020 ret = (xmlRelaxNGStatesPtr) xmlMalloc(sizeof(xmlRelaxNGStates) + |
1019 (size - | 1021 (size - |
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1963 if (ret == NULL) { | 1965 if (ret == NULL) { |
1964 xmlRngPErr(ctxt, (xmlNodePtr) doc, XML_ERR_NO_MEMORY, | 1966 xmlRngPErr(ctxt, (xmlNodePtr) doc, XML_ERR_NO_MEMORY, |
1965 "xmlRelaxNG: allocate memory for doc %s\n", URL, NULL); | 1967 "xmlRelaxNG: allocate memory for doc %s\n", URL, NULL); |
1966 xmlFreeDoc(doc); | 1968 xmlFreeDoc(doc); |
1967 return (NULL); | 1969 return (NULL); |
1968 } | 1970 } |
1969 memset(ret, 0, sizeof(xmlRelaxNGDocument)); | 1971 memset(ret, 0, sizeof(xmlRelaxNGDocument)); |
1970 ret->doc = doc; | 1972 ret->doc = doc; |
1971 ret->href = xmlStrdup(URL); | 1973 ret->href = xmlStrdup(URL); |
1972 ret->next = ctxt->documents; | 1974 ret->next = ctxt->documents; |
| 1975 ret->externalRef = 1; |
1973 ctxt->documents = ret; | 1976 ctxt->documents = ret; |
1974 | 1977 |
1975 /* | 1978 /* |
1976 * transmit the ns if needed | 1979 * transmit the ns if needed |
1977 */ | 1980 */ |
1978 if (ns != NULL) { | 1981 if (ns != NULL) { |
1979 root = xmlDocGetRootElement(doc); | 1982 root = xmlDocGetRootElement(doc); |
1980 if (root != NULL) { | 1983 if (root != NULL) { |
1981 if (xmlHasProp(root, BAD_CAST "ns") == NULL) { | 1984 if (xmlHasProp(root, BAD_CAST "ns") == NULL) { |
1982 xmlSetProp(root, BAD_CAST "ns", ns); | 1985 xmlSetProp(root, BAD_CAST "ns", ns); |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2365 * real cause of the problem. | 2368 * real cause of the problem. |
2366 */ | 2369 */ |
2367 if (ctxt->errNr != 0) | 2370 if (ctxt->errNr != 0) |
2368 xmlRelaxNGDumpValidError(ctxt); | 2371 xmlRelaxNGDumpValidError(ctxt); |
2369 if (ctxt->state != NULL) { | 2372 if (ctxt->state != NULL) { |
2370 node = ctxt->state->node; | 2373 node = ctxt->state->node; |
2371 seq = ctxt->state->seq; | 2374 seq = ctxt->state->seq; |
2372 } else { | 2375 } else { |
2373 node = seq = NULL; | 2376 node = seq = NULL; |
2374 } | 2377 } |
| 2378 if ((node == NULL) && (seq == NULL)) { |
| 2379 node = ctxt->pnode; |
| 2380 } |
2375 xmlRelaxNGShowValidError(ctxt, err, node, seq, arg1, arg2); | 2381 xmlRelaxNGShowValidError(ctxt, err, node, seq, arg1, arg2); |
2376 } | 2382 } |
2377 /* | 2383 /* |
2378 * Stack the error for later processing if needed | 2384 * Stack the error for later processing if needed |
2379 */ | 2385 */ |
2380 else { | 2386 else { |
2381 xmlRelaxNGValidErrorPush(ctxt, err, arg1, arg2, dup); | 2387 xmlRelaxNGValidErrorPush(ctxt, err, arg1, arg2, dup); |
2382 } | 2388 } |
2383 } | 2389 } |
2384 | 2390 |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2842 | 2848 |
2843 /************************************************************************ | 2849 /************************************************************************ |
2844 * * | 2850 * * |
2845 * Compiling element content into regexp * | 2851 * Compiling element content into regexp * |
2846 * * | 2852 * * |
2847 * Sometime the element content can be compiled into a pure regexp, * | 2853 * Sometime the element content can be compiled into a pure regexp, * |
2848 * This allows a faster execution and streamability at that level * | 2854 * This allows a faster execution and streamability at that level * |
2849 * * | 2855 * * |
2850 ************************************************************************/ | 2856 ************************************************************************/ |
2851 | 2857 |
| 2858 /* from automata.c but not exported */ |
| 2859 void xmlAutomataSetFlags(xmlAutomataPtr am, int flags); |
| 2860 |
| 2861 |
2852 static int xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt, | 2862 static int xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt, |
2853 xmlRelaxNGDefinePtr def); | 2863 xmlRelaxNGDefinePtr def); |
2854 | 2864 |
2855 /** | 2865 /** |
2856 * xmlRelaxNGIsCompileable: | 2866 * xmlRelaxNGIsCompileable: |
2857 * @define: the definition to check | 2867 * @define: the definition to check |
2858 * | 2868 * |
2859 * Check if a definition is nullable. | 2869 * Check if a definition is nullable. |
2860 * | 2870 * |
2861 * Returns 1 if yes, 0 if no and -1 in case of error | 2871 * Returns 1 if yes, 0 if no and -1 in case of error |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3025 if ((xmlRelaxNGIsCompileable(def) == 1) && (def->depth != -25)) { | 3035 if ((xmlRelaxNGIsCompileable(def) == 1) && (def->depth != -25)) { |
3026 xmlAutomataPtr oldam = ctxt->am; | 3036 xmlAutomataPtr oldam = ctxt->am; |
3027 xmlAutomataStatePtr oldstate = ctxt->state; | 3037 xmlAutomataStatePtr oldstate = ctxt->state; |
3028 | 3038 |
3029 def->depth = -25; | 3039 def->depth = -25; |
3030 | 3040 |
3031 list = def->content; | 3041 list = def->content; |
3032 ctxt->am = xmlNewAutomata(); | 3042 ctxt->am = xmlNewAutomata(); |
3033 if (ctxt->am == NULL) | 3043 if (ctxt->am == NULL) |
3034 return (-1); | 3044 return (-1); |
| 3045 |
| 3046 /* |
| 3047 * assume identical strings but not same pointer are different |
| 3048 * atoms, needed for non-determinism detection |
| 3049 * That way if 2 elements with the same name are in a choice |
| 3050 * branch the automata is found non-deterministic and |
| 3051 * we fallback to the normal validation which does the right |
| 3052 * thing of exploring both choices. |
| 3053 */ |
| 3054 xmlAutomataSetFlags(ctxt->am, 1); |
| 3055 |
3035 ctxt->state = xmlAutomataGetInitState(ctxt->am); | 3056 ctxt->state = xmlAutomataGetInitState(ctxt->am); |
3036 while (list != NULL) { | 3057 while (list != NULL) { |
3037 xmlRelaxNGCompile(ctxt, list); | 3058 xmlRelaxNGCompile(ctxt, list); |
3038 list = list->next; | 3059 list = list->next; |
3039 } | 3060 } |
3040 xmlAutomataSetFinalState(ctxt->am, ctxt->state); | 3061 xmlAutomataSetFinalState(ctxt->am, ctxt->state); |
3041 def->contModel = xmlAutomataCompile(ctxt->am); | 3062 def->contModel = xmlAutomataCompile(ctxt->am); |
3042 xmlRegexpIsDeterminist(def->contModel); | 3063 xmlRegexpIsDeterminist(def->contModel); |
3043 | 3064 |
3044 xmlFreeAutomata(ctxt->am); | 3065 xmlFreeAutomata(ctxt->am); |
(...skipping 11 matching lines...) Expand all Loading... |
3056 if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) { | 3077 if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) { |
3057 xmlAutomataPtr oldam = ctxt->am; | 3078 xmlAutomataPtr oldam = ctxt->am; |
3058 xmlAutomataStatePtr oldstate = ctxt->state; | 3079 xmlAutomataStatePtr oldstate = ctxt->state; |
3059 | 3080 |
3060 def->depth = -25; | 3081 def->depth = -25; |
3061 | 3082 |
3062 list = def->content; | 3083 list = def->content; |
3063 ctxt->am = xmlNewAutomata(); | 3084 ctxt->am = xmlNewAutomata(); |
3064 if (ctxt->am == NULL) | 3085 if (ctxt->am == NULL) |
3065 return (-1); | 3086 return (-1); |
| 3087 xmlAutomataSetFlags(ctxt->am, 1); |
3066 ctxt->state = xmlAutomataGetInitState(ctxt->am); | 3088 ctxt->state = xmlAutomataGetInitState(ctxt->am); |
3067 while (list != NULL) { | 3089 while (list != NULL) { |
3068 xmlRelaxNGCompile(ctxt, list); | 3090 xmlRelaxNGCompile(ctxt, list); |
3069 list = list->next; | 3091 list = list->next; |
3070 } | 3092 } |
3071 xmlAutomataSetFinalState(ctxt->am, ctxt->state); | 3093 xmlAutomataSetFinalState(ctxt->am, ctxt->state); |
3072 def->contModel = xmlAutomataCompile(ctxt->am); | 3094 def->contModel = xmlAutomataCompile(ctxt->am); |
3073 if (!xmlRegexpIsDeterminist(def->contModel)) { | 3095 if (!xmlRegexpIsDeterminist(def->contModel)) { |
| 3096 #ifdef DEBUG_COMPILE |
| 3097 xmlGenericError(xmlGenericErrorContext, |
| 3098 "Content model not determinist %s\n", |
| 3099 def->name); |
| 3100 #endif |
3074 /* | 3101 /* |
3075 * we can only use the automata if it is determinist | 3102 * we can only use the automata if it is determinist |
3076 */ | 3103 */ |
3077 xmlRegFreeRegexp(def->contModel); | 3104 xmlRegFreeRegexp(def->contModel); |
3078 def->contModel = NULL; | 3105 def->contModel = NULL; |
3079 } | 3106 } |
3080 xmlFreeAutomata(ctxt->am); | 3107 xmlFreeAutomata(ctxt->am); |
3081 ctxt->state = oldstate; | 3108 ctxt->state = oldstate; |
3082 ctxt->am = oldam; | 3109 ctxt->am = oldam; |
3083 } else { | 3110 } else { |
3084 xmlAutomataPtr oldam = ctxt->am; | 3111 xmlAutomataPtr oldam = ctxt->am; |
3085 | 3112 |
3086 /* | 3113 /* |
3087 * we can't build the content model for this element content | 3114 * we can't build the content model for this element content |
3088 * but it still might be possible to build it for some of its | 3115 * but it still might be possible to build it for some of its |
3089 * children, recurse. | 3116 * children, recurse. |
3090 */ | 3117 */ |
3091 ret = xmlRelaxNGTryCompile(ctxt, def); | 3118 ret = xmlRelaxNGTryCompile(ctxt, def); |
3092 ctxt->am = oldam; | 3119 ctxt->am = oldam; |
3093 } | 3120 } |
3094 break; | 3121 break; |
3095 case XML_RELAXNG_NOOP: | 3122 case XML_RELAXNG_NOOP: |
3096 ret = xmlRelaxNGCompile(ctxt, def->content); | 3123 ret = xmlRelaxNGCompile(ctxt, def->content); |
3097 break; | 3124 break; |
3098 case XML_RELAXNG_OPTIONAL:{ | 3125 case XML_RELAXNG_OPTIONAL:{ |
3099 xmlAutomataStatePtr oldstate = ctxt->state; | 3126 xmlAutomataStatePtr oldstate = ctxt->state; |
3100 | 3127 |
3101 xmlRelaxNGCompile(ctxt, def->content); | 3128 list = def->content; |
| 3129 while (list != NULL) { |
| 3130 xmlRelaxNGCompile(ctxt, list); |
| 3131 list = list->next; |
| 3132 } |
3102 xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state); | 3133 xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state); |
3103 break; | 3134 break; |
3104 } | 3135 } |
3105 case XML_RELAXNG_ZEROORMORE:{ | 3136 case XML_RELAXNG_ZEROORMORE:{ |
3106 xmlAutomataStatePtr oldstate; | 3137 xmlAutomataStatePtr oldstate; |
3107 | 3138 |
3108 ctxt->state = | 3139 ctxt->state = |
3109 xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); | 3140 xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); |
3110 oldstate = ctxt->state; | 3141 oldstate = ctxt->state; |
3111 list = def->content; | 3142 list = def->content; |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3433 * Applies algorithm from 4.3. datatypeLibrary attribute | 3464 * Applies algorithm from 4.3. datatypeLibrary attribute |
3434 * | 3465 * |
3435 * Returns the datatypeLibary value or NULL if not found | 3466 * Returns the datatypeLibary value or NULL if not found |
3436 */ | 3467 */ |
3437 static xmlChar * | 3468 static xmlChar * |
3438 xmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED, | 3469 xmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED, |
3439 xmlNodePtr node) | 3470 xmlNodePtr node) |
3440 { | 3471 { |
3441 xmlChar *ret, *escape; | 3472 xmlChar *ret, *escape; |
3442 | 3473 |
| 3474 if (node == NULL) |
| 3475 return(NULL); |
| 3476 |
3443 if ((IS_RELAXNG(node, "data")) || (IS_RELAXNG(node, "value"))) { | 3477 if ((IS_RELAXNG(node, "data")) || (IS_RELAXNG(node, "value"))) { |
3444 ret = xmlGetProp(node, BAD_CAST "datatypeLibrary"); | 3478 ret = xmlGetProp(node, BAD_CAST "datatypeLibrary"); |
3445 if (ret != NULL) { | 3479 if (ret != NULL) { |
3446 if (ret[0] == 0) { | 3480 if (ret[0] == 0) { |
3447 xmlFree(ret); | 3481 xmlFree(ret); |
3448 return (NULL); | 3482 return (NULL); |
3449 } | 3483 } |
3450 escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?"); | 3484 escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?"); |
3451 if (escape == NULL) { | 3485 if (escape == NULL) { |
3452 return (ret); | 3486 return (ret); |
(...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4609 prev = prev->nextHash; | 4643 prev = prev->nextHash; |
4610 prev->nextHash = def; | 4644 prev->nextHash = def; |
4611 } | 4645 } |
4612 } | 4646 } |
4613 } | 4647 } |
4614 } | 4648 } |
4615 return (ret); | 4649 return (ret); |
4616 } | 4650 } |
4617 | 4651 |
4618 /** | 4652 /** |
| 4653 * xmlRelaxNGParseImportRef: |
| 4654 * @payload: the parser context |
| 4655 * @data: the current grammar |
| 4656 * @name: the reference name |
| 4657 * |
| 4658 * Import import one references into the current grammar |
| 4659 */ |
| 4660 static void |
| 4661 xmlRelaxNGParseImportRef(void *payload, void *data, xmlChar *name) { |
| 4662 xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data; |
| 4663 xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload; |
| 4664 int tmp; |
| 4665 |
| 4666 def->dflags |= IS_EXTERNAL_REF; |
| 4667 |
| 4668 tmp = xmlHashAddEntry(ctxt->grammar->refs, name, def); |
| 4669 if (tmp < 0) { |
| 4670 xmlRelaxNGDefinePtr prev; |
| 4671 |
| 4672 prev = (xmlRelaxNGDefinePtr) |
| 4673 xmlHashLookup(ctxt->grammar->refs, def->name); |
| 4674 if (prev == NULL) { |
| 4675 if (def->name != NULL) { |
| 4676 xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED, |
| 4677 "Error refs definitions '%s'\n", |
| 4678 def->name, NULL); |
| 4679 } else { |
| 4680 xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED, |
| 4681 "Error refs definitions\n", |
| 4682 NULL, NULL); |
| 4683 } |
| 4684 } else { |
| 4685 def->nextHash = prev->nextHash; |
| 4686 prev->nextHash = def; |
| 4687 } |
| 4688 } |
| 4689 } |
| 4690 |
| 4691 /** |
| 4692 * xmlRelaxNGParseImportRefs: |
| 4693 * @ctxt: the parser context |
| 4694 * @grammar: the sub grammar |
| 4695 * |
| 4696 * Import references from the subgrammar into the current grammar |
| 4697 * |
| 4698 * Returns 0 in case of success, -1 in case of failure |
| 4699 */ |
| 4700 static int |
| 4701 xmlRelaxNGParseImportRefs(xmlRelaxNGParserCtxtPtr ctxt, |
| 4702 xmlRelaxNGGrammarPtr grammar) { |
| 4703 if ((ctxt == NULL) || (grammar == NULL) || (ctxt->grammar == NULL)) |
| 4704 return(-1); |
| 4705 if (grammar->refs == NULL) |
| 4706 return(0); |
| 4707 if (ctxt->grammar->refs == NULL) |
| 4708 ctxt->grammar->refs = xmlHashCreate(10); |
| 4709 if (ctxt->grammar->refs == NULL) { |
| 4710 xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED, |
| 4711 "Could not create references hash\n", NULL, NULL); |
| 4712 return(-1); |
| 4713 } |
| 4714 xmlHashScan(grammar->refs, xmlRelaxNGParseImportRef, ctxt); |
| 4715 return(0); |
| 4716 } |
| 4717 |
| 4718 /** |
4619 * xmlRelaxNGProcessExternalRef: | 4719 * xmlRelaxNGProcessExternalRef: |
4620 * @ctxt: the parser context | 4720 * @ctxt: the parser context |
4621 * @node: the externlRef node | 4721 * @node: the externlRef node |
4622 * | 4722 * |
4623 * Process and compile an externlRef node | 4723 * Process and compile an externlRef node |
4624 * | 4724 * |
4625 * Returns the xmlRelaxNGDefinePtr or NULL in case of error | 4725 * Returns the xmlRelaxNGDefinePtr or NULL in case of error |
4626 */ | 4726 */ |
4627 static xmlRelaxNGDefinePtr | 4727 static xmlRelaxNGDefinePtr |
4628 xmlRelaxNGProcessExternalRef(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) | 4728 xmlRelaxNGProcessExternalRef(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4676 /* | 4776 /* |
4677 * Parsing to get a precompiled schemas. | 4777 * Parsing to get a precompiled schemas. |
4678 */ | 4778 */ |
4679 oldflags = ctxt->flags; | 4779 oldflags = ctxt->flags; |
4680 ctxt->flags |= XML_RELAXNG_IN_EXTERNALREF; | 4780 ctxt->flags |= XML_RELAXNG_IN_EXTERNALREF; |
4681 docu->schema = xmlRelaxNGParseDocument(ctxt, root); | 4781 docu->schema = xmlRelaxNGParseDocument(ctxt, root); |
4682 ctxt->flags = oldflags; | 4782 ctxt->flags = oldflags; |
4683 if ((docu->schema != NULL) && | 4783 if ((docu->schema != NULL) && |
4684 (docu->schema->topgrammar != NULL)) { | 4784 (docu->schema->topgrammar != NULL)) { |
4685 docu->content = docu->schema->topgrammar->start; | 4785 docu->content = docu->schema->topgrammar->start; |
| 4786 if (docu->schema->topgrammar->refs) |
| 4787 xmlRelaxNGParseImportRefs(ctxt, docu->schema->topgrammar); |
4686 } | 4788 } |
4687 | 4789 |
4688 /* | 4790 /* |
4689 * the externalRef may be reused in a different ns context | 4791 * the externalRef may be reused in a different ns context |
4690 */ | 4792 */ |
4691 if (newNs == 1) { | 4793 if (newNs == 1) { |
4692 xmlUnsetProp(root, BAD_CAST "ns"); | 4794 xmlUnsetProp(root, BAD_CAST "ns"); |
4693 } | 4795 } |
4694 } | 4796 } |
4695 def->content = docu->content; | 4797 def->content = docu->content; |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5260 last->next = tmp; | 5362 last->next = tmp; |
5261 last = tmp; | 5363 last = tmp; |
5262 } | 5364 } |
5263 } | 5365 } |
5264 child = child->next; | 5366 child = child->next; |
5265 } | 5367 } |
5266 } | 5368 } |
5267 } else { | 5369 } else { |
5268 xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_CONTENT, | 5370 xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_CONTENT, |
5269 "expecting name, anyName, nsName or choice : got %s\n", | 5371 "expecting name, anyName, nsName or choice : got %s\n", |
5270 node->name, NULL); | 5372 (node == NULL ? (const xmlChar *) "nothing" : node->name), |
| 5373 » » NULL); |
5271 return (NULL); | 5374 return (NULL); |
5272 } | 5375 } |
5273 if (ret != def) { | 5376 if (ret != def) { |
5274 if (def->nameClass == NULL) { | 5377 if (def->nameClass == NULL) { |
5275 def->nameClass = ret; | 5378 def->nameClass = ret; |
5276 } else { | 5379 } else { |
5277 tmp = def->nameClass; | 5380 tmp = def->nameClass; |
5278 while (tmp->next != NULL) { | 5381 while (tmp->next != NULL) { |
5279 tmp = tmp->next; | 5382 tmp = tmp->next; |
5280 } | 5383 } |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5562 * element of a given grammar using the same name. | 5665 * element of a given grammar using the same name. |
5563 */ | 5666 */ |
5564 static void | 5667 static void |
5565 xmlRelaxNGCheckReference(xmlRelaxNGDefinePtr ref, | 5668 xmlRelaxNGCheckReference(xmlRelaxNGDefinePtr ref, |
5566 xmlRelaxNGParserCtxtPtr ctxt, | 5669 xmlRelaxNGParserCtxtPtr ctxt, |
5567 const xmlChar * name) | 5670 const xmlChar * name) |
5568 { | 5671 { |
5569 xmlRelaxNGGrammarPtr grammar; | 5672 xmlRelaxNGGrammarPtr grammar; |
5570 xmlRelaxNGDefinePtr def, cur; | 5673 xmlRelaxNGDefinePtr def, cur; |
5571 | 5674 |
| 5675 /* |
| 5676 * Those rules don't apply to imported ref from xmlRelaxNGParseImportRef |
| 5677 */ |
| 5678 if (ref->dflags & IS_EXTERNAL_REF) |
| 5679 return; |
| 5680 |
5572 grammar = ctxt->grammar; | 5681 grammar = ctxt->grammar; |
5573 if (grammar == NULL) { | 5682 if (grammar == NULL) { |
5574 xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR, | 5683 xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR, |
5575 "Internal error: no grammar in CheckReference %s\n", | 5684 "Internal error: no grammar in CheckReference %s\n", |
5576 name, NULL); | 5685 name, NULL); |
5577 return; | 5686 return; |
5578 } | 5687 } |
5579 if (ref->content != NULL) { | 5688 if (ref->content != NULL) { |
5580 xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR, | 5689 xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR, |
5581 "Internal error: reference has content in CheckReference %s\n
", | 5690 "Internal error: reference has content in CheckReference %s\n
", |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6126 * | 6235 * |
6127 * Check for rules in section 7.1 and 7.2 | 6236 * Check for rules in section 7.1 and 7.2 |
6128 * | 6237 * |
6129 * Returns the content type of @cur | 6238 * Returns the content type of @cur |
6130 */ | 6239 */ |
6131 static xmlRelaxNGContentType | 6240 static xmlRelaxNGContentType |
6132 xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt, | 6241 xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt, |
6133 xmlRelaxNGDefinePtr cur, int flags, | 6242 xmlRelaxNGDefinePtr cur, int flags, |
6134 xmlRelaxNGType ptype) | 6243 xmlRelaxNGType ptype) |
6135 { | 6244 { |
6136 int nflags = flags; | 6245 int nflags; |
6137 xmlRelaxNGContentType ret, tmp, val = XML_RELAXNG_CONTENT_EMPTY; | 6246 xmlRelaxNGContentType ret, tmp, val = XML_RELAXNG_CONTENT_EMPTY; |
6138 | 6247 |
6139 while (cur != NULL) { | 6248 while (cur != NULL) { |
6140 ret = XML_RELAXNG_CONTENT_EMPTY; | 6249 ret = XML_RELAXNG_CONTENT_EMPTY; |
6141 if ((cur->type == XML_RELAXNG_REF) || | 6250 if ((cur->type == XML_RELAXNG_REF) || |
6142 (cur->type == XML_RELAXNG_PARENTREF)) { | 6251 (cur->type == XML_RELAXNG_PARENTREF)) { |
6143 /* | 6252 /* |
6144 * This should actually be caught by list//element(ref) at the | 6253 * This should actually be caught by list//element(ref) at the |
6145 * element boundaries, c.f. Bug #159968 local refs are dropped | 6254 * element boundaries, c.f. Bug #159968 local refs are dropped |
6146 * in step 4.19. | 6255 * in step 4.19. |
6147 */ | 6256 */ |
6148 #if 0 | 6257 #if 0 |
6149 if (flags & XML_RELAXNG_IN_LIST) { | 6258 if (flags & XML_RELAXNG_IN_LIST) { |
6150 xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_REF, | 6259 xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_REF, |
6151 "Found forbidden pattern list//ref\n", NULL, | 6260 "Found forbidden pattern list//ref\n", NULL, |
6152 NULL); | 6261 NULL); |
6153 } | 6262 } |
6154 #endif | 6263 #endif |
6155 if (flags & XML_RELAXNG_IN_DATAEXCEPT) { | 6264 if (flags & XML_RELAXNG_IN_DATAEXCEPT) { |
6156 xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_REF, | 6265 xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_REF, |
6157 "Found forbidden pattern data/except//ref\n", | 6266 "Found forbidden pattern data/except//ref\n", |
6158 NULL, NULL); | 6267 NULL, NULL); |
6159 } | 6268 } |
| 6269 if (cur->content == NULL) { |
| 6270 if (cur->type == XML_RELAXNG_PARENTREF) |
| 6271 xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF, |
| 6272 "Internal found no define for parent refs\n", |
| 6273 NULL, NULL); |
| 6274 else |
| 6275 xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF, |
| 6276 "Internal found no define for ref %s\n", |
| 6277 (cur->name ? cur->name: BAD_CAST "null"), NULL); |
| 6278 } |
6160 if (cur->depth > -4) { | 6279 if (cur->depth > -4) { |
6161 cur->depth = -4; | 6280 cur->depth = -4; |
6162 ret = xmlRelaxNGCheckRules(ctxt, cur->content, | 6281 ret = xmlRelaxNGCheckRules(ctxt, cur->content, |
6163 flags, cur->type); | 6282 flags, cur->type); |
6164 cur->depth = ret - 15; | 6283 cur->depth = ret - 15; |
6165 } else if (cur->depth == -4) { | 6284 } else if (cur->depth == -4) { |
6166 ret = XML_RELAXNG_CONTENT_COMPLEX; | 6285 ret = XML_RELAXNG_CONTENT_COMPLEX; |
6167 } else { | 6286 } else { |
6168 ret = (xmlRelaxNGContentType) (cur->depth + 15); | 6287 ret = (xmlRelaxNGContentType) (cur->depth + 15); |
6169 } | 6288 } |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6401 ret = | 6520 ret = |
6402 xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type); | 6521 xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type); |
6403 } else { | 6522 } else { |
6404 ret = | 6523 ret = |
6405 xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type); | 6524 xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type); |
6406 } | 6525 } |
6407 cur = cur->next; | 6526 cur = cur->next; |
6408 if (ptype == XML_RELAXNG_GROUP) { | 6527 if (ptype == XML_RELAXNG_GROUP) { |
6409 val = xmlRelaxNGGroupContentType(val, ret); | 6528 val = xmlRelaxNGGroupContentType(val, ret); |
6410 } else if (ptype == XML_RELAXNG_INTERLEAVE) { | 6529 } else if (ptype == XML_RELAXNG_INTERLEAVE) { |
| 6530 /* |
| 6531 * TODO: scan complain that tmp is never used, seems on purpose |
| 6532 * need double-checking |
| 6533 */ |
6411 tmp = xmlRelaxNGGroupContentType(val, ret); | 6534 tmp = xmlRelaxNGGroupContentType(val, ret); |
6412 if (tmp != XML_RELAXNG_CONTENT_ERROR) | 6535 if (tmp != XML_RELAXNG_CONTENT_ERROR) |
6413 tmp = xmlRelaxNGMaxContentType(val, ret); | 6536 tmp = xmlRelaxNGMaxContentType(val, ret); |
6414 } else if (ptype == XML_RELAXNG_CHOICE) { | 6537 } else if (ptype == XML_RELAXNG_CHOICE) { |
6415 val = xmlRelaxNGMaxContentType(val, ret); | 6538 val = xmlRelaxNGMaxContentType(val, ret); |
6416 } else if (ptype == XML_RELAXNG_LIST) { | 6539 } else if (ptype == XML_RELAXNG_LIST) { |
6417 val = XML_RELAXNG_CONTENT_SIMPLE; | 6540 val = XML_RELAXNG_CONTENT_SIMPLE; |
6418 } else if (ptype == XML_RELAXNG_EXCEPT) { | 6541 } else if (ptype == XML_RELAXNG_EXCEPT) { |
6419 if (ret == XML_RELAXNG_CONTENT_ERROR) | 6542 if (ret == XML_RELAXNG_CONTENT_ERROR) |
6420 val = XML_RELAXNG_CONTENT_ERROR; | 6543 val = XML_RELAXNG_CONTENT_ERROR; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6488 } | 6611 } |
6489 | 6612 |
6490 /* | 6613 /* |
6491 * link together defines and refs in this grammar | 6614 * link together defines and refs in this grammar |
6492 */ | 6615 */ |
6493 if (ret->refs != NULL) { | 6616 if (ret->refs != NULL) { |
6494 xmlHashScan(ret->refs, (xmlHashScanner) xmlRelaxNGCheckReference, | 6617 xmlHashScan(ret->refs, (xmlHashScanner) xmlRelaxNGCheckReference, |
6495 ctxt); | 6618 ctxt); |
6496 } | 6619 } |
6497 | 6620 |
| 6621 |
| 6622 /* @@@@ */ |
| 6623 |
6498 ctxt->grammar = old; | 6624 ctxt->grammar = old; |
6499 return (ret); | 6625 return (ret); |
6500 } | 6626 } |
6501 | 6627 |
6502 /** | 6628 /** |
6503 * xmlRelaxNGParseDocument: | 6629 * xmlRelaxNGParseDocument: |
6504 * @ctxt: a Relax-NG parser context | 6630 * @ctxt: a Relax-NG parser context |
6505 * @node: the root node of the RelaxNG schema | 6631 * @node: the root node of the RelaxNG schema |
6506 * | 6632 * |
6507 * parse a Relax-NG definition resource and build an internal | 6633 * parse a Relax-NG definition resource and build an internal |
(...skipping 1828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8336 return (-1); | 8462 return (-1); |
8337 } | 8463 } |
8338 state->seq = elem; | 8464 state->seq = elem; |
8339 ctxt->state = state; | 8465 ctxt->state = state; |
8340 ctxt->errNo = XML_RELAXNG_OK; | 8466 ctxt->errNo = XML_RELAXNG_OK; |
8341 ret = xmlRelaxNGValidateDefinition(ctxt, ctxt->pdef); | 8467 ret = xmlRelaxNGValidateDefinition(ctxt, ctxt->pdef); |
8342 if ((ret != 0) || (ctxt->errNo != XML_RELAXNG_OK)) | 8468 if ((ret != 0) || (ctxt->errNo != XML_RELAXNG_OK)) |
8343 ret = -1; | 8469 ret = -1; |
8344 else | 8470 else |
8345 ret = 1; | 8471 ret = 1; |
8346 xmlRelaxNGFreeValidState(ctxt, state); | 8472 xmlRelaxNGFreeValidState(ctxt, ctxt->state); |
8347 ctxt->state = NULL; | 8473 ctxt->state = NULL; |
8348 #ifdef DEBUG_PROGRESSIVE | 8474 #ifdef DEBUG_PROGRESSIVE |
8349 if (ret < 0) | 8475 if (ret < 0) |
8350 xmlGenericError(xmlGenericErrorContext, "FullElem %s failed\n", | 8476 xmlGenericError(xmlGenericErrorContext, "FullElem %s failed\n", |
8351 elem->name); | 8477 elem->name); |
8352 #endif | 8478 #endif |
8353 return (ret); | 8479 return (ret); |
8354 } | 8480 } |
8355 | 8481 |
8356 /************************************************************************ | 8482 /************************************************************************ |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8805 ret = -1; | 8931 ret = -1; |
8806 break; | 8932 break; |
8807 } else | 8933 } else |
8808 ret = 0; | 8934 ret = 0; |
8809 list = list->next; | 8935 list = list->next; |
8810 } | 8936 } |
8811 break; | 8937 break; |
8812 } | 8938 } |
8813 case XML_RELAXNG_REF: | 8939 case XML_RELAXNG_REF: |
8814 case XML_RELAXNG_PARENTREF: | 8940 case XML_RELAXNG_PARENTREF: |
8815 ret = xmlRelaxNGValidateValue(ctxt, define->content); | 8941 » if (define->content == NULL) { |
| 8942 VALID_ERR(XML_RELAXNG_ERR_NODEFINE); |
| 8943 ret = -1; |
| 8944 » } else { |
| 8945 ret = xmlRelaxNGValidateValue(ctxt, define->content); |
| 8946 } |
8816 break; | 8947 break; |
8817 default: | 8948 default: |
8818 TODO ret = -1; | 8949 TODO ret = -1; |
8819 } | 8950 } |
8820 return (ret); | 8951 return (ret); |
8821 } | 8952 } |
8822 | 8953 |
8823 /** | 8954 /** |
8824 * xmlRelaxNGValidateValueContent: | 8955 * xmlRelaxNGValidateValueContent: |
8825 * @ctxt: a Relax-NG validation context | 8956 * @ctxt: a Relax-NG validation context |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9312 */ | 9443 */ |
9313 if (ctxt->states->nbState > 0) { | 9444 if (ctxt->states->nbState > 0) { |
9314 xmlRelaxNGFreeValidState(ctxt, oldstate); | 9445 xmlRelaxNGFreeValidState(ctxt, oldstate); |
9315 if (best != -1) { | 9446 if (best != -1) { |
9316 oldstate = ctxt->states->tabState[best]; | 9447 oldstate = ctxt->states->tabState[best]; |
9317 ctxt->states->tabState[best] = NULL; | 9448 ctxt->states->tabState[best] = NULL; |
9318 } else { | 9449 } else { |
9319 oldstate = | 9450 oldstate = |
9320 ctxt->states->tabState[ctxt->states->nbState - 1]; | 9451 ctxt->states->tabState[ctxt->states->nbState - 1]; |
9321 ctxt->states->tabState[ctxt->states->nbState - 1] = NULL; | 9452 ctxt->states->tabState[ctxt->states->nbState - 1] = NULL; |
| 9453 ctxt->states->nbState--; |
9322 } | 9454 } |
9323 } | 9455 } |
9324 for (j = 0; j < ctxt->states->nbState ; j++) { | 9456 for (j = 0; j < ctxt->states->nbState ; j++) { |
9325 xmlRelaxNGFreeValidState(ctxt, ctxt->states->tabState[j]); | 9457 xmlRelaxNGFreeValidState(ctxt, ctxt->states->tabState[j]); |
9326 } | 9458 } |
9327 xmlRelaxNGFreeStates(ctxt, ctxt->states); | 9459 xmlRelaxNGFreeStates(ctxt, ctxt->states); |
9328 ctxt->states = NULL; | 9460 ctxt->states = NULL; |
9329 if (found == 0) { | 9461 if (found == 0) { |
9330 VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name); | 9462 if (cur == NULL) { |
| 9463 » » VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, |
| 9464 » » » (const xmlChar *) "noname"); |
| 9465 } else { |
| 9466 VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name); |
| 9467 } |
9331 ret = -1; | 9468 ret = -1; |
9332 ctxt->state = oldstate; | 9469 ctxt->state = oldstate; |
9333 goto done; | 9470 goto done; |
9334 } | 9471 } |
9335 } else { | 9472 } else { |
9336 ret = -1; | 9473 ret = -1; |
9337 break; | 9474 break; |
9338 } | 9475 } |
9339 if (lasts[i] != NULL) { | 9476 if (lasts[i] != NULL) { |
9340 lasts[i]->next = last; | 9477 lasts[i]->next = last; |
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9867 } | 10004 } |
9868 if (tmp != 0) { | 10005 if (tmp != 0) { |
9869 /* | 10006 /* |
9870 * validation error, log the message for the "best" one | 10007 * validation error, log the message for the "best" one |
9871 */ | 10008 */ |
9872 ctxt->flags |= FLAGS_IGNORABLE; | 10009 ctxt->flags |= FLAGS_IGNORABLE; |
9873 xmlRelaxNGLogBestError(ctxt); | 10010 xmlRelaxNGLogBestError(ctxt); |
9874 } | 10011 } |
9875 for (i = 0; i < ctxt->states->nbState; i++) { | 10012 for (i = 0; i < ctxt->states->nbState; i++) { |
9876 xmlRelaxNGFreeValidState(ctxt, | 10013 xmlRelaxNGFreeValidState(ctxt, |
9877 ctxt->states-> | 10014 ctxt->states->tabState[i]); |
9878 tabState[i]); | 10015 ctxt->states->tabState[i] = NULL; |
9879 } | 10016 } |
9880 xmlRelaxNGFreeStates(ctxt, ctxt->states); | 10017 xmlRelaxNGFreeStates(ctxt, ctxt->states); |
9881 ctxt->flags = oldflags; | 10018 ctxt->flags = oldflags; |
9882 ctxt->states = NULL; | 10019 ctxt->states = NULL; |
9883 if ((ret == 0) && (tmp == -1)) | 10020 if ((ret == 0) && (tmp == -1)) |
9884 ret = -1; | 10021 ret = -1; |
9885 } else { | 10022 } else { |
9886 state = ctxt->state; | 10023 state = ctxt->state; |
9887 if (ret == 0) | 10024 if (ret == 0) |
9888 ret = xmlRelaxNGValidateElementEnd(ctxt, 1); | 10025 ret = xmlRelaxNGValidateElementEnd(ctxt, 1); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9990 * All the input states are also exit states | 10127 * All the input states are also exit states |
9991 */ | 10128 */ |
9992 if (ctxt->state != NULL) { | 10129 if (ctxt->state != NULL) { |
9993 xmlRelaxNGAddStates(ctxt, res, | 10130 xmlRelaxNGAddStates(ctxt, res, |
9994 xmlRelaxNGCopyValidState(ctxt, | 10131 xmlRelaxNGCopyValidState(ctxt, |
9995 ctxt-> | 10132 ctxt-> |
9996 state)); | 10133 state)); |
9997 } else { | 10134 } else { |
9998 for (j = 0; j < ctxt->states->nbState; j++) { | 10135 for (j = 0; j < ctxt->states->nbState; j++) { |
9999 xmlRelaxNGAddStates(ctxt, res, | 10136 xmlRelaxNGAddStates(ctxt, res, |
10000 xmlRelaxNGCopyValidState(ctxt, | 10137 xmlRelaxNGCopyValidState(ctxt, |
10001 ctxt-> | 10138 ctxt->states->tabState[j])); |
10002 states-> | |
10003 tabState | |
10004 [j])); | |
10005 } | 10139 } |
10006 } | 10140 } |
10007 oldflags = ctxt->flags; | 10141 oldflags = ctxt->flags; |
10008 ctxt->flags |= FLAGS_IGNORABLE; | 10142 ctxt->flags |= FLAGS_IGNORABLE; |
10009 do { | 10143 do { |
10010 progress = 0; | 10144 progress = 0; |
10011 base = res->nbState; | 10145 base = res->nbState; |
10012 | 10146 |
10013 if (ctxt->states != NULL) { | 10147 if (ctxt->states != NULL) { |
10014 states = ctxt->states; | 10148 states = ctxt->states; |
10015 for (i = 0; i < states->nbState; i++) { | 10149 for (i = 0; i < states->nbState; i++) { |
10016 ctxt->state = states->tabState[i]; | 10150 ctxt->state = states->tabState[i]; |
10017 ctxt->states = NULL; | 10151 ctxt->states = NULL; |
10018 ret = xmlRelaxNGValidateDefinitionList(ctxt, | 10152 ret = xmlRelaxNGValidateDefinitionList(ctxt, |
10019 define-> | 10153 define-> |
10020 content); | 10154 content); |
10021 if (ret == 0) { | 10155 if (ret == 0) { |
10022 if (ctxt->state != NULL) { | 10156 if (ctxt->state != NULL) { |
10023 tmp = xmlRelaxNGAddStates(ctxt, res, | 10157 tmp = xmlRelaxNGAddStates(ctxt, res, |
10024 ctxt->state); | 10158 ctxt->state); |
10025 ctxt->state = NULL; | 10159 ctxt->state = NULL; |
10026 if (tmp == 1) | 10160 if (tmp == 1) |
10027 progress = 1; | 10161 progress = 1; |
10028 } else if (ctxt->states != NULL) { | 10162 } else if (ctxt->states != NULL) { |
10029 for (j = 0; j < ctxt->states->nbState; | 10163 for (j = 0; j < ctxt->states->nbState; |
10030 j++) { | 10164 j++) { |
10031 tmp = | 10165 tmp = |
10032 xmlRelaxNGAddStates(ctxt, res, | 10166 xmlRelaxNGAddStates(ctxt, res, |
10033 ctxt-> | 10167 ctxt->states->tabState[j]); |
10034 states-> | |
10035 tabState | |
10036 [j]); | |
10037 if (tmp == 1) | 10168 if (tmp == 1) |
10038 progress = 1; | 10169 progress = 1; |
10039 } | 10170 } |
10040 xmlRelaxNGFreeStates(ctxt, | 10171 xmlRelaxNGFreeStates(ctxt, |
10041 ctxt->states); | 10172 ctxt->states); |
10042 ctxt->states = NULL; | 10173 ctxt->states = NULL; |
10043 } | 10174 } |
10044 } else { | 10175 } else { |
10045 if (ctxt->state != NULL) { | 10176 if (ctxt->state != NULL) { |
10046 xmlRelaxNGFreeValidState(ctxt, | 10177 xmlRelaxNGFreeValidState(ctxt, |
(...skipping 13 matching lines...) Expand all Loading... |
10060 base = res->nbState; | 10191 base = res->nbState; |
10061 if (ctxt->state != NULL) { | 10192 if (ctxt->state != NULL) { |
10062 tmp = xmlRelaxNGAddStates(ctxt, res, | 10193 tmp = xmlRelaxNGAddStates(ctxt, res, |
10063 ctxt->state); | 10194 ctxt->state); |
10064 ctxt->state = NULL; | 10195 ctxt->state = NULL; |
10065 if (tmp == 1) | 10196 if (tmp == 1) |
10066 progress = 1; | 10197 progress = 1; |
10067 } else if (ctxt->states != NULL) { | 10198 } else if (ctxt->states != NULL) { |
10068 for (j = 0; j < ctxt->states->nbState; j++) { | 10199 for (j = 0; j < ctxt->states->nbState; j++) { |
10069 tmp = xmlRelaxNGAddStates(ctxt, res, | 10200 tmp = xmlRelaxNGAddStates(ctxt, res, |
10070 ctxt-> | 10201 ctxt->states->tabState[j]); |
10071 states-> | |
10072 tabState[j]); | |
10073 if (tmp == 1) | 10202 if (tmp == 1) |
10074 progress = 1; | 10203 progress = 1; |
10075 } | 10204 } |
10076 if (states == NULL) { | 10205 if (states == NULL) { |
10077 states = ctxt->states; | 10206 states = ctxt->states; |
10078 } else { | 10207 } else { |
10079 xmlRelaxNGFreeStates(ctxt, | 10208 xmlRelaxNGFreeStates(ctxt, |
10080 ctxt->states); | 10209 ctxt->states); |
10081 } | 10210 } |
10082 ctxt->states = NULL; | 10211 ctxt->states = NULL; |
(...skipping 17 matching lines...) Expand all Loading... |
10100 states = ctxt->states; | 10229 states = ctxt->states; |
10101 if (states == NULL) { | 10230 if (states == NULL) { |
10102 progress = 0; | 10231 progress = 0; |
10103 break; | 10232 break; |
10104 } | 10233 } |
10105 } | 10234 } |
10106 states->nbState = 0; | 10235 states->nbState = 0; |
10107 for (i = base; i < res->nbState; i++) | 10236 for (i = base; i < res->nbState; i++) |
10108 xmlRelaxNGAddStates(ctxt, states, | 10237 xmlRelaxNGAddStates(ctxt, states, |
10109 xmlRelaxNGCopyValidState | 10238 xmlRelaxNGCopyValidState |
10110 (ctxt, | 10239 (ctxt, res->tabState[i])); |
10111 res->tabState[i])); | |
10112 ctxt->states = states; | 10240 ctxt->states = states; |
10113 } | 10241 } |
10114 } | 10242 } |
10115 } while (progress == 1); | 10243 } while (progress == 1); |
10116 if (states != NULL) { | 10244 if (states != NULL) { |
10117 xmlRelaxNGFreeStates(ctxt, states); | 10245 xmlRelaxNGFreeStates(ctxt, states); |
10118 } | 10246 } |
10119 ctxt->states = res; | 10247 ctxt->states = res; |
10120 ctxt->flags = oldflags; | 10248 ctxt->flags = oldflags; |
10121 #if 0 | 10249 #if 0 |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10623 if (xmlValidateDocumentFinal(&vctxt, doc) != 1) | 10751 if (xmlValidateDocumentFinal(&vctxt, doc) != 1) |
10624 ret = -1; | 10752 ret = -1; |
10625 } | 10753 } |
10626 #endif /* LIBXML_VALID_ENABLED */ | 10754 #endif /* LIBXML_VALID_ENABLED */ |
10627 if ((ret == 0) && (ctxt->errNo != XML_RELAXNG_OK)) | 10755 if ((ret == 0) && (ctxt->errNo != XML_RELAXNG_OK)) |
10628 ret = -1; | 10756 ret = -1; |
10629 | 10757 |
10630 return (ret); | 10758 return (ret); |
10631 } | 10759 } |
10632 | 10760 |
| 10761 /** |
| 10762 * xmlRelaxNGCleanPSVI: |
| 10763 * @node: an input element or document |
| 10764 * |
| 10765 * Call this routine to speed up XPath computation on static documents. |
| 10766 * This stamps all the element nodes with the document order |
| 10767 * Like for line information, the order is kept in the element->content |
| 10768 * field, the value stored is actually - the node number (starting at -1) |
| 10769 * to be able to differentiate from line numbers. |
| 10770 * |
| 10771 * Returns the number of elements found in the document or -1 in case |
| 10772 * of error. |
| 10773 */ |
| 10774 static void |
| 10775 xmlRelaxNGCleanPSVI(xmlNodePtr node) { |
| 10776 xmlNodePtr cur; |
| 10777 |
| 10778 if ((node == NULL) || |
| 10779 ((node->type != XML_ELEMENT_NODE) && |
| 10780 (node->type != XML_DOCUMENT_NODE) && |
| 10781 (node->type != XML_HTML_DOCUMENT_NODE))) |
| 10782 return; |
| 10783 if (node->type == XML_ELEMENT_NODE) |
| 10784 node->psvi = NULL; |
| 10785 |
| 10786 cur = node->children; |
| 10787 while (cur != NULL) { |
| 10788 if (cur->type == XML_ELEMENT_NODE) { |
| 10789 cur->psvi = NULL; |
| 10790 if (cur->children != NULL) { |
| 10791 cur = cur->children; |
| 10792 continue; |
| 10793 } |
| 10794 } |
| 10795 if (cur->next != NULL) { |
| 10796 cur = cur->next; |
| 10797 continue; |
| 10798 } |
| 10799 do { |
| 10800 cur = cur->parent; |
| 10801 if (cur == NULL) |
| 10802 break; |
| 10803 if (cur == node) { |
| 10804 cur = NULL; |
| 10805 break; |
| 10806 } |
| 10807 if (cur->next != NULL) { |
| 10808 cur = cur->next; |
| 10809 break; |
| 10810 } |
| 10811 } while (cur != NULL); |
| 10812 } |
| 10813 return; |
| 10814 } |
10633 /************************************************************************ | 10815 /************************************************************************ |
10634 * * | 10816 * * |
10635 * Validation interfaces * | 10817 * Validation interfaces * |
10636 * * | 10818 * * |
10637 ************************************************************************/ | 10819 ************************************************************************/ |
10638 | 10820 |
10639 /** | 10821 /** |
10640 * xmlRelaxNGNewValidCtxt: | 10822 * xmlRelaxNGNewValidCtxt: |
10641 * @schema: a precompiled XML RelaxNGs | 10823 * @schema: a precompiled XML RelaxNGs |
10642 * | 10824 * |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10797 { | 10979 { |
10798 int ret; | 10980 int ret; |
10799 | 10981 |
10800 if ((ctxt == NULL) || (doc == NULL)) | 10982 if ((ctxt == NULL) || (doc == NULL)) |
10801 return (-1); | 10983 return (-1); |
10802 | 10984 |
10803 ctxt->doc = doc; | 10985 ctxt->doc = doc; |
10804 | 10986 |
10805 ret = xmlRelaxNGValidateDocument(ctxt, doc); | 10987 ret = xmlRelaxNGValidateDocument(ctxt, doc); |
10806 /* | 10988 /* |
| 10989 * Remove all left PSVI |
| 10990 */ |
| 10991 xmlRelaxNGCleanPSVI((xmlNodePtr) doc); |
| 10992 |
| 10993 /* |
10807 * TODO: build error codes | 10994 * TODO: build error codes |
10808 */ | 10995 */ |
10809 if (ret == -1) | 10996 if (ret == -1) |
10810 return (1); | 10997 return (1); |
10811 return (ret); | 10998 return (ret); |
10812 } | 10999 } |
10813 | 11000 |
10814 #define bottom_relaxng | 11001 #define bottom_relaxng |
10815 #include "elfgcchack.h" | 11002 #include "elfgcchack.h" |
10816 #endif /* LIBXML_SCHEMAS_ENABLED */ | 11003 #endif /* LIBXML_SCHEMAS_ENABLED */ |
OLD | NEW |