fix link return order and bug 3639 c file
[scilab.git] / scilab / modules / dynamic_link / sci_gateway / cpp / sci_link.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) INRIA - Allan CORNET
4  * Copyright (C) DIGITEO - 2011 - Antoine ELIAS
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13
14 /*-----------------------------------------------------------------------------------*/
15 #include "dynamic_link_gw.hxx"
16 #include "configvariable.hxx"
17 #include "function.hxx"
18 #include "double.hxx"
19 #include "string.hxx"
20
21 extern "C"
22 {
23 #include "Scierror.h"
24 #include "dynamic_link.h"
25 #include "ilib_verbose.h"
26 #include "sci_malloc.h"
27 #include "localization.h"
28 #include "dl_genErrorMessage.h"
29 #include "freeArrayOfString.h"
30 #include "sciprint.h"
31 }
32
33 void displayDynLibInfo(void);
34 types::Double* getLibraryIDs(void);
35 /*-----------------------------------------------------------------------------------*/
36 types::Function::ReturnValue sci_link(types::typed_list &in, int _iRetCount, types::typed_list &out)
37 {
38     int iSizeSubNames       = 0;
39     wchar_t** pwstSubNames  = NULL;
40     wchar_t* pwstLibName    = NULL;
41     BOOL bFortran           = TRUE;
42     int iIDSharedLib        = -1;
43
44     if (in.size() > 3)
45     {
46         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "c_link", 0, 3);
47         return types::Function::Error;
48     }
49
50     if (in.size() == 0)
51     {
52         std::vector<std::wstring> FunctionsList = ConfigVariable::getEntryPointNameList();
53         if (FunctionsList.size() == 0)
54         {
55             out.push_back(types::Double::Empty());
56             return types::Function::OK;
57         }
58
59         types::String* pSFunctionNames = new types::String(1, (int)FunctionsList.size());
60         for (int i = 0 ; i < FunctionsList.size(); i++)
61         {
62             pSFunctionNames->set(FunctionsList.size() - i - 1, FunctionsList[i].c_str());
63         }
64
65         out.push_back(pSFunctionNames);
66         return types::Function::OK;
67     }
68
69     if (in.size() == 3)
70     {
71         //flag
72         if (in[2]->isString() == false || in[2]->getAs<types::String>()->isScalar() == false)
73         {
74             Scierror(999 , _("%s : Wrong type for input argument #%d: A string expected.\n"), "link", 3);
75             return types::Function::Error;
76         }
77
78         types::String* pSFlag = in[2]->getAs<types::String>();
79         wchar_t* pwstFlag = pSFlag->get(0);
80         if (wcscmp(pwstFlag, L"f") == 0 || wcscmp(pwstFlag, L"c") == 0)
81         {
82             if (wcscmp(pwstFlag, L"c") == 0)
83             {
84                 bFortran = FALSE;
85             }
86         }
87         else
88         {
89             Scierror(999, _("%ls Wrong value for input argument #%d: '%s' or '%s' expected.\n"), "link", 3, "f", "c");
90             return types::Function::Error;
91         }
92
93     }
94
95     if (in.size() >= 2)
96     {
97         //sub names
98         if (in[1]->isString() == false || ( in[1]->getAs<types::String>()->isVector() == false && in[1]->getAs<types::String>()->isScalar() == false))
99         {
100             Scierror(999, _("%s Wrong type for input argument #%d: A string or a string vector expected.\n"), "link", 2);
101             return types::Function::Error;
102         }
103
104         types::String* pSSubNames = in[1]->getAs<types::String>();
105         iSizeSubNames = pSSubNames->getSize();
106         pwstSubNames = pSSubNames->get();
107     }
108
109     if (in.size() >= 1)
110     {
111         if (in[0]->isDouble())
112         {
113             types::Double* pD = in[0]->getAs<types::Double>();
114             if (pD->isScalar() == false)
115             {
116                 Scierror(999, _("%s : Wrong value for argument #%d: %s\n"), "link", 1, _("Unique id of a shared library expected."));
117                 return types::Function::Error;
118             }
119
120             iIDSharedLib = (int)pD->get(0);
121         }
122         else if (in[0]->isString())
123         {
124             types::String* pS = in[0]->getAs<types::String>();
125             if (pS->isScalar() == false)
126             {
127                 Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "link", 1);
128                 return types::Function::Error;
129             }
130
131             if (wcscmp(pS->get(0), L"show") == 0)
132             {
133                 //show option
134                 displayDynLibInfo();
135                 out.push_back(getLibraryIDs());
136                 return types::Function::OK;
137             }
138
139             //library name
140             pwstLibName = pS->get(0);
141         }
142         else
143         {
144             Scierror(999, _("%s: Wrong type for input argument #%d: A scalar or a string expected.\n"), "link", 1);
145             return types::Function::Error;
146         }
147     }
148
149     int iErr    = 0;
150     int iRetID  = scilabLink(iIDSharedLib, pwstLibName, pwstSubNames, iSizeSubNames, bFortran, &iErr);
151
152     if (iErr)
153     {
154         dl_genErrorMessage(L"link", iErr, pwstLibName);
155
156         /* release lib if it is a new link */
157         if (iIDSharedLib == -1)
158         {
159             ConfigVariable::removeDynamicLibrary(iRetID);
160         }
161         return types::Function::Error;
162     }
163
164     out.push_back(new types::Double(iRetID));
165     return types::Function::OK;
166 }
167 /*-----------------------------------------------------------------------------------*/
168 void displayDynLibInfo(void)
169 {
170     std::list<ConfigVariable::EntryPointStr*>* pEPList = ConfigVariable::getEntryPointList();
171     std::vector<ConfigVariable::DynamicLibraryStr*>* pDLList = ConfigVariable::getDynamicLibraryList();
172
173     if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
174     {
175         sciprint(_("Number of entry points %d.\nShared libraries :\n"), pEPList->size());
176     }
177
178     if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
179     {
180         sciprint("[ ");
181     }
182
183     int iLibCount = 0;
184     for (int i = 0 ; i < pDLList->size() ; i++)
185     {
186         if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
187         {
188             if ((*pDLList)[i] != NULL)
189             {
190                 sciprint("%d ", i);
191                 iLibCount++;
192             }
193         }
194     }
195
196     if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
197     {
198         if (iLibCount < 2)
199         {
200             sciprint(_("] : %d library.\n"), iLibCount);
201         }
202         else
203         {
204             sciprint(_("] : %d libraries.\n"), iLibCount);
205         }
206     }
207
208     std::list<ConfigVariable::EntryPointStr*>::const_reverse_iterator it;
209     for (it = pEPList->rbegin() ; it != pEPList->rend() ; it++)
210     {
211         if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
212         {
213             sciprint(_("Entry point %ls in shared library %d.\n"), (*it)->pwstEntryPointName, (*it)->iLibIndex);
214         }
215     }
216 }
217 /*-----------------------------------------------------------------------------------*/
218 types::Double* getLibraryIDs(void)
219 {
220     std::vector<ConfigVariable::DynamicLibraryStr*>* pDLList = ConfigVariable::getDynamicLibraryList();
221
222     int iLibCount = 0;
223     for (int i = 0 ; i < pDLList->size() ; i++)
224     {
225         if ((*pDLList)[i] != NULL)
226         {
227             iLibCount++;
228         }
229     }
230
231     if (iLibCount == 0)
232     {
233         return types::Double::Empty();
234     }
235
236     types::Double* pOut = new types::Double(1, iLibCount);
237     iLibCount = 0;
238     for (int i = 0 ; i < pDLList->size() ; i++)
239     {
240         if ((*pDLList)[i] != NULL)
241         {
242             pOut->set(iLibCount++, (double)i);
243         }
244     }
245     return pOut;
246 }
247 /*-----------------------------------------------------------------------------------*/