1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-29 11:41:22 +03:00

commiting some work done while in the Maldives (hence the timezone on the

* relaxng.c xmlschemas.c include/libxml/schemasInternals.h: commiting
  some work done while in the Maldives (hence the timezone on the
  laptop !)
* result/schemas/length3* test/schemas/deter0_*
  test/schemas/group0_*: some tests added too
Daniel
This commit is contained in:
Daniel Veillard
2003-06-02 16:58:46 +00:00
parent 8caa9c2c97
commit a84c0b30c4
10 changed files with 147 additions and 17 deletions

View File

@ -25,7 +25,7 @@
#include <libxml/xmlautomata.h>
#include <libxml/xmlregexp.h>
/* #define DEBUG 1 */ /* very verbose output */
/* #define DEBUG 1 */
/* #define DEBUG_CONTENT 1 */
/* #define DEBUG_TYPE 1 */
/* #define DEBUG_CONTENT_REGEXP 1 */
@ -406,6 +406,9 @@ xmlSchemaFree(xmlSchemaPtr schema)
if (schema->typeDecl != NULL)
xmlHashFree(schema->typeDecl,
(xmlHashDeallocator) xmlSchemaFreeType);
if (schema->groupDecl != NULL)
xmlHashFree(schema->groupDecl,
(xmlHashDeallocator) xmlSchemaFreeType);
if (schema->annot != NULL)
xmlSchemaFreeAnnot(schema->annot);
if (schema->doc != NULL)
@ -436,6 +439,7 @@ xmlSchemaErrorContext(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
int line = 0;
const xmlChar *file = NULL;
const xmlChar *name = NULL;
const xmlChar *prefix = NULL;
const char *type = "error";
if ((ctxt == NULL) || (ctxt->error == NULL))
@ -467,6 +471,9 @@ xmlSchemaErrorContext(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
file = node->doc->URL;
if (node->name != NULL)
name = node->name;
if ((node->type == XML_ELEMENT_NODE) && (node->ns != NULL) &&
(node->ns->prefix != NULL))
prefix = node->ns->prefix;
}
}
@ -475,9 +482,15 @@ xmlSchemaErrorContext(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
else if (schema != NULL)
type = "runtime error";
if ((file != NULL) && (line != 0) && (name != NULL))
if ((file != NULL) && (line != 0) && (name != NULL) && (prefix != NULL))
ctxt->error(ctxt->userData, "%s: file %s line %d element %s:%s\n",
type, file, line, prefix, name);
else if ((file != NULL) && (line != 0) && (name != NULL))
ctxt->error(ctxt->userData, "%s: file %s line %d element %s\n",
type, file, line, name);
else if ((file != NULL) && (name != NULL) && (prefix != NULL))
ctxt->error(ctxt->userData, "%s: file %s element %s:%s\n",
type, file, prefix, name);
else if ((file != NULL) && (name != NULL))
ctxt->error(ctxt->userData, "%s: file %s element %s\n",
type, file, name);
@ -485,6 +498,8 @@ xmlSchemaErrorContext(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
ctxt->error(ctxt->userData, "%s: file %s line %d\n", type, file, line);
else if (file != NULL)
ctxt->error(ctxt->userData, "%s: file %s\n", type, file);
else if ((name != NULL) && (prefix != NULL))
ctxt->error(ctxt->userData, "%s: element %s:%s\n", type, prefix, name);
else if (name != NULL)
ctxt->error(ctxt->userData, "%s: element %s\n", type, name);
else
@ -741,7 +756,7 @@ xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
*
* Lookup a type in the schemas or the predefined types
*
* Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
* Returns the group definition or NULL if not found.
*/
static xmlSchemaTypePtr
xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
@ -835,7 +850,7 @@ xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (val != 0) {
ctxt->nberrors++;
if ((ctxt != NULL) && (ctxt->error != NULL))
ctxt->error(ctxt->userData, "Could not add notation %s\n",
ctxt->error(ctxt->userData, "Notation %s already defined\n",
name);
xmlFree((char *) ret->name);
xmlFree(ret);
@ -886,7 +901,7 @@ xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (val != 0) {
ctxt->nberrors++;
if ((ctxt != NULL) && (ctxt->error != NULL))
ctxt->error(ctxt->userData, "Could not add attribute %s\n",
ctxt->error(ctxt->userData, "Attribute %s already defined\n",
name);
xmlFree((char *) ret->name);
xmlFree(ret);
@ -934,7 +949,7 @@ xmlSchemaAddAttributeGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (val != 0) {
ctxt->nberrors++;
if ((ctxt != NULL) && (ctxt->error != NULL))
ctxt->error(ctxt->userData, "Could not add attribute group %s\n",
ctxt->error(ctxt->userData, "Attribute group %s already defined\n",
name);
xmlFree((char *) ret->name);
xmlFree(ret);
@ -990,7 +1005,7 @@ xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (val != 0) {
ctxt->nberrors++;
if ((ctxt != NULL) && (ctxt->error != NULL))
ctxt->error(ctxt->userData, "Could not add element %s\n",
ctxt->error(ctxt->userData, "Element %s already defined\n",
name);
xmlFree((char *) ret->name);
xmlFree(ret);
@ -1040,7 +1055,57 @@ xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (val != 0) {
ctxt->nberrors++;
if ((ctxt != NULL) && (ctxt->error != NULL))
ctxt->error(ctxt->userData, "Could not add type %s\n", name);
ctxt->error(ctxt->userData, "Type %s already defined\n", name);
xmlFree((char *) ret->name);
xmlFree(ret);
return (NULL);
}
ret->minOccurs = 1;
ret->maxOccurs = 1;
return (ret);
}
/**
* xmlSchemaAddGroup:
* @ctxt: a schema validation context
* @schema: the schema being built
* @name: the group name
*
* Add an XML schema Group definition
*
* Returns the new struture or NULL in case of error
*/
static xmlSchemaTypePtr
xmlSchemaAddGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
const xmlChar * name)
{
xmlSchemaTypePtr ret = NULL;
int val;
if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
return (NULL);
if (schema->groupDecl == NULL)
schema->groupDecl = xmlHashCreate(10);
if (schema->groupDecl == NULL)
return (NULL);
ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
if (ret == NULL) {
ctxt->nberrors++;
if ((ctxt != NULL) && (ctxt->error != NULL))
ctxt->error(ctxt->userData, "Out of memory\n");
return (NULL);
}
memset(ret, 0, sizeof(xmlSchemaType));
ret->name = xmlStrdup(name);
val = xmlHashAddEntry2(schema->groupDecl, name, schema->targetNamespace,
ret);
if (val != 0) {
ctxt->nberrors++;
if ((ctxt != NULL) && (ctxt->error != NULL))
ctxt->error(ctxt->userData, "Group %s already defined\n", name);
xmlFree((char *) ret->name);
xmlFree(ret);
return (NULL);
@ -1808,6 +1873,7 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
schema->targetNamespace);
else
ret = xmlSchemaAddElement(ctxt, schema, name, namespace);
ret->node = node;
if (namespace != NULL)
xmlFree(namespace);
if (ret == NULL) {
@ -2118,7 +2184,7 @@ xmlSchemaParseGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
snprintf(buf, 99, "anongroup%d", ctxt->counter++ + 1);
name = xmlStrdup((xmlChar *) buf);
}
type = xmlSchemaAddType(ctxt, schema, name);
type = xmlSchemaAddGroup(ctxt, schema, name);
if (type == NULL)
return (NULL);
type->node = node;
@ -3456,6 +3522,8 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
break;
case XML_SCHEMA_TYPE_GROUP:
if (type->subtypes == NULL) {
}
case XML_SCHEMA_TYPE_COMPLEX:
case XML_SCHEMA_TYPE_COMPLEX_CONTENT:
if (type->subtypes != NULL)
@ -3470,10 +3538,11 @@ xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
}
/**
* xmlSchemaBuildContentModel:
* @typeDecl: the schema type definition
* @elem: the element
* @ctxt: the schema parser context
* @name: the element name
*
* Fixes the content model of the element.
* Builds the content model of the element.
*/
static void
xmlSchemaBuildContentModel(xmlSchemaElementPtr elem,
@ -3507,19 +3576,29 @@ xmlSchemaBuildContentModel(xmlSchemaElementPtr elem,
xmlSchemaBuildAContentModel(elem->subtypes, ctxt, name);
xmlAutomataSetFinalState(ctxt->am, ctxt->state);
elem->contModel = xmlAutomataCompile(ctxt->am);
if (!xmlAutomataIsDeterminist(ctxt->am)) {
xmlGenericError(xmlGenericErrorContext,
if (elem->contModel == NULL) {
xmlSchemaErrorContext(ctxt, NULL, elem->node, NULL);
if ((ctxt != NULL) && (ctxt->error != NULL))
ctxt->error(ctxt->userData,
"failed to compile %s content model\n",
name);
ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
ctxt->nberrors++;
} else if (xmlRegexpIsDeterminist(elem->contModel) != 1) {
xmlSchemaErrorContext(ctxt, NULL, elem->node, NULL);
if ((ctxt != NULL) && (ctxt->error != NULL))
ctxt->error(ctxt->userData,
"Content model of %s is not determinist:\n", name);
ctxt->err = XML_SCHEMAS_ERR_NOTDETERMINIST;
ctxt->state = NULL;
ctxt->nberrors++;
} else {
#ifdef DEBUG_CONTENT_REGEXP
xmlGenericError(xmlGenericErrorContext,
"Content model of %s:\n", name);
xmlRegexpPrint(stderr, elem->contModel);
#endif
ctxt->state = NULL;
}
ctxt->state = NULL;
xmlFreeAutomata(ctxt->am);
ctxt->am = NULL;
}