autocompletion on variable and functions in YaSp and completion module plugged.
[scilab.git] / scilab / modules / dynamic_link / src / cpp / dynamic_link.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) INRIA/ENPC
4 * Copyright (C) DIGITEO - 2011 - Allan CORNET
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
16 #include "configvariable.hxx"
17
18 extern "C"
19 {
20 #include <string.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "dynamic_link.h"
24 #include "dynamiclibrary.h"
25 #include "men_Sutils.h"
26 #include "MALLOC.h" /* MALLOC */
27 #include "warningmode.h"
28 #include "sciprint.h"
29 #include "stack-c.h"
30 #include "addinter.h"
31 #include "localization.h"
32 #include "Scierror.h"
33 #include "FileExist.h"
34 #include "ilib_verbose.h"
35 #ifdef _MSC_VER
36 #include "getenvc.h"
37 #include "dllinfo.h"
38
39     /* struct used by fortran (F2C) */
40     /* required to be defined in C */
41
42     typedef struct
43     {
44         char name[nlgh + 1];
45     } CINTER_struct;
46
47     __declspec (dllexport) CINTER_struct C2F(cinter);
48
49     /* struct used by fortran (F2C) */
50     /* required to be defined in C */
51     typedef struct
52     {
53         int ibuf[lsiz];
54     } IBFU_struct;
55     __declspec (dllexport) CINTER_struct C2F(ibfu);
56
57 #endif
58 #include "getshortpathname.h"
59 #include "BOOL.h"
60 #include "charEncoding.h"
61 }
62
63 static void Underscores(BOOL _bFortran, wchar_t* _pwstEntryPointName, wchar_t* _pwstTrailingName);
64
65 typedef void (*function) (wchar_t*);
66
67
68 int scilabLink(int _iLibID, wchar_t* _pwstLibraryName, wchar_t** _pwstEntryPointName, int _iEntryPointSize, BOOL _bFortran , int *_piErr)
69 {
70     int iLibID = -1;
71
72     if (_iLibID == -1)
73     {
74         iLibID = Sci_dlopen(_pwstLibraryName);
75     }
76     else
77     {
78         iLibID = _iLibID;
79     }
80
81     if (iLibID == -1)
82     {
83         if ( getWarningMode() )
84         {
85 #ifdef _MSC_VER
86             if (isDllW(_pwstLibraryName))
87             {
88 #ifdef _WIN64
89                 if (isX86DllW(_pwstLibraryName))
90                 {
91                     if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
92                     {
93                         sciprint(_("%s: can not to load a x86 dll in a x64 environment.\n" ), "link");
94                     }
95                     SetLastError(ERROR_DLL_INIT_FAILED);
96                 }
97 #else
98                 if (isX64DllW(_pwstLibraryName))
99                 {
100                     if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
101                     {
102                         sciprint(_("%s: can not load a x64 dll in a x86 environment.\n" ), "link");
103                     }
104                     SetLastError(ERROR_DLL_INIT_FAILED);
105                 }
106 #endif
107             }
108             else
109             {
110                 wchar_t* pwstPathSearch = searchEnvW(_pwstLibraryName, L"PATH");
111                 if (pwstPathSearch == NULL)
112                 {
113                     if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
114                     {
115                         sciprint(_("%ls: The file %ls does not exist in PATH environment.\n" ), L"link", _pwstLibraryName);
116                     }
117                 }
118             }
119 #else
120             if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
121             {
122                 sciprint(_("Link failed for dynamic library '%ls'.\n"), _pwstLibraryName);
123                 sciprint(_("An error occurred: %s\n"), GetLastDynLibError());
124             }
125 #endif
126         }
127         *_piErr = -1;
128         return iLibID;
129     }
130
131     if ( (_iLibID == -1) && (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT))
132     {
133         sciprint(_("Shared archive loaded.\n"));
134         sciprint(_("Link done.\n"));
135     }
136
137     for (int i = 0 ; i < _iEntryPointSize ; i++)
138     {
139         *_piErr = Sci_dlsym(_pwstEntryPointName[i], iLibID, _bFortran);
140     }
141
142     return iLibID;
143 }
144 /*---------------------------------------------------------------------------*/
145 /**
146 * Underscores : deals with the trailing _
147 * in entry names
148 */
149 static void Underscores(BOOL _bFortran, wchar_t* _pwstEntryPointName, wchar_t* _pwstTrailingName)
150 {
151 #ifdef WLU1
152     *_pwstTrailingName = L'_';
153     _pwstTrailingName++;
154 #endif
155     wcscpy(_pwstTrailingName, _pwstEntryPointName);
156 #ifdef WTU
157     if (_bFortran)
158     {
159         wcscat(_pwstTrailingName, L"_");
160     }
161 #endif
162     return;
163 }
164 /*---------------------------------------------------------------------------*/
165 int Sci_dlclose(unsigned long long _hLib)
166 {
167     return FreeDynLibrary((DynLibHandle)_hLib);
168 }
169 /*---------------------------------------------------------------------------*/
170 int Sci_dlopen(wchar_t* _pwstDynLibPath)
171 {
172     static DynLibHandle hLib = NULL;
173     int i = 0;
174
175 #ifdef _MSC_VER
176     {
177         hLib = LoadDynLibraryW(_pwstDynLibPath);
178     }
179 #else
180     {
181         char* pstDynLibPath = wide_string_to_UTF8(_pwstDynLibPath);
182         hLib = LoadDynLibrary (pstDynLibPath);
183         FREE(pstDynLibPath);
184     }
185 #endif
186
187     if (hLib == NULL)
188     {
189         return -1 ; /* the shared archive was not loaded. */
190     }
191
192     ConfigVariable::DynamicLibraryStr* pDL = ConfigVariable::getNewDynamicLibraryStr();
193     ConfigVariable::setLibraryName(pDL, _pwstDynLibPath);
194     pDL->hLib = (unsigned long long)hLib;
195
196
197     return ConfigVariable::addDynamicLibrary(pDL);
198 }
199 /*---------------------------------------------------------------------------*/
200 int Sci_dlsym(wchar_t* _pwstEntryPointName, int _iLibID, BOOL _bFortran)
201 {
202     DynLibHandle hDynLib = NULL;
203     ConfigVariable::EntryPointStr* pEP = ConfigVariable::getNewEntryPointStr();
204     //+3 : 1 for '\0', 1 for prefix _, 1 for suffix _
205     wchar_t* pwstEntryPointName = (wchar_t*)MALLOC(sizeof(wchar_t) * (wcslen(_pwstEntryPointName) + 3));
206     memset(pwstEntryPointName, 0x00, (wcslen(_pwstEntryPointName) + 3));
207
208     Underscores(_bFortran, _pwstEntryPointName, pwstEntryPointName);
209
210
211     if (_iLibID < 0 || ConfigVariable::isDynamicLibrary(_iLibID) == false)
212     {
213         //no valid library at this ID
214         return -3;
215     }
216
217     /** entry was previously loaded **/
218     if (ConfigVariable::getEntryPoint(_pwstEntryPointName, _iLibID) != NULL)
219     {
220         sciprint(_("Entry name %ls.\n"), _pwstEntryPointName);
221         return -4;
222     }
223
224     pEP->iLibIndex = _iLibID;
225     hDynLib = (DynLibHandle)  ConfigVariable::getDynamicLibrary(_iLibID)->hLib;
226 #ifdef _MCS_VER
227     pEP->functionPtr = (function) GetDynLibFuncPtrW(hDynLib, pwstEntryPointName);
228 #else
229     char* pstEntryPointName = wide_string_to_UTF8(pwstEntryPointName);
230     pEP->functionPtr = (function) GetDynLibFuncPtr(hDynLib, pstEntryPointName);
231     FREE(pstEntryPointName);
232 #endif
233     if (pEP->functionPtr == NULL)
234     {
235         if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
236         {
237             sciprint(_("%ls is not an entry point.\n"), _pwstEntryPointName);
238         }
239         return -5;
240     }
241
242
243     if (0 /*debug mode*/)
244     {
245         sciprint(_("Linking %ls.\n"), _pwstEntryPointName);
246     }
247
248     ConfigVariable::setEntryPointName(pEP, _pwstEntryPointName);
249     ConfigVariable::addEntryPoint(pEP);
250     FREE(pwstEntryPointName);
251     return 0;
252 }
253 /*---------------------------------------------------------------------------*/