2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010-2010 - DIGITEO - Antoine ELIAS
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
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.
22 #include "listundefined.hxx"
23 #include "callable.hxx"
24 #include "polynom.hxx"
25 #include "overload.hxx"
26 #include "configvariable.hxx"
27 #include "types_tools.hxx"
28 #include "scilabWrite.hxx"
31 #include "inspector.hxx"
36 #include "os_string.h"
42 ** Constructor & Destructor (public)
44 TList::TList() : List()
47 Inspector::addItem(this);
54 Inspector::removeItem(this);
58 bool TList::getMemory(int* _piSize, int* _piSizePlusType)
62 for (auto pData : *m_plData)
65 if (pData->getMemory(&piS, &piSPT))
68 *_piSizePlusType += piSPT;
72 *_piSizePlusType += sizeof(TList);
78 ** Create a new List and Copy all values.
82 return new TList(this);
85 bool TList::exists(const std::wstring& _sKey)
92 String* pS = getFieldNames();
94 //first field is the tlist type
95 for (int i = 1 ; i < pS->getSize() ; i++)
97 if (wcscmp(pS->get(i), _sKey.c_str()) == 0)
105 bool TList::invoke(typed_list & in, optional_list & /*opt*/, int _iRetCount, typed_list & out, const ast::Exp & e)
112 else if (in.size() == 1)
114 InternalType * arg = in[0];
115 InternalType * _out = NULL;
116 if (arg->isDouble() || arg->isInt() || arg->isBool() || arg->isImplicitList() || arg->isColon() || arg->isDollar())
118 _out = List::extract(&in);
125 List* pList = _out->getAs<types::List>();
126 for (int i = 0; i < pList->getSize(); i++)
128 out.push_back(pList->get(i));
133 else if (arg->isString())
135 std::list<std::wstring> stFields;
136 String * pString = arg->getAs<types::String>();
137 for (int i = 0; i < pString->getSize(); ++i)
139 stFields.push_back(pString->get(i));
142 _out = extractStrings(stFields);
149 List* pList = _out->getAs<types::List>();
150 for (int i = 0; i < pList->getSize(); i++)
152 out.push_back(pList->get(i));
157 else if (arg->isPoly())
159 Polynom* pPoly = arg->getAs<Polynom>();
160 SinglePoly* pSinglePoly = pPoly->get(0);
163 double dblParse = -1 * pSinglePoly->get(0);
164 int iSize = getSize();
166 if (pSinglePoly->getRank() < 2 && dblParse >= 0 && dblParse < (double)iSize)
168 out.push_back(get(iSize - 1 - dblParse));
176 if (out.empty() == false)
181 Callable::ReturnValue ret;
182 // Overload of extraction need
183 // the tlist from where we extract
187 std::wstring stType = getShortTypeStr();
190 ret = Overload::call(L"%" + stType + L"_e", in, _iRetCount, out);
192 catch (const ast::InternalError &ie)
196 //to compatibility with scilab 5 code.
197 //tlist/mlist name are truncated to 8 first character
198 if (stType.size() > 8)
200 std::wcout << (L"%" + stType.substr(0, 8) + L"_e") << std::endl;
201 ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, _iRetCount, out);
208 catch (ast::InternalError & /*se*/)
210 ret = Overload::call(L"%l_e", in, _iRetCount, out);
214 // Remove this from "in" for keep "in" unchanged.
218 if (ret == Callable::Error)
220 throw ast::InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
226 bool TList::extract(const std::wstring & name, InternalType *& out)
230 out = getField(name);
237 InternalType* TList::getField(const std::wstring& _sKey)
239 return List::get(getIndexFromString(_sKey));
242 int TList::getIndexFromString(const std::wstring& _sKey)
249 String* pS = getFieldNames();
250 //first field is the tlist type
251 for (int i = 1 ; i < pS->getSize() ; i++)
253 if (wcscmp(pS->get(i), _sKey.c_str()) == 0)
261 InternalType* TList::extractStrings(const std::list<std::wstring>& _stFields)
264 List* pLResult = new List();
265 std::list<std::wstring>::const_iterator it;
266 for (it = _stFields.begin() ; it != _stFields.end() ; it++)
268 if (exists(*it) == false)
274 for (it = _stFields.begin() ; it != _stFields.end() ; it++, i++)
276 InternalType* pIT = getField(*it);
283 pLResult->set(i, pIT);
289 std::wstring TList::getTypeStr() const
296 return getFieldNames()->get(0);
299 std::wstring TList::getShortTypeStr() const
304 TList* TList::set(const std::wstring& _sKey, InternalType* _pIT)
306 return List::set(getIndexFromString(_sKey), _pIT)->getAs<TList>();
309 TList* TList::set(const int _iIndex, InternalType* _pIT)
311 return List::set(_iIndex, _pIT)->getAs<TList>();
314 String* TList::getFieldNames() const
316 return (*m_plData)[0]->getAs<types::String>();
320 ** toString to display TLists
322 bool TList::toString(std::wostringstream& ostr)
324 //call overload %type_p if exists
325 types::typed_list in;
326 types::typed_list out;
333 if (Overload::generateNameAndCall(L"p", in, 1, out) == Function::Error)
335 ConfigVariable::setError();
342 catch (ast::InternalError& e)
344 if (e.GetErrorType() == ast::TYPE_ERROR)
350 // avoid error message about undefined overload %type_p
351 ConfigVariable::resetError();
356 // special case for lss
357 if (getSize() != 0 &&
358 (*m_plData)[0]->isString() &&
359 (*m_plData)[0]->getAs<types::String>()->getSize() > 0 &&
360 wcscmp((*m_plData)[0]->getAs<types::String>()->get(0), L"lss") == 0)
362 wchar_t* wcsVarName = os_wcsdup(ostr.str().c_str());
364 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 ="};
365 for (auto val : *m_plData)
367 std::wostringstream nextVarName;
369 nextVarName << " " << wcsVarName << L"(" << iPosition << L")";
370 ostr << std::endl << nextVarName.str() << wcsDesc[iPosition - 1] << std::endl << std::endl;
371 scilabWriteW(ostr.str().c_str());
372 VariableToString(val, nextVarName.str().c_str());
380 // call normal toString
381 return List::toString(ostr);
383 } // end namespace types