* Bug 14606 fixed: now `[names,mem]=who()` returns memory used by variables
[scilab.git] / scilab / modules / core / sci_gateway / cpp / sci_who.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
4  *  Copyright (C) 2014 - Scilab Enterprises - Cedric Delamarre
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16
17
18 #include <sstream>
19 #include "core_gw.hxx"
20 #include "function.hxx"
21 #include "context.hxx"
22 #include "scilabWrite.hxx"
23 #include "string.hxx"
24
25 extern "C"
26 {
27 #include "Scierror.h"
28 #include "localization.h"
29 #include "sciprint.h"
30 }
31
32 types::Function::ReturnValue sci_who(types::typed_list& in, int _iRetCount, types::typed_list& out)
33 {
34     std::wstring wcsWhat(L"");
35     bool bSorted = false;
36     std::list<std::pair<std::wstring, int>> lstVarWithSize;
37     int size = 0;
38
39     if (in.size() > 2)
40     {
41         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "who", 0, 2);
42         return types::Function::Error;
43     }
44
45     if (_iRetCount > 2)
46     {
47         Scierror(78, _("%s: Wrong number of output argument(s): %d to %d expected.\n"), "who", 0, 2);
48         return types::Function::Error;
49     }
50
51     if (in.size() == 0)
52     {
53         std::wstringstream wstream;
54         symbol::Context::getInstance()->print(wstream, bSorted);
55         wstream << std::endl;
56         scilabForcedWriteW(wstream.str().c_str());
57         return types::Function::OK;
58     }
59
60     if (in.size() == 2)
61     {
62         if (in[1]->isString() == false)
63         {
64             Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "who", 2);
65             return types::Function::Error;
66         }
67
68         types::String* pStrSorted = in[1]->getAs<types::String>();
69
70         if (pStrSorted->isScalar() == false)
71         {
72             Scierror(999, _("%s: Wrong type for input argument #%d: A single string expected.\n"), "who", 2);
73             return types::Function::Error;
74         }
75
76         if (wcscmp(pStrSorted->get(0), L"sorted") == 0)
77         {
78             bSorted = true;
79         }
80         else
81         {
82             Scierror(999, _("%s: Wrong value for input argument #%d: 'sorted' expected.\n"), "who", 2);
83             return types::Function::Error;
84         }
85     }
86
87     if (in.size() > 0)
88     {
89         if (in[0]->isString() == false)
90         {
91             Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "who", 1);
92             return types::Function::Error;
93         }
94
95         types::String* pStrWhat = in[0]->getAs<types::String>();
96
97         if (pStrWhat->isScalar() == false)
98         {
99             Scierror(999, _("%s: Wrong type for input argument #%d: A single string expected.\n"), "who", 1);
100             return types::Function::Error;
101         }
102
103         wcsWhat = pStrWhat->get(0);
104     }
105
106     if (wcsWhat == L"local" || wcsWhat == L"get")
107     {
108         size = symbol::Context::getInstance()->getVarsInfoForWho(lstVarWithSize, bSorted);
109     }
110     else if (wcsWhat == L"scope" || wcsWhat == L"current")
111     {
112         size = symbol::Context::getInstance()->getCurrentScope(lstVarWithSize, bSorted);
113     }
114     else if (wcsWhat == L"global")
115     {
116         size = symbol::Context::getInstance()->getGlobalInfoForWho(lstVarWithSize, bSorted);
117     }
118     else if (bSorted == false && wcsWhat == L"sorted")
119     {
120         bSorted = true;
121         std::wstringstream wstream;
122         symbol::Context::getInstance()->print(wstream, bSorted);
123         wstream << std::endl;
124         scilabForcedWriteW(wstream.str().c_str());
125         return types::Function::OK;
126     }
127     else
128     {
129         if (bSorted)
130         {
131             Scierror(999, _("%s: Wrong value for input argument #%d: 'local', 'get' or 'global' expected.\n"), "who", 1);
132         }
133         else
134         {
135             Scierror(999, _("%s: Wrong value for input argument #%d: 'local', 'get', 'global' or 'sorted' expected.\n"), "who", 1);
136         }
137
138         return types::Function::Error;
139     }
140
141     if (lstVarWithSize.empty())
142     {
143         out.push_back(types::Double::Empty());
144         if (_iRetCount == 2)
145         {
146             out.push_back(types::Double::Empty());
147         }
148
149         return types::Function::OK;
150     }
151
152     types::String* pStrOut = new types::String(size, 1);
153     int i = 0;
154     for (auto it : lstVarWithSize)
155     {
156         pStrOut->set(i++, it.first.c_str());
157     }
158     out.push_back(pStrOut);
159
160     if (_iRetCount == 2)
161     {
162         types::Double* pDblOut = new types::Double(size, 1);
163         i = 0;
164         for (auto it : lstVarWithSize)
165         {
166             pDblOut->set(i++, it.second);
167         }
168         out.push_back(pDblOut);
169     }
170
171     return types::Function::OK;
172 }