9c3654698326488197cb99057625fa53691ae10a
[scilab.git] / scilab / modules / external_objects / src / cpp / invoke_lu.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
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 "ScilabGateway.hxx"
14
15 namespace org_modules_external_objects
16 {
17
18 int ScilabGateway::invoke_lu(char * fname, const int envId, void * pvApiCtx)
19 {
20     SciErr err;
21     int typ = 0;
22     int * addr = 0;
23     int * listaddr = 0;
24     int len = 0;
25     int * tmpvar = 0;
26     int idObj = 0;
27     int * args = 0;
28     int * child = 0;
29     char * methName = 0;
30     int * eId;
31     int row, col;
32     int * ret = 0;
33
34     CheckInputArgument(pvApiCtx, 4, 4);
35
36     err = getVarAddressFromPosition(pvApiCtx, 4, &listaddr);
37     if (err.iErr)
38     {
39         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
40     }
41
42     err = getVarType(pvApiCtx, listaddr, &typ);
43     if (err.iErr)
44     {
45         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
46     }
47
48     if (typ != sci_list)
49     {
50         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Wrong type for input argument #%d: A List expected."), 4);
51     }
52
53     err = getListItemNumber(pvApiCtx, listaddr, &len);
54     if (err.iErr)
55     {
56         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
57     }
58
59     // Get the environment id
60     err = getVarAddressFromPosition(pvApiCtx, 2, &addr);
61     if (err.iErr)
62     {
63         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
64     }
65
66     err = getVarType(pvApiCtx, addr, &typ);
67     if (err.iErr)
68     {
69         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
70     }
71
72     if (typ != sci_ints)
73     {
74         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Wrong type for input argument #%d: An Integer32 expected."), 2);
75     }
76     else
77     {
78         int prec;
79
80         err = getMatrixOfIntegerPrecision(pvApiCtx, addr, &prec);
81         if (err.iErr)
82         {
83             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
84         }
85
86         if (prec != SCI_INT32)
87         {
88             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Wrong type for input argument #%d: An Integer32 expected."), 2);
89         }
90
91         err = getMatrixOfInteger32(pvApiCtx, addr, &row, &col, &eId);
92         if (err.iErr)
93         {
94             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
95         }
96     }
97
98     ScilabAbstractEnvironment & env = ScilabEnvironments::getEnvironment(*eId);
99     ScilabGatewayOptions & options = env.getGatewayOptions();
100     OptionsHelper::setCopyOccurred(false);
101     ScilabObjects::initialization(env, pvApiCtx);
102     options.setIsNew(false);
103
104     // Get the object id
105     err = getVarAddressFromPosition(pvApiCtx, 1, &addr);
106     if (err.iErr)
107     {
108         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
109     }
110
111     err = getVarType(pvApiCtx, addr, &typ);
112     if (err.iErr)
113     {
114         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
115     }
116
117     if (typ != sci_ints)
118     {
119         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Wrong type for input argument #%d: An Integer32 expected."), 1);
120     }
121     else
122     {
123         int prec;
124         int * id;
125
126         err = getMatrixOfIntegerPrecision(pvApiCtx, addr, &prec);
127         if (err.iErr)
128         {
129             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
130         }
131
132         if (prec != SCI_INT32)
133         {
134             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Wrong type for input argument #%d: An Integer32 expected."), 1);
135         }
136
137         err = getMatrixOfInteger32(pvApiCtx, addr, &row, &col, &id);
138         if (err.iErr)
139         {
140             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
141         }
142
143         idObj = *id;
144     }
145
146     if (idObj == 0)
147     {
148         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Cannot invoke on null object."), __FILE__, __LINE__);
149     }
150
151     tmpvar = new int[len + 1];
152     *tmpvar = 0;
153
154     args = new int[len];
155
156     for (int i = 0; i < len; i++)
157     {
158         err = getListItemAddress(pvApiCtx, listaddr, i + 1, &child);
159         if (err.iErr)
160         {
161             delete[] args;
162             ScilabObjects::removeTemporaryVars(*eId, tmpvar);
163             delete[] tmpvar;
164             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
165         }
166
167         try
168         {
169             args[i] = ScilabObjects::getArgumentId(child, tmpvar, false, false, *eId, pvApiCtx);
170         }
171         catch (ScilabAbstractEnvironmentException & e)
172         {
173             delete[] args;
174             delete[] tmpvar;
175             throw;
176         }
177     }
178
179     try
180     {
181         methName = ScilabObjects::getSingleString(3, pvApiCtx);
182     }
183     catch (ScilabAbstractEnvironmentException & e)
184     {
185         delete[] args;
186         ScilabObjects::removeTemporaryVars(*eId, tmpvar);
187         delete[] tmpvar;
188         throw;
189     }
190
191     try
192     {
193         ret = env.invoke(idObj, methName, args, len);
194     }
195     catch (std::exception & e)
196     {
197         delete[] args;
198         ScilabObjects::removeTemporaryVars(*eId, tmpvar);
199         delete[] tmpvar;
200         freeAllocatedSingleString(methName);
201         throw;
202     }
203
204     delete[] args;
205     ScilabObjects::removeTemporaryVars(*eId, tmpvar);
206     delete[] tmpvar;
207     freeAllocatedSingleString(methName);
208
209     if (!ret || *ret <= 0 || (*ret == 1 && ret[1] == VOID_OBJECT))
210     {
211         if (ret)
212         {
213             delete[] ret;
214         }
215
216         PutLhsVar();
217
218         return 0;
219     }
220
221     for (int i = 1; i <= *ret; i++)
222     {
223         if (!ScilabObjects::unwrap(ret[i], Rhs + i, *eId, pvApiCtx))
224         {
225             try
226             {
227                 ScilabObjects::createEnvironmentObjectAtPos(EXTERNAL_OBJECT, Rhs + i, ret[i], *eId, pvApiCtx);
228             }
229             catch (ScilabAbstractEnvironmentException & e)
230             {
231                 for (int j = 1; j <= *ret; j++)
232                 {
233                     env.removeobject(ret[j]);
234                 }
235                 delete[] ret;
236                 throw;
237             }
238         }
239         else
240         {
241             env.removeobject(ret[i]);
242         }
243
244         LhsVar(i) = Rhs + i;
245     }
246
247     delete[] ret;
248
249     PutLhsVar();
250
251     return 0;
252 }
253 }