Coverity: ast module resource leaks fixed
[scilab.git] / scilab / modules / ast / src / cpp / types / function.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
4  *  Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
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 #include <algorithm>
18 #include <sstream>
19 #include <vector>
20 #include "function.hxx"
21 #include "double.hxx"
22 #include "gatewaystruct.hxx"
23 #include "configvariable.hxx"
24 #include "scilabWrite.hxx"
25
26 extern "C"
27 {
28 #include "core_math.h"
29 #include "charEncoding.h"
30 #include "Scierror.h"
31 #include "sciprint.h"
32 #include "localization.h"
33 #include "sci_path.h"
34 #include "sci_malloc.h"
35 #include "os_string.h"
36 #include "lasterror.h"
37 #include "dynamic_module.h"
38 }
39
40 namespace types
41 {
42 Function* Function::createFunction(const std::wstring& _wstName, GW_FUNC _pFunc, const std::wstring& _wstModule)
43 {
44     return new Function(_wstName, _pFunc, NULL, _wstModule);
45 }
46
47 Function* Function::createFunction(const std::wstring& _wstName, GW_FUNC_OPT _pFunc, const std::wstring& _wstModule)
48 {
49     return new OptFunction(_wstName, _pFunc, NULL, _wstModule);
50 }
51
52 Function* Function::createFunction(const std::wstring& _wstName, OLDGW_FUNC _pFunc, const std::wstring& _wstModule)
53 {
54     return new WrapFunction(_wstName, _pFunc, NULL, _wstModule);
55 }
56
57 Function* Function::createFunction(const std::wstring& _wstName, MEXGW_FUNC _pFunc, const std::wstring& _wstModule)
58 {
59     return new WrapMexFunction(_wstName, _pFunc, NULL, _wstModule);
60 }
61
62 Function* Function::createFunction(const std::wstring& _wstName, GW_FUNC _pFunc, LOAD_DEPS _pLoadDeps, const std::wstring& _wstModule)
63 {
64     return new Function(_wstName, _pFunc, _pLoadDeps, _wstModule);
65 }
66
67 Function* Function::createFunction(const std::wstring& _wstName, GW_FUNC_OPT _pFunc, LOAD_DEPS _pLoadDeps, const std::wstring& _wstModule)
68 {
69     return new OptFunction(_wstName, _pFunc, _pLoadDeps, _wstModule);
70 }
71
72 Function* Function::createFunction(const std::wstring& _wstName, OLDGW_FUNC _pFunc, LOAD_DEPS _pLoadDeps, const std::wstring& _wstModule)
73 {
74     return new WrapFunction(_wstName, _pFunc, _pLoadDeps, _wstModule);
75 }
76
77 Function* Function::createFunction(const std::wstring& _wstName, MEXGW_FUNC _pFunc, LOAD_DEPS _pLoadDeps, const std::wstring& _wstModule)
78 {
79     return new WrapMexFunction(_wstName, _pFunc, _pLoadDeps, _wstModule);
80 }
81
82 Function* Function::createFunction(const std::wstring& _wstFunctionName, const std::wstring& _wstEntryPointName, const std::wstring& _wstLibName, FunctionType _iType, LOAD_DEPS _pLoadDeps, const std::wstring& _wstModule, bool _bCloseLibAfterCall)
83 {
84     return new DynamicFunction(_wstFunctionName, _wstEntryPointName, _wstLibName, _iType, _pLoadDeps, _wstModule, _bCloseLibAfterCall);
85 }
86
87 Function* Function::createFunction(const std::wstring& _wstFunctionName, const std::wstring& _wstEntryPointName, const std::wstring& _wstLibName, FunctionType _iType, const std::wstring& _wstLoadDepsName, const std::wstring& _wstModule, bool _bCloseLibAfterCall)
88 {
89     return new DynamicFunction(_wstFunctionName, _wstEntryPointName, _wstLibName, _iType, _wstLoadDepsName, _wstModule, _bCloseLibAfterCall);
90 }
91
92 Function* Function::createFunction(const std::wstring& _wstName, GW_C_FUNC _pFunc, const std::wstring& _wstModule)
93 {
94     return new WrapCFunction(_wstName, _pFunc, NULL, _wstModule);
95 }
96
97 Function* Function::createFunction(const std::wstring& _wstName, GW_C_FUNC _pFunc, LOAD_DEPS _pLoadDeps, const std::wstring& _wstModule)
98 {
99     return new WrapCFunction(_wstName, _pFunc, _pLoadDeps, _wstModule);
100 }
101
102
103 Function::Function(const std::wstring& _wstName, GW_FUNC _pFunc, LOAD_DEPS _pLoadDeps, const std::wstring& _wstModule) : Callable(), m_pFunc(_pFunc), m_pLoadDeps(_pLoadDeps)
104 {
105     setName(_wstName);
106     char* s = wide_string_to_UTF8(m_wstName.data());
107     m_stName = s;
108     FREE(s);
109
110     setModule(_wstModule);
111 }
112
113 Function::~Function()
114 {
115
116 }
117
118
119 Function::ReturnValue Function::call(typed_list &in, optional_list &/*opt*/, int _iRetCount, typed_list &out)
120 {
121     int ret = 1;
122     if (m_pLoadDeps != NULL)
123     {
124         ret = m_pLoadDeps(m_wstName);
125     }
126
127     if (ret == 0)
128     {
129         return Error;
130     }
131
132     return this->m_pFunc(in, _iRetCount, out);
133 }
134
135 void Function::whoAmI()
136 {
137     std::cout << "types::Function";
138 }
139
140 bool Function::toString(std::wostringstream& ostr)
141 {
142     // display nothing. ie : c = cos
143     return true;
144 }
145
146 Function* Function::clone()
147 {
148     IncreaseRef();
149     return this;
150 }
151
152 OptFunction::OptFunction(const std::wstring& _wstName, GW_FUNC_OPT _pFunc, LOAD_DEPS _pLoadDeps, const std::wstring& _wstModule)
153 {
154     m_wstName = _wstName;
155     char* s = wide_string_to_UTF8(m_wstName.data());
156     m_stName = s;
157     FREE(s);
158     m_pFunc = _pFunc;
159     m_pLoadDeps = _pLoadDeps;
160     m_wstModule = _wstModule;
161 }
162
163 OptFunction::OptFunction(OptFunction* _pWrapFunction)
164 {
165     m_wstModule  = _pWrapFunction->getModule();
166     m_wstName    = _pWrapFunction->getName();
167     char* s = wide_string_to_UTF8(m_wstName.data());
168     m_stName = s;
169     FREE(s);
170     m_pFunc = _pWrapFunction->getFunc();
171     m_pLoadDeps = _pWrapFunction->getDeps();
172 }
173
174 OptFunction* OptFunction::clone()
175 {
176     return new OptFunction(this);
177 }
178
179 Function::ReturnValue OptFunction::call(typed_list &in, optional_list &opt, int _iRetCount, typed_list &out)
180 {
181     int ret = 1;
182     if (m_pLoadDeps != NULL)
183     {
184         ret = m_pLoadDeps(m_wstName);
185     }
186
187     if (ret == 0)
188     {
189         return Error;
190     }
191
192     return this->m_pFunc(in, opt, _iRetCount, out);
193 }
194
195 WrapFunction::WrapFunction(const std::wstring& _wstName, OLDGW_FUNC _pFunc, LOAD_DEPS _pLoadDeps, const std::wstring& _wstModule)
196 {
197     m_wstName = _wstName;
198     m_pOldFunc = _pFunc;
199     m_wstModule = _wstModule;
200     char* s = wide_string_to_UTF8(m_wstName.data());
201     m_stName = s;
202     FREE(s);
203     m_pLoadDeps = _pLoadDeps;
204 }
205
206 WrapFunction::WrapFunction(WrapFunction* _pWrapFunction)
207 {
208     m_wstModule = _pWrapFunction->getModule();
209     m_wstName = _pWrapFunction->getName();
210     char* s = wide_string_to_UTF8(m_wstName.data());
211     m_stName = s;
212     FREE(s);
213     m_pOldFunc  = _pWrapFunction->getFunc();
214     m_pLoadDeps = _pWrapFunction->getDeps();
215 }
216
217 WrapFunction* WrapFunction::clone()
218 {
219     return new WrapFunction(this);
220 }
221
222 Function::ReturnValue WrapFunction::call(typed_list &in, optional_list &opt, int _iRetCount, typed_list &out)
223 {
224     int ret = 1;
225     int inSize = (int)in.size();
226     int optSize = (int)opt.size();
227     bool isRef = checkReferenceModule(m_wstModule.c_str());
228
229     if (m_pLoadDeps != NULL)
230     {
231         ret = m_pLoadDeps(m_wstName);
232     }
233
234     if (ret == 0)
235     {
236         return Error;
237     }
238
239     ReturnValue retVal = Callable::OK;
240     GatewayStruct gStr;
241     _iRetCount = std::max(1, _iRetCount);
242     gStr.m_iIn = inSize + optSize;
243     gStr.m_iOut = _iRetCount;
244
245     //copy input parameter to prevent calling gateway modifies input data
246     typed_list inCopy;
247
248     if (isRef == false)
249     {
250         for (int i = 0; i < inSize; i++)
251         {
252             inCopy.push_back(in[i]->clone());
253         }
254     }
255     else
256     {
257         for (int i = 0; i < inSize; i++)
258         {
259             inCopy.push_back(in[i]);
260         }
261     }
262     gStr.m_pIn = &inCopy;
263     gStr.m_pOpt = &opt;
264     typed_list::value_type tmpOut[MAX_OUTPUT_VARIABLE];
265     std::fill_n(tmpOut, MAX_OUTPUT_VARIABLE, static_cast<typed_list::value_type>(0));
266     gStr.m_pOut = tmpOut;
267     gStr.m_piRetCount = &_iRetCount;
268     gStr.m_pstName = m_stName.data();
269     // we should use a stack array of the max size to avoid dynamic alloc.
270     std::vector<int> outOrder(_iRetCount < 1 ? 1 : _iRetCount, -1);
271     gStr.m_pOutOrder = outOrder.data();
272
273     //call gateway
274     m_pOldFunc(const_cast<char*>(m_stName.data()), reinterpret_cast<int*>(&gStr));
275     if (ConfigVariable::isError())
276     {
277         retVal = Callable::Error;
278         ConfigVariable::resetError();
279     }
280     else
281     {
282         for (std::size_t i(0); i != (size_t)_iRetCount && outOrder[i] != -1 && outOrder[i] != 0; ++i)
283         {
284             if (outOrder[i] - 1 < gStr.m_iIn)
285             {
286                 std::size_t const iPos(outOrder[i] - 1);
287                 //protect variable to deletion
288                 inCopy[iPos]->IncreaseRef();
289                 if (inCopy[iPos]->isDouble() && ((types::Double*)inCopy[iPos])->isViewAsInteger())
290                 {
291                     types::Double* pD = inCopy[iPos]->getAs<types::Double>();
292                     pD->convertFromInteger();
293                 }
294
295                 if (inCopy[iPos]->isDouble() && ((types::Double*)inCopy[iPos])->isViewAsZComplex())
296                 {
297                     types::Double* pD = inCopy[iPos]->getAs<types::Double>();
298                     pD->convertFromZComplex();
299                 }
300
301                 out.push_back(inCopy[iPos]);
302             }
303             else
304             {
305                 std::size_t const iPos(outOrder[i] - gStr.m_iIn - 1);
306                 if (tmpOut[iPos]->isDouble() && ((types::Double*)tmpOut[iPos])->isViewAsInteger())
307                 {
308                     types::Double* pD = tmpOut[iPos]->getAs<types::Double>();
309                     pD->convertFromInteger();
310                 }
311
312                 if (tmpOut[iPos]->isDouble() && ((types::Double*)tmpOut[iPos])->isViewAsZComplex())
313                 {
314                     types::Double* pD = tmpOut[iPos]->getAs<types::Double>();
315                     pD->convertFromZComplex();
316                 }
317
318                 out.push_back(tmpOut[iPos]);
319                 tmpOut[iPos] = 0;
320             }
321         }
322     }
323
324     for (std::size_t i(0); i != MAX_OUTPUT_VARIABLE; ++i)
325     {
326         if (tmpOut[i])
327         {
328             tmpOut[i]->killMe();
329         }
330     }
331
332     //clean input copy
333     if (isRef == false)
334     {
335         //protect outputs
336         int size = (int)out.size();
337         for (int i = 0; i < size; i++)
338         {
339             out[i]->IncreaseRef();
340         }
341
342         for (int i = 0; i < inSize; i++)
343         {
344             inCopy[i]->killMe();
345         }
346
347         //unprotect outputs
348         for (int i = 0; i < size; i++)
349         {
350             out[i]->DecreaseRef();
351         }
352     }
353
354     return retVal;
355 }
356
357 WrapMexFunction::WrapMexFunction(const std::wstring& _wstName, MEXGW_FUNC _pFunc, LOAD_DEPS _pLoadDeps, const std::wstring& _wstModule)
358 {
359     m_wstName = _wstName;
360     char* s = wide_string_to_UTF8(m_wstName.data());
361     m_stName = s;
362     FREE(s);
363     m_pOldFunc = _pFunc;
364     m_wstModule = _wstModule;
365     m_pLoadDeps = _pLoadDeps;
366 }
367
368 WrapMexFunction::WrapMexFunction(WrapMexFunction* _pWrapFunction)
369 {
370     m_wstModule = _pWrapFunction->getModule();
371     char* s = wide_string_to_UTF8(m_wstName.data());
372     m_stName = s;
373     FREE(s);
374     m_wstName = _pWrapFunction->getName();
375     m_pOldFunc = _pWrapFunction->getFunc();
376     m_pLoadDeps = _pWrapFunction->getDeps();
377 }
378
379 WrapMexFunction* WrapMexFunction::clone()
380 {
381     return new WrapMexFunction(this);
382 }
383
384 Function::ReturnValue WrapMexFunction::call(typed_list &in, optional_list &/*opt*/, int _iRetCount, typed_list &out)
385 {
386     int ret = 1;
387     if (m_pLoadDeps != NULL)
388     {
389         ret = m_pLoadDeps(m_wstName);
390     }
391
392     if (ret == 0)
393     {
394         return Error;
395     }
396
397     ReturnValue retVal = Callable::OK;
398
399     char* name = wide_string_to_UTF8(getName().c_str());
400     ConfigVariable::setMexFunctionName(name);
401     FREE(name);
402
403     int nlhs = _iRetCount;
404     int** plhs = new int*[nlhs];
405     memset(plhs, 0x00, sizeof(int*) * nlhs);
406
407     int nrhs = (int)in.size();
408     int** prhs = new int*[nrhs];
409     for (int i = 0; i < nrhs; i++)
410     {
411         prhs[i] = (int*)(in[i]);
412     }
413
414     try
415     {
416         m_pOldFunc(nlhs, plhs, nrhs, prhs);
417     }
418     catch (const ast::InternalError& ie)
419     {
420         delete[] plhs;
421         delete[] prhs;
422         throw ie;
423     }
424
425     if (_iRetCount == 1 && plhs[0] == NULL)
426     {
427         //dont copy empty values, juste return "no value"
428         return retVal;
429     }
430
431     for (int i = 0; i < nlhs; i++)
432     {
433         out.push_back((types::InternalType*)plhs[i]);
434     }
435
436     delete[] plhs;
437     delete[] prhs;
438     return retVal;
439 }
440
441 WrapCFunction::WrapCFunction(const std::wstring& _wstName, GW_C_FUNC _pFunc, LOAD_DEPS _pLoadDeps, const std::wstring& _wstModule)
442 {
443     m_wstName = _wstName;
444     char* s = wide_string_to_UTF8(m_wstName.data());
445     m_stName = s;
446     FREE(s);
447     m_pCFunc = _pFunc;
448     m_wstModule = _wstModule;
449     m_pLoadDeps = _pLoadDeps;
450 }
451
452 WrapCFunction::WrapCFunction(WrapCFunction* _pWrapFunction)
453 {
454     m_wstModule = _pWrapFunction->getModule();
455     char* s = wide_string_to_UTF8(m_wstName.data());
456     m_stName = s;
457     FREE(s);
458     m_wstName = _pWrapFunction->getName();
459     m_pCFunc = _pWrapFunction->getFunc();
460     m_pLoadDeps = _pWrapFunction->getDeps();
461 }
462
463 WrapCFunction* WrapCFunction::clone()
464 {
465     return new WrapCFunction(this);
466 }
467
468 Function::ReturnValue WrapCFunction::call(typed_list& in, optional_list& opt, int _iRetCount, typed_list& out)
469 {
470     if (m_pLoadDeps != NULL)
471     {
472         if (m_pLoadDeps(m_wstName) == 0)
473         {
474             return Error;
475         }
476     }
477
478     ReturnValue retVal = OK;
479
480     try
481     {
482         GatewayCStruct gcs;
483         gcs.name = m_stName;
484         out.resize(_iRetCount, NULL);
485         if (m_pCFunc((void*)&gcs, (int)in.size(), (scilabVar*)(in.data()), (int)opt.size(), (scilabOpt)&opt, _iRetCount, (scilabVar*)(out.data())))
486         {
487             retVal = Error;
488         }
489     }
490     catch (const ast::InternalError& ie)
491     {
492         throw ie;
493     }
494
495     if (retVal == OK)
496     {
497         if (_iRetCount == 1 && out[0] == NULL)
498         {
499             //dont copy empty values, juste return "no value"
500             out.clear();
501             return retVal;
502         }
503     }
504
505     return retVal;
506 }
507
508 DynamicFunction::DynamicFunction(const std::wstring& _wstName, const std::wstring& _wstEntryPointName, const std::wstring& _wstLibName, FunctionType _iType, const std::wstring& _wstLoadDepsName, const std::wstring& _wstModule, bool _bCloseLibAfterCall)
509 {
510     m_wstName               = _wstName;
511     char* s = wide_string_to_UTF8(m_wstName.data());
512     m_stName = s;
513     FREE(s);
514     m_wstLibName = _wstLibName;
515     m_wstModule             = _wstModule;
516     m_wstEntryPoint         = _wstEntryPointName;
517     m_wstLoadDepsName       = _wstLoadDepsName;
518     m_pLoadDeps             = NULL;
519     m_bCloseLibAfterCall    = _bCloseLibAfterCall;
520     m_iType                 = _iType;
521     m_pFunc                 = NULL;
522     m_pOptFunc              = NULL;
523     m_pOldFunc              = NULL;
524     m_pMexFunc              = NULL;
525     m_pFunction             = NULL;
526     m_pCFunc                = NULL;
527 }
528
529 DynamicFunction::DynamicFunction(const std::wstring& _wstName, const std::wstring& _wstEntryPointName, const std::wstring& _wstLibName, FunctionType _iType, LOAD_DEPS _pLoadDeps, const std::wstring& _wstModule, bool _bCloseLibAfterCall)
530 {
531     m_wstName               = _wstName;
532     char* s = wide_string_to_UTF8(m_wstName.data());
533     m_stName = s;
534     FREE(s);
535     m_wstLibName = _wstLibName;
536     m_wstModule             = _wstModule;
537     m_wstEntryPoint         = _wstEntryPointName;
538     m_pLoadDeps             = _pLoadDeps;
539     m_wstLoadDepsName       = L"";
540     m_bCloseLibAfterCall    = _bCloseLibAfterCall;
541     m_iType                 = _iType;
542     m_pFunc                 = NULL;
543     m_pOptFunc              = NULL;
544     m_pOldFunc              = NULL;
545     m_pMexFunc              = NULL;
546     m_pFunction             = NULL;
547     m_pCFunc                = NULL;
548 }
549
550 Function::ReturnValue DynamicFunction::call(typed_list &in, optional_list &opt, int _iRetCount, typed_list &out)
551 {
552     if (m_pFunction == NULL)
553     {
554         if (Init() != OK)
555         {
556             return Error;
557         }
558     }
559
560     /*call function*/
561     if (m_pFunction->call(in, opt, _iRetCount, out) != OK)
562     {
563         return Error;
564     }
565
566     /*Close lib is mandatory*/
567     if (m_bCloseLibAfterCall)
568     {
569         Clear();
570     }
571
572     return OK;
573 }
574
575 DynamicFunction::~DynamicFunction()
576 {
577     if (m_pFunction)
578     {
579         delete m_pFunction;
580     }
581 }
582
583 Callable::ReturnValue DynamicFunction::Init()
584 {
585     /*Load library*/
586     if (m_wstLibName.empty())
587     {
588         Scierror(999, _("%s: Library name must not be empty\n."), m_wstName.c_str());
589         return Error;
590     }
591
592     DynLibHandle hLib = getDynModule(m_wstLibName.c_str());
593     if (hLib == 0)
594     {
595         char* pstLibName = wide_string_to_UTF8(m_wstLibName.c_str());
596         hLib = LoadDynLibrary(pstLibName);
597
598         if (hLib == 0)
599         {
600             //2nd chance for linux !
601 #ifndef _MSC_VER
602             char* pstError = strdup(GetLastDynLibError());
603
604             /* Haven't been able to find the lib with dlopen...
605             * This can happen for two reasons:
606             * - the lib must be dynamically linked
607             * - Some silly issues under Suse (see bug #2875)
608             * Note that we are handling only the "source tree build"
609             * because libraries are split (they are in the same directory
610             * in the binary)
611             */
612             wchar_t* pwstScilabPath = getSCIW();
613             wchar_t pwstModulesPath[] = L"/modules/";
614             wchar_t pwstLTDir[] =  L".libs/";
615
616             /* Build the full path to the library */
617             int iPathToLibLen = (wcslen(pwstScilabPath) + wcslen(pwstModulesPath) + wcslen(m_wstModule.c_str()) + wcslen(L"/") + wcslen(pwstLTDir) + wcslen(m_wstLibName.c_str()) + 1);
618             wchar_t* pwstPathToLib = (wchar_t*)MALLOC(iPathToLibLen * sizeof(wchar_t));
619             os_swprintf(pwstPathToLib, iPathToLibLen, L"%ls%ls%ls/%ls%ls", pwstScilabPath, pwstModulesPath, m_wstModule.c_str(), pwstLTDir, m_wstLibName.c_str());
620             FREE(pwstScilabPath);
621             char* pstPathToLib = wide_string_to_UTF8(pwstPathToLib);
622             FREE(pwstPathToLib);
623             hLib = LoadDynLibrary(pstPathToLib);
624
625             if (hLib == 0)
626             {
627                 Scierror(999, _("An error has been detected while loading %s: %s\n"), pstLibName, pstError);
628                 FREE(pstError);
629
630                 pstError = GetLastDynLibError();
631                 Scierror(999, _("An error has been detected while loading %s: %s\n"), pstPathToLib, pstError);
632
633                 FREE(pstLibName);
634                 FREE(pstPathToLib);
635                 return Error;
636             }
637             FREE(pstPathToLib);
638             FREE(pstError);
639 #else
640             char* pstError = wide_string_to_UTF8(m_wstLibName.c_str());
641             Scierror(999, _("Impossible to load %s library\n"), pstError);
642             FREE(pstError);
643             FREE(pstLibName);
644             return Error;
645 #endif
646         }
647         FREE(pstLibName);
648         addDynModule(m_wstLibName.c_str(), hLib);
649
650         /*Load deps*/
651         if (m_wstLoadDepsName.empty() == false && m_pLoadDeps == NULL)
652         {
653             char* pstLoadDepsName = wide_string_to_UTF8(m_wstLoadDepsName.c_str());
654             m_pLoadDeps = (LOAD_DEPS)GetDynLibFuncPtr(hLib, pstLoadDepsName);
655             FREE(pstLoadDepsName);
656         }
657
658     }
659
660     /*Load gateway*/
661     if (m_wstName != L"")
662     {
663         char* pstEntryPoint = wide_string_to_UTF8(m_wstEntryPoint.c_str());
664         switch (m_iType)
665         {
666             case EntryPointCPPOpt :
667                 m_pOptFunc = (GW_FUNC_OPT)GetDynLibFuncPtr(hLib, pstEntryPoint);
668                 break;
669             case EntryPointCPP :
670                 m_pFunc = (GW_FUNC)GetDynLibFuncPtr(hLib, pstEntryPoint);
671                 break;
672             case EntryPointOldC :
673                 m_pOldFunc = (OLDGW_FUNC)GetDynLibFuncPtr(hLib, pstEntryPoint);
674                 break;
675             case EntryPointMex:
676                 m_pMexFunc = (MEXGW_FUNC)GetDynLibFuncPtr(hLib, pstEntryPoint);
677                 break;
678             case EntryPointC:
679                 m_pCFunc = (GW_C_FUNC)GetDynLibFuncPtr(hLib, pstEntryPoint);
680                 break;
681         }
682
683         FREE(pstEntryPoint);
684     }
685
686     if (m_pFunc == NULL && m_pOldFunc == NULL && m_pMexFunc == NULL && m_pOptFunc == NULL && m_pCFunc == NULL)
687     {
688         char* pstEntry = wide_string_to_UTF8(m_wstEntryPoint.c_str());
689         char* pstLib = wide_string_to_UTF8(m_wstLibName.c_str());
690         Scierror(999, _("Impossible to load %s function in %s library: %s\n"), pstEntry, pstLib, GetLastDynLibError());
691         FREE(pstEntry);
692         FREE(pstLib);
693         return Error;
694     }
695
696     switch (m_iType)
697     {
698         case EntryPointCPPOpt :
699             m_pFunction = new OptFunction(m_wstName, m_pOptFunc, m_pLoadDeps, m_wstModule);
700             break;
701         case EntryPointCPP :
702             m_pFunction = new Function(m_wstName, m_pFunc, m_pLoadDeps, m_wstModule);
703             break;
704         case EntryPointOldC :
705             m_pFunction = new WrapFunction(m_wstName, m_pOldFunc, m_pLoadDeps, m_wstModule);
706             break;
707         case EntryPointMex:
708             m_pFunction = new WrapMexFunction(m_wstName, m_pMexFunc, m_pLoadDeps, m_wstModule);
709             break;
710         case EntryPointC:
711             m_pFunction = new WrapCFunction(m_wstName, m_pCFunc, m_pLoadDeps, m_wstModule);
712             break;
713     }
714
715     if (m_pFunction == NULL)
716     {
717         return Error;
718     }
719     return OK;
720 }
721
722 void DynamicFunction::Clear()
723 {
724     m_pFunc     = NULL;
725     m_pOldFunc  = NULL;
726     m_pMexFunc  = NULL;
727 }
728
729 }