fix closure of last <File> in result xml file and add contribution message
[scilab.git] / scilab / modules / slint / sci_gateway / cpp / sci_slint.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2006 - INRIA - Antoine ELIAS
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 <iostream>
17 #include <string>
18
19 #include "SLint.hxx"
20 #include "output/SLintScilabResult.hxx"
21 #include "output/SLintXmlResult.hxx"
22 #include "output/cnes/CNESXmlResult.hxx"
23 #include "output/cnes/CNESCsvResult.hxx"
24 #include "config/cnes/ToolConfiguration.hxx"
25 #include "config/XMLConfig.hxx"
26
27 #include "struct.hxx"
28 #include "string.hxx"
29 #include "slint_gw.hxx"
30
31 extern "C"
32 {
33 #include "Scierror.h"
34 #include "sciprint.h"
35 #include "localization.h"
36 }
37
38 static bool contributionMsg = true;
39 /**
40  * slint(String[a,b] files, String[1,c] conf, String[1,1] out)
41  * slint(String[a,b] files, String[1,1] out)                   : default conf is etc/slint.xml
42  * slint(String[a,b] files)                                    : default conf is etc/slint.xml & out is outputstream
43  * slint(String[a,b] files, bool[1,1] printResult)             : default conf is etc/slint.xml
44  * slint(String[a,b] files, String[1,c] conf, bool[1,1] printResult)
45  */
46
47 /*--------------------------------------------------------------------------*/
48 types::Function::ReturnValue sci_slint(types::typed_list & in, int _iRetCount, types::typed_list & out)
49 {
50     slint::SLintResult * results = nullptr;
51     bool printResults = false;
52     const int size = (int)in.size();
53     types::String * conf = nullptr;
54     types::String * outFile = nullptr;
55
56     if (size == 0 || size >= 4)
57     {
58         Scierror(999, _("%s: Wrong number of input arguments: at least %d expected.\n"), "slint", 1);
59         return types::Function::Error;
60     }
61
62     if (!in[0]->isString())
63     {
64         Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "slint", 1);
65         return types::Function::Error;
66     }
67
68     switch (size)
69     {
70         case 1:
71         {
72             printResults = true;
73             break;
74         }
75         case 2:
76         {
77             if (in[1]->isBool())
78             {
79                 if (in[1]->getAs<types::Bool>()->getSize() == 1)
80                 {
81                     printResults = in[1]->getAs<types::Bool>()->get(0) == 0 ? false : true;
82                 }
83                 else
84                 {
85                     Scierror(999, _("%s: Wrong type for input argument #%d: A single boolean expected.\n"), "slint", 2);
86                     return types::Function::Error;
87                 }
88             }
89             else if (in[1]->isString())
90             {
91                 outFile = in[1]->getAs<types::String>();
92             }
93             else
94             {
95                 Scierror(999, _("%s: Wrong type for input argument #%d: A string or a boolean expected.\n"), "slint", 2);
96                 return types::Function::Error;
97             }
98             break;
99         }
100         case 3:
101         {
102             if (in[2]->isBool())
103             {
104                 if (in[2]->getAs<types::Bool>()->getSize() == 1)
105                 {
106                     printResults = in[2]->getAs<types::Bool>()->get(0) == 0 ? false : true;
107                 }
108                 else
109                 {
110                     Scierror(999, _("%s: Wrong type for input argument #%d: A single boolean expected.\n"), "slint", 3);
111                     return types::Function::Error;
112                 }
113             }
114             else if (in[2]->isString())
115             {
116                 outFile = in[2]->getAs<types::String>();
117             }
118             else
119             {
120                 Scierror(999, _("%s: Wrong type for input argument #%d: A string or a boolean expected.\n"), "slint", 3);
121                 return types::Function::Error;
122             }
123
124             if (!in[1]->isString())
125             {
126                 Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "slint", 3);
127                 return types::Function::Error;
128             }
129             conf = in[1]->getAs<types::String>();
130             break;
131         }
132     }
133
134     try
135     {
136         slint::SLintOptions options;
137         if (conf)
138         {
139             if (conf->getSize() == 1)
140             {
141                 slint::XMLConfig::getOptions(conf->get(0), options);
142             }
143             else
144             {
145                 slint::XMLConfig::getOptions(*conf, options);
146             }
147         }
148         else
149         {
150             slint::XMLConfig::getOptions(L"SCI/modules/slint/etc/slint.xml", options);
151         }
152
153         if (outFile)
154         {
155             if (conf && conf->getSize() >= 2 && (std::wstring(conf->get(0)) == L"cnes"))
156             {
157                 const slint::CNES::ToolConfiguration tc = slint::CNES::ToolConfiguration::createFromXml(conf->get(1));
158                 const std::wstring out(outFile->get(0));
159                 const std::size_t pos = out.find_last_of(L'.');
160                 if (pos != std::string::npos && out.substr(pos) == L".csv")
161                 {
162                     results = new slint::CNES::CNESCsvResult(tc, conf, options.getId(), outFile->get(0));
163                 }
164                 else
165                 {
166                     results = new slint::CNES::CNESXmlResult(tc, conf, options.getId(), outFile->get(0));
167                 }
168             }
169             else
170             {
171                 results = new slint::SLintXmlResult(outFile->get(0));
172             }
173         }
174         else
175         {
176             if (printResults)
177             {
178                 results = new slint::SLintScilabResult();
179             }
180             else
181             {
182                 results = new slint::SLintScilabOut();
183             }
184         }
185
186         slint::SLint slint(options, *results);
187         slint.setFiles(in[0]->getAs<types::String>());
188         slint.check();
189         results->finalize();
190
191         if (!outFile && !printResults)
192         {
193             out.emplace_back(static_cast<slint::SLintScilabOut *>(results)->getStruct());
194         }
195     }
196     catch (slint::PCREException & e)
197     {
198         delete results;
199         Scierror(999, _("%s: %s\n"), "slint", e.what(), 1);
200         return types::Function::Error;
201     }
202     catch (slint::FileException & e)
203     {
204         delete results;
205         Scierror(999, _("%s: %s\n"), "slint", e.what(), 1);
206         return types::Function::Error;
207     }
208     catch (slint::SLintXMLException & e)
209     {
210         delete results;
211         Scierror(999, _("%s: %s\n"), "slint", e.what(), 1);
212         return types::Function::Error;
213     }
214
215     delete results;
216
217     if (contributionMsg)
218     {
219         sciprint("%s\n", _("Module developed with the contribution of CNES."));
220         contributionMsg = false;
221     }
222
223     return types::Function::OK;
224 }