Merge remote-tracking branch 'origin/master' into windows
[scilab.git] / scilab / modules / ast / src / cpp / types / mlist.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2010-2010 - DIGITEO - 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 <sstream>
17 #include "mlist.hxx"
18 #include "callable.hxx"
19 #include "overload.hxx"
20 #include "configvariable.hxx"
21 #include "exp.hxx"
22
23 #ifndef NDEBUG
24 #include "inspector.hxx"
25 #endif
26
27 namespace types
28 {
29 bool MList::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & out, const ast::Exp & e)
30 {
31     if (in.size() == 0)
32     {
33         out.push_back(this);
34         return true;
35     }
36     else if (in.size() == 1)
37     {
38         InternalType * arg = in[0];
39         InternalType* _out = NULL;
40         if (arg->isString())
41         {
42             std::list<std::string> stFields;
43             String * pString = arg->getAs<types::String>();
44             for (int i = 0; i < pString->getSize(); ++i)
45             {
46                 stFields.push_back(pString->get(i));
47             }
48
49             _out = extractStrings(stFields);
50
51             List* pList = _out->getAs<types::List>();
52             for (int i = 0; i < pList->getSize(); i++)
53             {
54                 out.push_back(pList->get(i));
55             }
56
57             delete pList;
58         }
59
60         if (!out.empty())
61         {
62             return true;
63         }
64     }
65
66     Callable::ReturnValue ret;
67     // Overload of extraction need
68     // the mlist from where we extract
69     this->IncreaseRef();
70     in.push_back(this);
71
72     try
73     {
74         ret = Overload::call("%" + getShortTypeStr() + "_e", in, 1, out);
75     }
76     catch (ast::InternalError & /*se*/)
77     {
78         ret = Overload::call("%l_e", in, 1, out);
79     }
80
81     // Remove this from "in" for keep "in" unchanged.
82     this->DecreaseRef();
83     in.pop_back();
84
85     if (ret == Callable::Error)
86     {
87         throw ast::InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
88     }
89
90     return true;
91 }
92 }