1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
4 *
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
6 *
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
13 *
14 */
15
16 #include "XMLObject.hxx"
17 #include "XMLValidation.hxx"
18 #include "XMLValidationRelaxNG.hxx"
19 #include "XMLDocument.hxx"
20 #include "VariableScope.hxx"
21
22 extern "C"
23 {
24 #include "expandPathVariable.h"
25 #include "sci_malloc.h"
26 #include "localization.h"
27 #include "BOOL.h"
28 }
29
30 namespace org_modules_xml
31 {
32
XMLValidationRelaxNG(const char * path,std::string * error)33 XMLValidationRelaxNG::XMLValidationRelaxNG(const char *path, std::string * error): XMLValidation()
34 {
35 char *expandedPath = expandPathVariable(const_cast < char *>(path));
36 if (expandedPath)
37 {
38 xmlRelaxNGParserCtxt *pctxt = xmlRelaxNGNewParserCtxt(expandedPath);
39 FREE(expandedPath);
40 if (!pctxt)
41 {
42 errorBuffer.clear();
43 errorBuffer.append(gettext("Cannot create a validation context"));
44 *error = errorBuffer;
45 }
46 else
47 {
48 validationFile = (void *)xmlRelaxNGParse(pctxt);
49 xmlRelaxNGFreeParserCtxt(pctxt);
50 if (!validationFile)
51 {
52 errorBuffer.clear();
53 errorBuffer.append(gettext("Cannot parse the Relax NG grammar"));
54 *error = errorBuffer;
55 }
56 else
57 {
58 openValidationFiles.push_back(this);
59 }
60 }
61 }
62 else
63 {
64 *error = std::string(gettext("Invalid file name: ")) + std::string(path);
65 }
66
67 scope->registerPointers(validationFile, this);
68 id = scope->getVariableId(*this);
69 }
70
~XMLValidationRelaxNG()71 XMLValidationRelaxNG::~XMLValidationRelaxNG()
72 {
73 scope->unregisterPointer(validationFile);
74 scope->removeId(id);
75 if (validationFile)
76 {
77 xmlRelaxNGFree((xmlRelaxNG *) validationFile);
78 openValidationFiles.remove(this);
79 if (openValidationFiles.size() == 0 && XMLDocument::getOpenDocuments().size() == 0)
80 {
81 resetScope();
82 }
83 }
84
85 errorBuffer.clear();
86 }
87
validate(const XMLDocument & doc,std::string * error) const88 bool XMLValidationRelaxNG::validate(const XMLDocument & doc, std::string * error) const
89 {
90 bool ret;
91 xmlRelaxNGValidCtxt *vctxt = xmlRelaxNGNewValidCtxt((xmlRelaxNG *) validationFile);
92
93 errorBuffer.clear();
94
95 if (!vctxt)
96 {
97 errorBuffer.append(gettext("Cannot create a validation context"));
98 *error = errorBuffer;
99 return false;
100 }
101
102 xmlRelaxNGSetValidErrors(vctxt, (xmlRelaxNGValidityErrorFunc) XMLValidation::errorFunction, 0, 0);
103
104 ret = BOOLtobool(xmlRelaxNGValidateDoc(vctxt, doc.getRealDocument()));
105
106 xmlRelaxNGSetValidErrors(vctxt, 0, 0, 0);
107 xmlRelaxNGFreeValidCtxt(vctxt);
108
109 if (ret)
110 {
111 *error = errorBuffer;
112 }
113
114 return ret == 0;
115 }
116
validate(xmlTextReader * reader,std::string * error) const117 bool XMLValidationRelaxNG::validate(xmlTextReader * reader, std::string * error) const
118 {
119 int last;
120 int valid;
121
122 errorBuffer.clear();
123
124 xmlTextReaderSetErrorHandler(reader, (xmlTextReaderErrorFunc) XMLValidation::errorReaderFunction, 0);
125 xmlTextReaderRelaxNGSetSchema(reader, getValidationFile < xmlRelaxNG > ());
126
127 while ((last = xmlTextReaderRead(reader)) == 1)
128 {
129 ;
130 }
131 valid = xmlTextReaderIsValid(reader);
132
133 xmlTextReaderSetErrorHandler(reader, 0, 0);
134 xmlFreeTextReader(reader);
135
136 if (last == -1 || valid != 1)
137 {
138 *error = errorBuffer;
139 return false;
140 }
141
142 return true;
143 }
144
toString() const145 const std::string XMLValidationRelaxNG::toString() const
146 {
147 return std::string("XML Relax NG\nNo public information");
148 }
149 }
150
151