Files
swift-mirror/tools/swift-ide-test/XMLValidator.cpp
Dmitri Hrybenko 68e8fee5fc Comment parsing: put more information into the generated XML documents
This commit adds infrastructure for conversion and testing it.

The conversion is still incomplete, pending discussion about which tags should
we use in the XML documents.  I copied the RelaxNG schema from Clang, and will
edit it accordingly.


Swift SVN r16451
2014-04-17 15:42:51 +00:00

97 lines
2.7 KiB
C++

//===-- XMLValidator.cpp - XML validation ---------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include "XMLValidator.h"
#ifdef SWIFT_HAVE_LIBXML
// libxml headers use their own variant of documentation comments that Clang
// does not understand well.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdocumentation"
#include <libxml/parser.h>
#include <libxml/relaxng.h>
#include <libxml/xmlerror.h>
#pragma clang diagnostic pop
using namespace swift;
struct XMLValidator::Implementation {
std::string SchemaFileName;
xmlRelaxNGParserCtxtPtr RNGParser;
xmlRelaxNGPtr Schema;
};
XMLValidator::XMLValidator() : Impl(new Implementation()) {}
XMLValidator::~XMLValidator() { delete Impl; }
void XMLValidator::setSchema(StringRef FileName) {
assert(Impl->SchemaFileName.empty());
Impl->SchemaFileName = FileName;
}
XMLValidator::Status XMLValidator::validate(const std::string &XML) {
if (Impl->SchemaFileName.empty())
return Status{ErrorCode::NoSchema, ""};
if (!Impl->RNGParser) {
Impl->RNGParser = xmlRelaxNGNewParserCtxt(Impl->SchemaFileName.c_str());
Impl->Schema = xmlRelaxNGParse(Impl->RNGParser);
}
if (!Impl->RNGParser)
return Status{ErrorCode::InternalError, ""};
if (!Impl->Schema)
return Status{ErrorCode::BadSchema, ""};
xmlDocPtr Doc = xmlParseDoc(reinterpret_cast<const xmlChar *>(XML.data()));
if (!Doc)
return Status{ErrorCode::NotWellFormed, xmlGetLastError()->message};
xmlRelaxNGValidCtxtPtr ValidationCtxt = xmlRelaxNGNewValidCtxt(Impl->Schema);
int ValidationStatus = xmlRelaxNGValidateDoc(ValidationCtxt, Doc);
Status Result;
if (ValidationStatus == 0) {
Result = Status{ErrorCode::Valid, ""};
} else if (ValidationStatus > 0) {
Result = Status{ErrorCode::NotValid, xmlGetLastError()->message};
} else
Result = Status{ErrorCode::InternalError, ""};
xmlRelaxNGFreeValidCtxt(ValidationCtxt);
xmlFreeDoc(Doc);
return Result;
}
#else // !SWIFT_HAVE_LIBXML
using namespace swift;
struct XMLValidator::Implementation {};
XMLValidator::XMLValidator() : Impl(new Implementation()) {}
XMLValidator::~XMLValidator() { delete Impl; }
void XMLValidator::setSchema(StringRef FileName) {}
XMLValidator::Status XMLValidator::validate(const std::string &XML) {
return Status{ErrorCode::NotCompiledIn, ""};
}
#endif // SWIFT_HAVE_LIBXML