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