Index: src/domain_conf.c =================================================================== RCS file: /data/cvs/libvirt/src/domain_conf.c,v retrieving revision 1.10 diff -u -r1.10 domain_conf.c --- src/domain_conf.c 28 Jul 2008 14:06:54 -0000 1.10 +++ src/domain_conf.c 30 Jul 2008 16:21:54 -0000 @@ -1838,32 +1838,57 @@ return NULL; } +/* Called from SAX on parsing errors in the XML. */ +static void +catchXMLError (void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; + + if (ctxt && + ctxt->lastError.level == XML_ERR_FATAL && + ctxt->lastError.message != NULL) { + virDomainReportError (ctxt->_private, VIR_ERR_XML_DETAIL, + ctxt->lastError.message, ctxt->lastError.line); + } +} virDomainDefPtr virDomainDefParseString(virConnectPtr conn, virCapsPtr caps, const char *xmlStr) { - xmlDocPtr xml; + xmlParserCtxtPtr pctxt; + xmlDocPtr xml = NULL; xmlNodePtr root; virDomainDefPtr def = NULL; - if (!(xml = xmlReadDoc(BAD_CAST xmlStr, "domain.xml", NULL, - XML_PARSE_NOENT | XML_PARSE_NONET | - XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { - virDomainReportError(conn, VIR_ERR_XML_ERROR, NULL); - return NULL; + /* Set up a parser context so we can catch the details of XML errors. */ + pctxt = xmlNewParserCtxt (); + if (!pctxt || !pctxt->sax) + goto cleanup; + pctxt->sax->error = catchXMLError; + pctxt->_private = conn; + + xml = xmlCtxtReadDoc (pctxt, BAD_CAST xmlStr, "domain.xml", NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + if (!xml) { + /* virDomainReportError has already been called by the + * callback function (hopefully). + */ + goto cleanup; } if ((root = xmlDocGetRootElement(xml)) == NULL) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", _("missing root element")); - xmlFreeDoc(xml); - return NULL; + goto cleanup; } def = virDomainDefParseNode(conn, caps, xml, root); - xmlFreeDoc(xml); +cleanup: + xmlFreeParserCtxt (pctxt); + xmlFreeDoc (xml); return def; } @@ -1871,27 +1896,39 @@ virCapsPtr caps, const char *filename) { - xmlDocPtr xml; + xmlParserCtxtPtr pctxt; + xmlDocPtr xml = NULL; xmlNodePtr root; virDomainDefPtr def = NULL; - if (!(xml = xmlReadFile(filename, NULL, - XML_PARSE_NOENT | XML_PARSE_NONET | - XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { - virDomainReportError(conn, VIR_ERR_XML_ERROR, NULL); - return NULL; + /* Set up a parser context so we can catch the details of XML errors. */ + pctxt = xmlNewParserCtxt (); + if (!pctxt || !pctxt->sax) + goto cleanup; + pctxt->sax->error = catchXMLError; + pctxt->_private = conn; + + xml = xmlCtxtReadFile (pctxt, filename, NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + if (!xml) { + /* virDomainReportError has already been called by the + * callback function (hopefully). + */ + goto cleanup; } if ((root = xmlDocGetRootElement(xml)) == NULL) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", _("missing root element")); - xmlFreeDoc(xml); - return NULL; + goto cleanup; } def = virDomainDefParseNode(conn, caps, xml, root); - xmlFreeDoc(xml); +cleanup: + xmlFreeParserCtxt (pctxt); + xmlFreeDoc (xml); return def; } Index: src/network_conf.c =================================================================== RCS file: /data/cvs/libvirt/src/network_conf.c,v retrieving revision 1.3 diff -u -r1.3 network_conf.c --- src/network_conf.c 25 Jul 2008 14:27:25 -0000 1.3 +++ src/network_conf.c 30 Jul 2008 16:21:54 -0000 @@ -348,57 +348,95 @@ return NULL; } +/* Called from SAX on parsing errors in the XML. */ +static void +catchXMLError (void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; + + if (ctxt && + ctxt->lastError.level == XML_ERR_FATAL && + ctxt->lastError.message != NULL) { + virNetworkReportError (ctxt->_private, VIR_ERR_XML_DETAIL, + ctxt->lastError.message, ctxt->lastError.line); + } +} + virNetworkDefPtr virNetworkDefParseString(virConnectPtr conn, const char *xmlStr) { - xmlDocPtr xml; + xmlParserCtxtPtr pctxt; + xmlDocPtr xml = NULL; xmlNodePtr root; - virNetworkDefPtr def; + virNetworkDefPtr def = NULL; - if (!(xml = xmlReadDoc(BAD_CAST xmlStr, "network.xml", NULL, - XML_PARSE_NOENT | XML_PARSE_NONET | - XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { - virNetworkReportError(conn, VIR_ERR_XML_ERROR, NULL); - return NULL; + /* Set up a parser context so we can catch the details of XML errors. */ + pctxt = xmlNewParserCtxt (); + if (!pctxt || !pctxt->sax) + goto cleanup; + pctxt->sax->error = catchXMLError; + pctxt->_private = conn; + + xml = xmlCtxtReadDoc (pctxt, BAD_CAST xmlStr, "network.xml", NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + if (!xml) { + /* virNetworkReportError has already been called by the + * callback function (hopefully). + */ + goto cleanup; } if ((root = xmlDocGetRootElement(xml)) == NULL) { virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", _("missing root element")); - xmlFreeDoc(xml); - return NULL; + goto cleanup; } def = virNetworkDefParseNode(conn, xml, root); - xmlFreeDoc(xml); +cleanup: + xmlFreeParserCtxt (pctxt); + xmlFreeDoc (xml); return def; } virNetworkDefPtr virNetworkDefParseFile(virConnectPtr conn, const char *filename) { - xmlDocPtr xml; + xmlParserCtxtPtr pctxt; + xmlDocPtr xml = NULL; xmlNodePtr root; - virNetworkDefPtr def; + virNetworkDefPtr def = NULL; - if (!(xml = xmlReadFile(filename, NULL, - XML_PARSE_NOENT | XML_PARSE_NONET | - XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { - virNetworkReportError(conn, VIR_ERR_XML_ERROR, NULL); - return NULL; + /* Set up a parser context so we can catch the details of XML errors. */ + pctxt = xmlNewParserCtxt (); + if (!pctxt || !pctxt->sax) + goto cleanup; + pctxt->sax->error = catchXMLError; + pctxt->_private = conn; + + xml = xmlCtxtReadFile (pctxt, filename, NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + if (!xml) { + /* virNetworkReportError has already been called by the + * callback function (hopefully). + */ + goto cleanup; } if ((root = xmlDocGetRootElement(xml)) == NULL) { virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", _("missing root element")); - xmlFreeDoc(xml); - return NULL; + goto cleanup; } def = virNetworkDefParseNode(conn, xml, root); - xmlFreeDoc(xml); +cleanup: + xmlFreeParserCtxt (pctxt); + xmlFreeDoc (xml); return def; } Index: src/storage_conf.c =================================================================== RCS file: /data/cvs/libvirt/src/storage_conf.c,v retrieving revision 1.10 diff -u -r1.10 storage_conf.c --- src/storage_conf.c 25 Jul 2008 14:27:25 -0000 1.10 +++ src/storage_conf.c 30 Jul 2008 16:21:55 -0000 @@ -361,22 +361,46 @@ return NULL; } +/* Called from SAX on parsing errors in the XML. */ +static void +catchXMLError (void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; + + if (ctxt && + ctxt->lastError.level == XML_ERR_FATAL && + ctxt->lastError.message != NULL) { + virStorageReportError (ctxt->_private, VIR_ERR_XML_DETAIL, + ctxt->lastError.message, ctxt->lastError.line); + } +} + virStoragePoolDefPtr virStoragePoolDefParse(virConnectPtr conn, const char *xmlStr, const char *filename) { virStoragePoolDefPtr ret = NULL; + xmlParserCtxtPtr pctxt; xmlDocPtr xml = NULL; xmlNodePtr node = NULL; xmlXPathContextPtr ctxt = NULL; - if (!(xml = xmlReadDoc(BAD_CAST xmlStr, - filename ? filename : "storage.xml", - NULL, - XML_PARSE_NOENT | XML_PARSE_NONET | - XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { - virStorageReportError(conn, VIR_ERR_XML_ERROR, - "%s", _("malformed xml document")); + /* Set up a parser context so we can catch the details of XML errors. */ + pctxt = xmlNewParserCtxt (); + if (!pctxt || !pctxt->sax) + goto cleanup; + pctxt->sax->error = catchXMLError; + pctxt->_private = conn; + + xml = xmlCtxtReadDoc (pctxt, BAD_CAST xmlStr, + filename ? filename : "storage.xml", + NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + if (!xml) { + /* virStorageReportError has already been called by the + * callback function (hopefully). + */ goto cleanup; } @@ -396,12 +420,14 @@ ret = virStoragePoolDefParseDoc(conn, ctxt, node); + xmlFreeParserCtxt (pctxt); xmlXPathFreeContext(ctxt); xmlFreeDoc(xml); return ret; cleanup: + xmlFreeParserCtxt (pctxt); xmlXPathFreeContext(ctxt); xmlFreeDoc(xml); return NULL; @@ -725,15 +751,26 @@ const char *xmlStr, const char *filename) { virStorageVolDefPtr ret = NULL; + xmlParserCtxtPtr pctxt; xmlDocPtr xml = NULL; xmlNodePtr node = NULL; xmlXPathContextPtr ctxt = NULL; - if (!(xml = xmlReadDoc(BAD_CAST xmlStr, filename ? filename : "storage.xml", NULL, - XML_PARSE_NOENT | XML_PARSE_NONET | - XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { - virStorageReportError(conn, VIR_ERR_XML_ERROR, - "%s", _("malformed xml document")); + /* Set up a parser context so we can catch the details of XML errors. */ + pctxt = xmlNewParserCtxt (); + if (!pctxt || !pctxt->sax) + goto cleanup; + pctxt->sax->error = catchXMLError; + pctxt->_private = conn; + + xml = xmlCtxtReadDoc (pctxt, BAD_CAST xmlStr, + filename ? filename : "storage.xml", NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + if (!xml) { + /* virStorageReportError has already been called by the + * callback function (hopefully). + */ goto cleanup; } @@ -753,12 +790,14 @@ ret = virStorageVolDefParseDoc(conn, pool, ctxt, node); + xmlFreeParserCtxt (pctxt); xmlXPathFreeContext(ctxt); xmlFreeDoc(xml); return ret; cleanup: + xmlFreeParserCtxt (pctxt); xmlXPathFreeContext(ctxt); xmlFreeDoc(xml); return NULL;