eb077e330857714b75b75081bd3977eea028a521
[scilab.git] / scilab / modules / slint / src / cpp / SLintXmlResult.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2015 - 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 <string>
17
18 #include "output/SLintXmlResult.hxx"
19 #include "checkers/SLintChecker.hxx"
20 #include "FileException.hxx"
21 #include "SLint.hxx"
22 #include "SciFile.hxx"
23 #include "UTF8.hxx"
24
25 extern "C"
26 {
27 #include "sci_malloc.h"
28 #include "charEncoding.h"
29 #include "localization.h"
30 }
31
32 namespace slint
33 {
34
35 SLintXmlResult::SLintXmlResult(const std::wstring & _path) : current(nullptr), path(_path)
36 {
37     const std::wstring fullpath = SLint::getFullPath(path);
38     out = new std::ofstream(scilab::UTF8::toUTF8(fullpath), std::ios::out);
39     if (!out->is_open())
40     {
41         delete out;
42         out = nullptr;
43         throw FileException(fullpath, L"Can\'t open it.");
44     }
45     else
46     {
47         (*out) << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
48                << "<SLintResult>\n";
49     }
50 }
51
52 SLintXmlResult::~SLintXmlResult()
53 {
54     if (out)
55     {
56         out->close();
57         delete out;
58     }
59 }
60
61 void SLintXmlResult::finalize()
62 {
63     (*out) << "</SLintResult>\n";
64     out->close();
65     delete out;
66     out = nullptr;
67 }
68
69 const std::string SLintXmlResult::getStr(const std::wstring & str)
70 {
71     return scilab::UTF8::toUTF8(replaceByEntities(str));
72 }
73
74     void SLintXmlResult::handleMessage(SLintContext & context, const Location & loc, const SLintChecker & checker, const unsigned sub, const std::wstring & msg)
75 {
76     if (context.getSciFile().get() != current.get())
77     {
78         if (current.get())
79         {
80             (*out) << "  </File>\n";
81         }
82         current = context.getSciFile();
83         print(current);
84     }
85     print(loc, checker, sub, msg);
86 }
87
88 void SLintXmlResult::print(const SciFilePtr & file)
89 {
90     (*out) << "  <File name=\"" << getStr(file->getFilename()) << "\">\n";
91 }
92
93 void SLintXmlResult::print(const Location & loc, const SLintChecker & checker, const unsigned sub, const std::wstring & msg)
94 {
95     (*out) << "    <Result>\n";
96     print(loc);
97     print(checker, sub);
98     print(msg);
99     (*out) << "    </Result>\n";
100 }
101
102 void SLintXmlResult::print(const Location & loc)
103 {
104     (*out) << "      <Location first_line=\"" << loc.first_line
105            << "\" first_column=\"" << loc.first_column
106            << "\" last_line=\"" << loc.last_line
107            << "\" last_column=\"" << loc.last_column
108            << "\"/>\n";
109 }
110
111     void SLintXmlResult::print(const SLintChecker & checker, const unsigned sub)
112 {
113     (*out) << "      <Checker name=\"" << checker.getName()
114            << "\" id=\"" << getStr(checker.getId(sub))
115            << "\"/>\n";
116 }
117
118 void SLintXmlResult::print(const std::wstring & msg)
119 {
120     (*out) << "      <Message text=\"" << getStr(msg)
121            << "\"/>\n";
122 }
123
124 std::wstring SLintXmlResult::replaceByEntities(const std::wstring & seq)
125 {
126     std::vector<wchar_t> buf;
127     for (auto c : seq)
128     {
129         if (c == L'<')
130         {
131             pushEntity(buf, L"&lt;", 4);
132         }
133         else if (c == L'>')
134         {
135             pushEntity(buf, L"&gt;", 4);
136         }
137         else if (c == L'\'')
138         {
139             pushEntity(buf, L"&apos;", 6);
140         }
141         else if (c == L'\"')
142         {
143             pushEntity(buf, L"&quot;", 6);
144         }
145         else if (c == L'&')
146         {
147             pushEntity(buf, L"&amp;", 5);
148         }
149         else
150         {
151             buf.push_back(c);
152         }
153     }
154
155     return std::wstring(buf.begin(), buf.end());
156 }
157
158 } // namespace slint