read data in the tlist whit polynom $
[scilab.git] / scilab / modules / ast / src / cpp / types / tlist.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2010-2010 - DIGITEO - Antoine ELIAS
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include <cstring>
14 #include <sstream>
15 #include "string.hxx"
16 #include "list.hxx"
17 #include "tlist.hxx"
18 #include "listundefined.hxx"
19 #include "callable.hxx"
20 #include "overload.hxx"
21 #include "execvisitor.hxx"
22
23 #ifndef NDEBUG
24 #include "inspector.hxx"
25 #endif
26
27 extern "C"
28 {
29 #include "os_string.h"
30 }
31
32 namespace types
33 {
34 /**
35 ** Constructor & Destructor (public)
36 */
37 TList::TList() : List()
38 {
39 #ifndef NDEBUG
40     Inspector::addItem(this);
41 #endif
42 }
43
44 TList::~TList()
45 {
46 #ifndef NDEBUG
47     Inspector::removeItem(this);
48 #endif
49 }
50
51 /**
52 ** Clone
53 ** Create a new List and Copy all values.
54 */
55 InternalType* TList::clone()
56 {
57     return new TList(this);
58 }
59
60 bool TList::exists(const std::wstring& _sKey)
61 {
62     if (getSize() < 1)
63     {
64         return false;
65     }
66
67     String* pS = getFieldNames();
68
69     //first field is the tlist type
70     for (int i = 1 ; i < pS->getSize() ; i++)
71     {
72         if (wcscmp(pS->get(i), _sKey.c_str()) == 0)
73         {
74             return true;
75         }
76     }
77     return false;
78 }
79
80 bool TList::invoke(typed_list & in, optional_list & /*opt*/, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::Exp & /*e*/)
81 {
82     if (in.size() == 0)
83     {
84         out.push_back(this);
85         return true;
86     }
87     else if (in.size() == 1)
88     {
89         InternalType * arg = in[0];
90         InternalType * _out = NULL;
91         if (arg->isDouble() || arg->isInt() || arg->isBool() || arg->isImplicitList() || arg->isColon() || arg->isDollar())
92         {
93             _out = List::extract(&in);
94             if (_out == NULL)
95             {
96                 // invalid index
97                 return false;
98             }
99
100             List* pList = _out->getAs<types::List>();
101             for (int i = 0; i < pList->getSize(); i++)
102             {
103                 out.push_back(pList->get(i));
104             }
105
106             delete pList;
107         }
108         else if (arg->isString())
109         {
110             std::list<std::wstring> stFields;
111             String * pString = arg->getAs<types::String>();
112             for (int i = 0; i < pString->getSize(); ++i)
113             {
114                 stFields.push_back(pString->get(i));
115             }
116
117             _out = extractStrings(stFields);
118             if (_out == NULL)
119             {
120                 // invalid index
121                 return false;
122             }
123
124             List* pList = _out->getAs<types::List>();
125             for (int i = 0; i < pList->getSize(); i++)
126             {
127                 out.push_back(pList->get(i));
128             }
129
130             delete pList;
131         }
132         else if (arg->isPoly())
133         {
134             Polynom* pPoly = arg->getAs<Polynom>();
135             SinglePoly* pSinglePoly = pPoly->get(0);
136
137             int iMaxDim = 0;
138             double dblParse = -1 * pSinglePoly->get(0);
139             int iSize = getSize();
140
141             if (pSinglePoly->getRank() < 2 && dblParse >= 0 && dblParse < (double)iSize)
142             {
143                 out.push_back(get(iSize - 1 - dblParse));
144             }
145             else
146             {
147                 return false;
148             }
149         }
150
151         if (out.empty() == false)
152         {
153             return true;
154         }
155     }
156     Callable::ReturnValue ret;
157     // Overload of extraction need
158     // the tlist from where we extract
159     this->IncreaseRef();
160     in.push_back(this);
161
162     std::wstring stType = getShortTypeStr();
163     try
164     {
165         ret = Overload::call(L"%" + stType + L"_e", in, _iRetCount, out, &execFunc);
166     }
167     catch (ast::ScilabError &se)
168     {
169         try
170         {
171             //to compatibility with scilab 5 code.
172             //tlist/mlist name are truncated to 8 first character
173             if (stType.size() > 8)
174             {
175                 std::wcout << (L"%" + stType.substr(0, 8) + L"_e") << std::endl;
176                 ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, 1, out, &execFunc);
177             }
178             else
179             {
180                 throw se;
181             }
182         }
183         catch (ast::ScilabError & /*se*/)
184         {
185             ret = Overload::call(L"%l_e", in, 1, out, &execFunc);
186         }
187     }
188
189     // Remove this from "in" for keep "in" unchanged.
190     this->DecreaseRef();
191     in.pop_back();
192
193     if (ret == Callable::Error)
194     {
195         throw ast::ScilabError();
196     }
197
198     return true;
199 }
200
201 bool TList::extract(const std::wstring & name, InternalType *& out)
202 {
203     if (exists(name))
204     {
205         out = getField(name);
206         return true;
207     }
208
209     return false;
210 }
211
212 InternalType* TList::getField(const std::wstring& _sKey)
213 {
214     return List::get(getIndexFromString(_sKey));
215 }
216
217 int TList::getIndexFromString(const std::wstring& _sKey)
218 {
219     if (getSize() < 1)
220     {
221         return -1;
222     }
223
224     String* pS = getFieldNames();
225     //first field is the tlist type
226     for (int i = 1 ; i < pS->getSize() ; i++)
227     {
228         if (wcscmp(pS->get(i), _sKey.c_str()) == 0)
229         {
230             return i;
231         }
232     }
233     return -1;
234 }
235
236 InternalType* TList::extractStrings(const std::list<std::wstring>& _stFields)
237 {
238     int i = 0;
239     List* pLResult = new List();
240     std::list<std::wstring>::const_iterator it;
241     for (it = _stFields.begin() ; it != _stFields.end() ; it++)
242     {
243         if (exists(*it) == false)
244         {
245             return pLResult;
246         }
247     }
248
249     for (it = _stFields.begin() ; it != _stFields.end() ; it++, i++)
250     {
251         InternalType* pIT = getField(*it);
252         if (pIT == NULL)
253         {
254             delete pLResult;
255             return NULL;
256         }
257
258         pLResult->set(i, pIT);
259     }
260
261     return pLResult;
262 }
263
264 std::wstring TList::getTypeStr()
265 {
266     if (getSize() < 1)
267     {
268         return L"";
269     }
270
271     return getFieldNames()->get(0);
272 }
273
274 std::wstring TList::getShortTypeStr()
275 {
276     return getTypeStr();
277 }
278
279 bool TList::set(const std::wstring& _sKey, InternalType* _pIT)
280 {
281     return List::set(getIndexFromString(_sKey), _pIT);
282 }
283
284 bool TList::set(const int _iIndex, InternalType* _pIT)
285 {
286     return List::set(_iIndex, _pIT);
287 }
288
289 String* TList::getFieldNames()
290 {
291     return (*m_plData)[0]->getAs<types::String>();
292 }
293
294 /**
295 ** toString to display TLists
296 */
297 bool TList::toString(std::wostringstream& ostr)
298 {
299     //call overload %type_p if exists
300     types::typed_list in;
301     types::typed_list out;
302     ast::ExecVisitor exec;
303
304     IncreaseRef();
305     in.push_back(this);
306
307     try
308     {
309         if (Overload::generateNameAndCall(L"p", in, 1, out, &exec) == Function::Error)
310         {
311             ConfigVariable::setError();
312         }
313
314         ostr.str(L"");
315         DecreaseRef();
316         return true;
317     }
318     catch (ast::ScilabError /* &e */)
319     {
320         // avoid error message about undefined overload %type_p
321         ConfigVariable::resetError();
322     }
323
324     DecreaseRef();
325
326     // special case for lss
327     if (getSize() != 0 &&
328             (*m_plData)[0]->isString() &&
329             (*m_plData)[0]->getAs<types::String>()->getSize() > 0 &&
330             wcscmp((*m_plData)[0]->getAs<types::String>()->get(0), L"lss") == 0)
331     {
332         wchar_t* wcsVarName = os_wcsdup(ostr.str().c_str());
333         int iPosition = 1;
334         const wchar_t * wcsDesc[7] = {L"  (state-space system:)", L"= A matrix =", L"= B matrix =", L"= C matrix =", L"= D matrix =", L"= X0 (initial state) =", L"= Time domain ="};
335         for (auto val : *m_plData)
336         {
337             std::wostringstream nextVarName;
338             ostr.str(L"");
339             nextVarName << " " << wcsVarName << L"(" << iPosition << L")";
340             ostr << std::endl << nextVarName.str() << wcsDesc[iPosition - 1] << std::endl << std::endl;
341             scilabWriteW(ostr.str().c_str());
342             VariableToString(val, nextVarName.str().c_str());
343             iPosition++;
344         }
345         ostr.str(L"");
346         free(wcsVarName);
347         return true;
348     }
349
350     // call normal toString
351     return List::toString(ostr);
352 }
353 } // end namespace types