diff --git a/schematron.c b/schematron.c index a8259201..191ead3d 100644 --- a/schematron.c +++ b/schematron.c @@ -63,16 +63,6 @@ static const xmlChar *xmlOldSchematronNs = SCT_OLD_NS; node = node->next; \ } -/** - * TODO: - * - * macro to flag unimplemented blocks - */ -#define TODO \ - xmlGenericError(xmlGenericErrorContext, \ - "Unimplemented block at %s:%d\n", \ - __FILE__, __LINE__); - typedef enum { XML_SCHEMATRON_ASSERT=1, XML_SCHEMATRON_REPORT=2 @@ -242,13 +232,11 @@ struct _xmlSchematronParserCtxt { * Handle an out of memory condition */ static void -xmlSchematronPErrMemory(xmlSchematronParserCtxtPtr ctxt, - const char *extra, xmlNodePtr node) +xmlSchematronPErrMemory(xmlSchematronParserCtxtPtr ctxt) { if (ctxt != NULL) ctxt->nberrors++; - __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL, - extra); + xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_SCHEMASP, NULL); } /** @@ -269,6 +257,7 @@ xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error, xmlGenericErrorFunc channel = NULL; xmlStructuredErrorFunc schannel = NULL; void *data = NULL; + int res; if (ctxt != NULL) { ctxt->nberrors++; @@ -276,10 +265,13 @@ xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error, data = ctxt->userData; schannel = ctxt->serror; } - __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, - error, XML_ERR_ERROR, NULL, 0, - (const char *) str1, (const char *) str2, NULL, 0, 0, - msg, str1, str2); + + res = __xmlRaiseError(schannel, channel, data, ctxt, node, + XML_FROM_SCHEMASP, error, XML_ERR_ERROR, NULL, 0, + (const char *) str1, (const char *) str2, NULL, 0, 0, + msg, str1, str2); + if (res < 0) + xmlSchematronPErrMemory(ctxt); } /** @@ -290,15 +282,48 @@ xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error, * Handle an out of memory condition */ static void -xmlSchematronVErrMemory(xmlSchematronValidCtxtPtr ctxt, - const char *extra, xmlNodePtr node) +xmlSchematronVErrMemory(xmlSchematronValidCtxtPtr ctxt) { if (ctxt != NULL) { ctxt->nberrors++; ctxt->err = XML_SCHEMAV_INTERNAL; } - __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL, - extra); + xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_SCHEMASV, NULL); +} + +/** + * xmlSchematronVErr: + * @ctxt: the parsing context + * @node: the context node + * @error: the error code + * @msg: the error message + * @str1: extra data + * @str2: extra data + * + * Handle a validation error + */ +static void LIBXML_ATTR_FORMAT(3,0) +xmlSchematronVErr(xmlSchematronValidCtxtPtr ctxt, int error, + const char *msg, const xmlChar * str1) +{ + xmlGenericErrorFunc channel = NULL; + xmlStructuredErrorFunc schannel = NULL; + void *data = NULL; + int res; + + if (ctxt != NULL) { + ctxt->nberrors++; + channel = ctxt->error; + data = ctxt->userData; + schannel = ctxt->serror; + } + + res = __xmlRaiseError(schannel, channel, data, ctxt, NULL, + XML_FROM_SCHEMASV, error, XML_ERR_ERROR, NULL, 0, + (const char *) str1, NULL, NULL, 0, 0, + msg, str1); + if (res < 0) + xmlSchematronVErrMemory(ctxt); } /************************************************************************ @@ -347,7 +372,7 @@ xmlSchematronAddTest(xmlSchematronParserCtxtPtr ctxt, ret = (xmlSchematronTestPtr) xmlMalloc(sizeof(xmlSchematronTest)); if (ret == NULL) { - xmlSchematronPErrMemory(ctxt, "allocating schema test", node); + xmlSchematronPErrMemory(ctxt); return (NULL); } memset(ret, 0, sizeof(xmlSchematronTest)); @@ -451,7 +476,7 @@ xmlSchematronAddRule(xmlSchematronParserCtxtPtr ctxt, xmlSchematronPtr schema, ret = (xmlSchematronRulePtr) xmlMalloc(sizeof(xmlSchematronRule)); if (ret == NULL) { - xmlSchematronPErrMemory(ctxt, "allocating schema rule", node); + xmlSchematronPErrMemory(ctxt); return (NULL); } memset(ret, 0, sizeof(xmlSchematronRule)); @@ -532,7 +557,7 @@ xmlSchematronAddPattern(xmlSchematronParserCtxtPtr ctxt, ret = (xmlSchematronPatternPtr) xmlMalloc(sizeof(xmlSchematronPattern)); if (ret == NULL) { - xmlSchematronPErrMemory(ctxt, "allocating schema pattern", node); + xmlSchematronPErrMemory(ctxt); return (NULL); } memset(ret, 0, sizeof(xmlSchematronPattern)); @@ -584,7 +609,7 @@ xmlSchematronNewSchematron(xmlSchematronParserCtxtPtr ctxt) ret = (xmlSchematronPtr) xmlMalloc(sizeof(xmlSchematron)); if (ret == NULL) { - xmlSchematronPErrMemory(ctxt, "allocating schema", NULL); + xmlSchematronPErrMemory(ctxt); return (NULL); } memset(ret, 0, sizeof(xmlSchematron)); @@ -639,8 +664,7 @@ xmlSchematronNewParserCtxt(const char *URL) (xmlSchematronParserCtxtPtr) xmlMalloc(sizeof(xmlSchematronParserCtxt)); if (ret == NULL) { - xmlSchematronPErrMemory(NULL, "allocating schema parser context", - NULL); + xmlSchematronPErrMemory(NULL); return (NULL); } memset(ret, 0, sizeof(xmlSchematronParserCtxt)); @@ -650,8 +674,7 @@ xmlSchematronNewParserCtxt(const char *URL) ret->includes = NULL; ret->xctxt = xmlXPathNewContext(NULL); if (ret->xctxt == NULL) { - xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context", - NULL); + xmlSchematronPErrMemory(NULL); xmlSchematronFreeParserCtxt(ret); return (NULL); } @@ -681,8 +704,7 @@ xmlSchematronNewMemParserCtxt(const char *buffer, int size) (xmlSchematronParserCtxtPtr) xmlMalloc(sizeof(xmlSchematronParserCtxt)); if (ret == NULL) { - xmlSchematronPErrMemory(NULL, "allocating schema parser context", - NULL); + xmlSchematronPErrMemory(NULL); return (NULL); } memset(ret, 0, sizeof(xmlSchematronParserCtxt)); @@ -691,8 +713,7 @@ xmlSchematronNewMemParserCtxt(const char *buffer, int size) ret->dict = xmlDictCreate(); ret->xctxt = xmlXPathNewContext(NULL); if (ret->xctxt == NULL) { - xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context", - NULL); + xmlSchematronPErrMemory(NULL); xmlSchematronFreeParserCtxt(ret); return (NULL); } @@ -720,8 +741,7 @@ xmlSchematronNewDocParserCtxt(xmlDocPtr doc) (xmlSchematronParserCtxtPtr) xmlMalloc(sizeof(xmlSchematronParserCtxt)); if (ret == NULL) { - xmlSchematronPErrMemory(NULL, "allocating schema parser context", - NULL); + xmlSchematronPErrMemory(NULL); return (NULL); } memset(ret, 0, sizeof(xmlSchematronParserCtxt)); @@ -731,8 +751,7 @@ xmlSchematronNewDocParserCtxt(xmlDocPtr doc) ret->preserve = 1; ret->xctxt = xmlXPathNewContext(doc); if (ret->xctxt == NULL) { - xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context", - NULL); + xmlSchematronPErrMemory(NULL); xmlSchematronFreeParserCtxt(ret); return (NULL); } @@ -780,8 +799,7 @@ xmlSchematronPushInclude(xmlSchematronParserCtxtPtr ctxt, ctxt->includes = (xmlNodePtr *) xmlMalloc(ctxt->maxIncludes * 2 * sizeof(xmlNodePtr)); if (ctxt->includes == NULL) { - xmlSchematronPErrMemory(NULL, "allocating parser includes", - NULL); + xmlSchematronPErrMemory(NULL); return; } ctxt->nbIncludes = 0; @@ -792,8 +810,7 @@ xmlSchematronPushInclude(xmlSchematronParserCtxtPtr ctxt, xmlRealloc(ctxt->includes, ctxt->maxIncludes * 4 * sizeof(xmlNodePtr)); if (tmp == NULL) { - xmlSchematronPErrMemory(NULL, "allocating parser includes", - NULL); + xmlSchematronPErrMemory(NULL); return; } ctxt->includes = tmp; @@ -850,8 +867,7 @@ xmlSchematronAddNamespace(xmlSchematronParserCtxtPtr ctxt, ctxt->namespaces = (const xmlChar **) xmlMalloc(ctxt->maxNamespaces * 2 * sizeof(const xmlChar *)); if (ctxt->namespaces == NULL) { - xmlSchematronPErrMemory(NULL, "allocating parser namespaces", - NULL); + xmlSchematronPErrMemory(NULL); return; } ctxt->nbNamespaces = 0; @@ -862,8 +878,7 @@ xmlSchematronAddNamespace(xmlSchematronParserCtxtPtr ctxt, xmlRealloc((xmlChar **) ctxt->namespaces, ctxt->maxNamespaces * 4 * sizeof(const xmlChar *)); if (tmp == NULL) { - xmlSchematronPErrMemory(NULL, "allocating parser namespaces", - NULL); + xmlSchematronPErrMemory(NULL); return; } ctxt->namespaces = tmp; @@ -1493,9 +1508,6 @@ xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt, ret = xmlStrcat(ret, spacer); ret = xmlStrcat(ret, eval->nodesetval->nodeTab[indx]->name); } - } else { - xmlGenericError(xmlGenericErrorContext, - "Empty node set\n"); } break; } @@ -1521,8 +1533,8 @@ xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt, ret = xmlStrcat(ret, eval->stringval); break; default: - xmlGenericError(xmlGenericErrorContext, - "Unsupported XPATH Type: %d\n", eval->type); + xmlSchematronVErr(ctxt, XML_ERR_INTERNAL_ERROR, + "Unsupported XPATH Type\n", NULL); } xmlXPathFreeObject(eval); xmlXPathFreeCompExpr(comp); @@ -1581,7 +1593,7 @@ xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt, (test->type == XML_SCHEMATRON_REPORT)) return; if (ctxt->flags & XML_SCHEMATRON_OUT_XML) { - TODO + /* TODO */ } else { xmlChar *path; char msg[1000]; @@ -1612,26 +1624,28 @@ xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt, line, (const char *) report); if (ctxt->flags & XML_SCHEMATRON_OUT_ERROR) { - xmlStructuredErrorFunc schannel = NULL; - xmlGenericErrorFunc channel = NULL; - void *data = NULL; + xmlStructuredErrorFunc schannel; + xmlGenericErrorFunc channel; + void *data; + int res; - if (ctxt != NULL) { - if (ctxt->serror != NULL) - schannel = ctxt->serror; - else - channel = ctxt->error; - data = ctxt->userData; - } + schannel = ctxt->serror; + channel = ctxt->error; + data = ctxt->userData; - __xmlRaiseError(schannel, channel, data, - NULL, cur, XML_FROM_SCHEMATRONV, - (test->type == XML_SCHEMATRON_ASSERT)?XML_SCHEMATRONV_ASSERT:XML_SCHEMATRONV_REPORT, - XML_ERR_ERROR, NULL, line, - (pattern == NULL)?NULL:((const char *) pattern->name), - (const char *) path, - (const char *) report, 0, 0, - "%s", msg); + res = __xmlRaiseError(schannel, channel, data, NULL, cur, + XML_FROM_SCHEMATRONV, + (test->type == XML_SCHEMATRON_ASSERT) ? + XML_SCHEMATRONV_ASSERT : + XML_SCHEMATRONV_REPORT, + XML_ERR_ERROR, NULL, line, + (pattern == NULL) ? + NULL : + (const char *) pattern->name, + (const char *) path, (const char *) report, 0, 0, + "%s", msg); + if (res < 0) + xmlSchematronVErrMemory(ctxt); } else { xmlSchematronReportOutput(ctxt, cur, &msg[0]); } @@ -1658,7 +1672,7 @@ xmlSchematronReportPattern(xmlSchematronValidCtxtPtr ctxt, if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) || (ctxt->flags & XML_SCHEMATRON_OUT_ERROR)) /* Error gives pattern name as part of error */ return; if (ctxt->flags & XML_SCHEMATRON_OUT_XML) { - TODO + /* TODO */ } else { char msg[1000]; @@ -1713,8 +1727,7 @@ xmlSchematronNewValidCtxt(xmlSchematronPtr schema, int options) ret = (xmlSchematronValidCtxtPtr) xmlMalloc(sizeof(xmlSchematronValidCtxt)); if (ret == NULL) { - xmlSchematronVErrMemory(NULL, "allocating validation context", - NULL); + xmlSchematronVErrMemory(NULL); return (NULL); } memset(ret, 0, sizeof(xmlSchematronValidCtxt)); @@ -1723,8 +1736,7 @@ xmlSchematronNewValidCtxt(xmlSchematronPtr schema, int options) ret->xctxt = xmlXPathNewContext(NULL); ret->flags = options; if (ret->xctxt == NULL) { - xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context", - NULL); + xmlSchematronPErrMemory(NULL); xmlSchematronFreeValidCtxt(ret); return (NULL); } @@ -1870,7 +1882,9 @@ xmlSchematronRunTest(xmlSchematronValidCtxtPtr ctxt, * Returns -1 in case of errors, otherwise 0 */ static int -xmlSchematronRegisterVariables(xmlXPathContextPtr ctxt, xmlSchematronLetPtr let, +xmlSchematronRegisterVariables(xmlSchematronValidCtxtPtr vctxt, + xmlXPathContextPtr ctxt, + xmlSchematronLetPtr let, xmlDocPtr instance, xmlNodePtr cur) { xmlXPathObjectPtr let_eval; @@ -1880,13 +1894,14 @@ xmlSchematronRegisterVariables(xmlXPathContextPtr ctxt, xmlSchematronLetPtr let, while (let != NULL) { let_eval = xmlXPathCompiledEval(let->comp, ctxt); if (let_eval == NULL) { - xmlGenericError(xmlGenericErrorContext, - "Evaluation of compiled expression failed\n"); + xmlSchematronVErr(vctxt, XML_ERR_INTERNAL_ERROR, + "Evaluation of compiled expression failed\n", + NULL); return -1; } if(xmlXPathRegisterVariableNS(ctxt, let->name, NULL, let_eval)) { - xmlGenericError(xmlGenericErrorContext, - "Registering a let variable failed\n"); + xmlSchematronVErr(vctxt, XML_ERR_INTERNAL_ERROR, + "Registering a let variable failed\n", NULL); return -1; } let = let->next; @@ -1904,12 +1919,14 @@ xmlSchematronRegisterVariables(xmlXPathContextPtr ctxt, xmlSchematronLetPtr let, * Returns -1 in case of errors, otherwise 0 */ static int -xmlSchematronUnregisterVariables(xmlXPathContextPtr ctxt, xmlSchematronLetPtr let) +xmlSchematronUnregisterVariables(xmlSchematronValidCtxtPtr vctxt, + xmlXPathContextPtr ctxt, + xmlSchematronLetPtr let) { while (let != NULL) { if (xmlXPathRegisterVariableNS(ctxt, let->name, NULL, NULL)) { - xmlGenericError(xmlGenericErrorContext, - "Unregistering a let variable failed\n"); + xmlSchematronVErr(vctxt, XML_ERR_INTERNAL_ERROR, + "Unregistering a let variable failed\n", NULL); return -1; } let = let->next; @@ -1941,7 +1958,7 @@ xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance) ctxt->nberrors = 0; root = xmlDocGetRootElement(instance); if (root == NULL) { - TODO + /* TODO */ ctxt->nberrors++; return(1); } @@ -1958,7 +1975,8 @@ xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance) if (xmlPatternMatch(rule->pattern, cur) == 1) { test = rule->tests; - if (xmlSchematronRegisterVariables(ctxt->xctxt, rule->lets, instance, cur)) + if (xmlSchematronRegisterVariables(ctxt, ctxt->xctxt, + rule->lets, instance, cur)) return -1; while (test != NULL) { @@ -1966,7 +1984,8 @@ xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance) test = test->next; } - if (xmlSchematronUnregisterVariables(ctxt->xctxt, rule->lets)) + if (xmlSchematronUnregisterVariables(ctxt, ctxt->xctxt, + rule->lets)) return -1; } @@ -1996,15 +2015,16 @@ xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance) while (rule != NULL) { if (xmlPatternMatch(rule->pattern, cur) == 1) { test = rule->tests; - xmlSchematronRegisterVariables(ctxt->xctxt, rule->lets, - instance, cur); + xmlSchematronRegisterVariables(ctxt, ctxt->xctxt, + rule->lets, instance, cur); while (test != NULL) { xmlSchematronRunTest(ctxt, test, instance, cur, pattern); test = test->next; } - xmlSchematronUnregisterVariables(ctxt->xctxt, rule->lets); + xmlSchematronUnregisterVariables(ctxt, ctxt->xctxt, + rule->lets); } rule = rule->patnext; }