1e84c4734c826ab218d1496bfd95637c08cc7c3f
[scilab.git] / scilab / modules / external_objects / src / cpp / invoke.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(char * fname, const int envId, void * pvApiCtx)
19 {
20     SciErr err;
21     int * tmpvar = 0;
22     int * addr = 0;
23     int * args = 0;
24     int idObj = 0;
25     int * ret = 0;
26     char * methName = 0;
27
28     if (Rhs < 2)
29     {
30         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Wrong number of arguments : more than 2 arguments expected"));
31     }
32
33     ScilabAbstractEnvironment & env = ScilabEnvironments::getEnvironment(envId);
34     ScilabGatewayOptions & options = env.getGatewayOptions();
35     OptionsHelper & helper = env.getOptionsHelper();
36     OptionsHelper::setCopyOccurred(false);
37     ScilabObjects::initialization(env, pvApiCtx);
38     options.setIsNew(false);
39
40     err = getVarAddressFromPosition(pvApiCtx, 1, &addr);
41     if (err.iErr)
42     {
43         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
44     }
45
46     tmpvar = new int[Rhs - 1];
47     *tmpvar = 0;
48
49     try
50     {
51         idObj = ScilabObjects::getArgumentId(addr, tmpvar, false, false, envId, pvApiCtx);
52     }
53     catch (ScilabAbstractEnvironmentException & e)
54     {
55         delete[] tmpvar;
56         throw;
57     }
58
59     if (idObj == 0)
60     {
61         delete[] tmpvar;
62         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Cannot invoke on null object"));
63     }
64
65     args = new int[Rhs - 2];
66
67     for (int i = 0; i < Rhs - 2; i++)
68     {
69         err = getVarAddressFromPosition(pvApiCtx, i + 3, &addr);
70         if (err.iErr)
71         {
72             delete[] args;
73             ScilabObjects::removeTemporaryVars(envId, tmpvar);
74             delete[] tmpvar;
75             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
76         }
77
78         try
79         {
80             args[i] = ScilabObjects::getArgumentId(addr, tmpvar, false, false, envId, pvApiCtx);
81         }
82         catch (ScilabAbstractEnvironmentException & e)
83         {
84             delete[] args;
85             ScilabObjects::removeTemporaryVars(envId, tmpvar);
86             delete[] tmpvar;
87             throw;
88         }
89     }
90
91     try
92     {
93         methName = ScilabObjects::getSingleString(2, pvApiCtx);
94     }
95     catch (ScilabAbstractEnvironmentException & e)
96     {
97         delete[] args;
98         ScilabObjects::removeTemporaryVars(envId, tmpvar);
99         delete[] tmpvar;
100         throw;
101     }
102
103     try
104     {
105         ret = env.invoke(idObj, methName, args, Rhs - 2);
106     }
107     catch (std::exception & e)
108     {
109         delete[] args;
110         ScilabObjects::removeTemporaryVars(envId, tmpvar);
111         delete[] tmpvar;
112         env.removeobject(idObj);
113         freeAllocatedSingleString(methName);
114         throw;
115     }
116
117     delete[] args;
118     ScilabObjects::removeTemporaryVars(envId, tmpvar);
119     delete[] tmpvar;
120     freeAllocatedSingleString(methName);
121
122     if (!ret || *ret <= 0 || (*ret == 1 && ret[1] == VOID_OBJECT))
123     {
124         if (ret)
125         {
126             delete[] ret;
127         }
128
129         PutLhsVar();
130
131         return 0;
132     }
133
134     if (helper.getAutoUnwrap())
135     {
136         for (int i = 1; i <= *ret; i++)
137         {
138             if (!ScilabObjects::unwrap(ret[i], Rhs + i, envId, pvApiCtx))
139             {
140                 try
141                 {
142                     ScilabObjects::createEnvironmentObjectAtPos(EXTERNAL_OBJECT, Rhs + i, ret[i], envId, pvApiCtx);
143                 }
144                 catch (ScilabAbstractEnvironmentException & e)
145                 {
146                     for (int j = 1; j <= *ret; j++)
147                     {
148                         env.removeobject(ret[j]);
149                     }
150                     delete[] ret;
151                     throw;
152                 }
153             }
154             else
155             {
156                 env.removeobject(ret[i]);
157             }
158
159             LhsVar(i) = Rhs + i;
160         }
161     }
162     else
163     {
164         for (int i = 1; i <= *ret; i++)
165         {
166             try
167             {
168                 ScilabObjects::createEnvironmentObjectAtPos(EXTERNAL_OBJECT, Rhs + i, ret[i], envId, pvApiCtx);
169             }
170             catch (ScilabAbstractEnvironmentException & e)
171             {
172                 for (int j = 1; j <= *ret; j++)
173                 {
174                     env.removeobject(ret[j]);
175                 }
176                 delete[] ret;
177                 throw;
178             }
179
180             LhsVar(i) = Rhs + i;
181         }
182     }
183
184     delete[] ret;
185
186     PutLhsVar();
187
188     return 0;
189 }
190 }