* scicos_log() support options parameters to retrieve model statistics.
[scilab.git] / scilab / modules / scicos / sci_gateway / cpp / sci_scicos_log.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
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 "gw_scicos.hxx"
19
20 #include "types.hxx"
21 #include "string.hxx"
22 #include "double.hxx"
23 #include "mlist.hxx"
24 #include "list.hxx"
25 #include "function.hxx"
26
27 #include "Controller.hxx"
28 #include "LoggerView.hxx"
29 #include "utilities.hxx"
30 #include "controller_helpers.hxx"
31
32 extern "C"
33 {
34 #include "Scierror.h"
35 #include "localization.h"
36 }
37
38 using namespace org_scilab_modules_scicos;
39
40 static const std::string funame = "scicos_log";
41
42 types::Function::ReturnValue sci_scicos_log(types::typed_list &in, int _iRetCount, types::typed_list &out)
43 {
44     if (in.size() > 2)
45     {
46         Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), funame.data(), 0, 2);
47         return types::Function::Error;
48     }
49     if (!(0 <= _iRetCount && _iRetCount <= 1))
50     {
51         Scierror(999, _("%s: Wrong number of output arguments: %d to %d expected.\n"), funame.data(), 0, 1);
52         return types::Function::Error;
53     }
54
55     if (in.size() == 0)
56     {
57         LoggerView* logger = get_or_allocate_logger();
58         enum LogLevel previous = logger->getLevel();
59
60         if (_iRetCount == 1)
61         {
62             out.push_back(new types::String(LoggerView::toString(previous)));
63         }
64
65         return types::Function::OK;
66     }
67
68     types::InternalType* internLevel = in[0];
69     if (internLevel->getType() != types::InternalType::ScilabString)
70     {
71         Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), funame.data(), 1);
72         return types::Function::Error;
73     }
74     types::String* strLevel = internLevel->getAs<types::String>();
75     if (strLevel->getSize() != 1)
76     {
77         Scierror(999, _("%s: Wrong size for input argument #%d: String expected.\n"), funame.data(), 1);
78         return types::Function::Error;
79     }
80
81     /*
82      * specific usages :
83      */
84
85     // "refCounters" will return reference counters per object, per kind
86     if (std::wstring(L"refCounters") == strLevel->get(0))
87     {
88         Controller controller;
89
90         std::vector<ScicosID> objects;
91         std::vector<ScicosID> tmp;
92
93         tmp = controller.getAll(BLOCK);
94         objects.insert(objects.end(), tmp.begin(), tmp.end());
95         tmp = controller.getAll(DIAGRAM);
96         objects.insert(objects.end(), tmp.begin(), tmp.end());
97         tmp = controller.getAll(LINK);
98         objects.insert(objects.end(), tmp.begin(), tmp.end());
99         tmp = controller.getAll(ANNOTATION);
100         objects.insert(objects.end(), tmp.begin(), tmp.end());
101
102         types::Double* refCounts = new types::Double((int) objects.size(), 3);
103
104         for (int i = 0; i < objects.size(); ++i)
105         {
106             model::BaseObject* o = controller.getObject(objects[i]);
107
108             refCounts->set(i, 0, o->id());
109             refCounts->set(i, 1, o->kind());
110             refCounts->set(i, 2, o->refCount());
111         }
112
113         out.push_back(refCounts);
114         return types::Function::OK;
115     }
116
117     /*
118      * default usage: log level setting
119      */
120
121     enum LogLevel logLevel = LoggerView::indexOf(strLevel->get(0));
122     if (logLevel < 0)
123     {
124         std::wstringstream buffer;
125         for (int i = LOG_TRACE; i < LOG_FATAL; i++)
126         {
127             buffer << LoggerView::toString(static_cast<enum LogLevel>(i));
128             buffer << L", ";
129         }
130         buffer << LoggerView::toString(LOG_FATAL);
131
132         Scierror(999, _("%s: Wrong value for input argument #%d: Must be one of %ls.\n"), funame.data(), 1, buffer.str().data());
133         return types::Function::Error;
134     }
135
136     if (in.size() == 1)
137     {
138         /*
139          * Configure the logger value mode and return the previous log level
140          */
141         LoggerView* logger = get_or_allocate_logger();
142         enum LogLevel previous = logger->getLevel();
143         logger->setLevel(logLevel);
144
145         if (_iRetCount == 1)
146         {
147             out.push_back(new types::String(LoggerView::toString(previous)));
148         }
149     }
150     else
151     {
152         /*
153          * Log a message for a specific level and return the log level
154          */
155         types::InternalType* internMsg = in[1];
156         if (internMsg->getType() != types::InternalType::ScilabString)
157         {
158             Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), funame.data(), 2);
159             return types::Function::Error;
160         }
161         types::String* strMsg = internMsg->getAs<types::String>();
162         if (strMsg->getSize() != 1)
163         {
164             Scierror(999, _("%s: Wrong size for input argument #%d: String expected.\n"), funame.data(), 2);
165             return types::Function::Error;
166         }
167
168         LoggerView* logger = get_or_allocate_logger();
169         logger->log(logLevel, strMsg->get(0));
170
171         if (_iRetCount == 1)
172         {
173             out.push_back(new types::String(LoggerView::toString(logLevel)));
174         }
175     }
176
177     return types::Function::OK;
178 }