JIMS: add jvoid
[scilab.git] / scilab / modules / external_objects / src / cpp / newInstance.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 extern "C" {
16 #include "scicurdir.h"
17 }
18
19 namespace org_modules_external_objects
20 {
21
22 int ScilabGateway::newInstance(char * fname, const int envId, void * pvApiCtx)
23 {
24     SciErr err;
25     int * addr = 0;
26     int idClass = 0;
27     int * tmpvar = 0;
28     int * args = 0;
29     int ret = 0;
30     char * className = 0;
31     int error = 0;
32     char * cwd = 0;
33     int nbArgs = Rhs - 1;
34
35     if (Rhs == 0)
36     {
37         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Wrong number of arguments : more than 1 argument expected"));
38     }
39
40     ScilabAbstractEnvironment & env = ScilabEnvironments::getEnvironment(envId);
41     ScilabGatewayOptions & options = env.getGatewayOptions();
42     OptionsHelper & helper = env.getOptionsHelper();
43     OptionsHelper::setCopyOccurred(false);
44     ScilabObjects::initialization(env, pvApiCtx);
45     options.setIsNew(false);
46
47     err = getVarAddressFromPosition(pvApiCtx, 1, &addr);
48     if (err.iErr)
49     {
50         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
51     }
52
53     cwd = scigetcwd(&error);
54     if (error)
55     {
56         FREE(cwd);
57         cwd = 0;
58     }
59
60     if (isStringType(pvApiCtx, addr))
61     {
62         className = ScilabObjects::getSingleString(1, pvApiCtx);
63         try
64         {
65             idClass = env.loadclass(className, cwd, false, helper.getAllowReload());
66         }
67         catch (std::exception & e)
68         {
69             FREE(cwd);
70             freeAllocatedSingleString(className);
71             throw;
72         }
73         FREE(cwd);
74         freeAllocatedSingleString(className);
75     }
76     else if (ScilabObjects::isExternalClass(addr, pvApiCtx))
77     {
78         idClass = ScilabObjects::getArgumentId(addr, 0, false, true, envId, pvApiCtx);
79     }
80
81     tmpvar = new int[Rhs];
82     *tmpvar = 0;
83     args = new int[Rhs - 1];
84
85     for (int i = 0; i < Rhs - 1; i++)
86     {
87         err = getVarAddressFromPosition(pvApiCtx, i + 2, &addr);
88         if (err.iErr)
89         {
90             delete[] args;
91             ScilabObjects::removeTemporaryVars(envId, tmpvar);
92             delete[] tmpvar;
93             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
94         }
95         try
96         {
97             args[i] = ScilabObjects::getArgumentId(addr, tmpvar, false, false, envId, pvApiCtx);
98         }
99         catch (ScilabAbstractEnvironmentException & e)
100         {
101             delete[] args;
102             delete[] tmpvar;
103             throw;
104         }
105
106         if (args[i] == VOID_OBJECT)
107         {
108             nbArgs = 0;
109         }
110     }
111
112     try
113     {
114         ret = env.newinstance(idClass, args, nbArgs);
115     }
116     catch (std::exception & e)
117     {
118         delete[] args;
119         ScilabObjects::removeTemporaryVars(envId, tmpvar);
120         delete[] tmpvar;
121         throw;
122     }
123
124     delete[] args;
125     ScilabObjects::removeTemporaryVars(envId, tmpvar);
126     delete[] tmpvar;
127
128     try
129     {
130         ScilabObjects::createEnvironmentObjectAtPos(EXTERNAL_OBJECT, Rhs + 1, ret, envId, pvApiCtx);
131     }
132     catch (ScilabAbstractEnvironmentException & e)
133     {
134         env.removeobject(ret);
135         throw;
136     }
137
138     LhsVar(1) = Rhs + 1;
139     PutLhsVar();
140
141     return 0;
142 }
143 }